-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
257 add cypress tests that use the integration db (#295)
* init cypress integration * assert-free-ports should exit 0 if nothing is running on :3000 or :3883, otherwise it should exit 1. the commands after it in yarn should run with && not ; * refactor big block of shell into "yarn integration:servers:start" * can i also refactor "ci:test" to use "integration:servers:start" ? the difference is adding MAILING_CLI=true, was that ommitted intentionally or no? * add precheck for servers running to test:integration:cypress * move ./scripts/assert-free-ports.sh check to integration:servers:start * now you can't fuck it up * hook for db:reset * demo of a function that counts * beforeAll is just called "before" in cypress * small refactor for readability * resolve typescript declared twice warning * working clear dev database, imports are all screwy * working clear web db * wtf well i guess it allows some imports? * add headed option * add cy test that duplicates the bug * fix bug on /settings page * will it run in github * oops fix ts * add a login test * test api key functionality * test logout * test login form errors * test signup form errors * fix github action * try using cypress-io/github-action@v4 * oops * duh yarn * rm commented
- Loading branch information
1 parent
038ccdd
commit 1499e90
Showing
8 changed files
with
228 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
name: Cypress Integration Tests | ||
|
||
on: | ||
push: | ||
|
||
jobs: | ||
cypress: | ||
runs-on: ubuntu-latest | ||
services: | ||
# Label used to access the service container | ||
postgres: | ||
# Docker Hub image | ||
image: postgres | ||
# Provide the password for postgres | ||
env: | ||
POSTGRES_PASSWORD: postgres | ||
# Set health checks to wait until postgres has started | ||
options: >- | ||
--health-cmd pg_isready | ||
--health-interval 10s | ||
--health-timeout 5s | ||
--health-retries 5 | ||
ports: | ||
# Maps tcp port 5432 on service container to the host | ||
- 5432:5432 | ||
env: | ||
MAILING_DATABASE_URL_TEST: postgresql://postgres:postgres@localhost:5432/mailing_cli_test | ||
WEB_DATABASE_URL_TEST: postgresql://postgres:postgres@localhost:5432/mailing_test | ||
MAILING_WEB_SESSION_PASSWORD: test-YEAed65EasPz7zbGF4fuoMTDka7C | ||
MAILING_SESSION_PASSWORD: test-5toTch6whgDvErN1nPg0hbDq6Do6 | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
- name: Use Node.js 18.x | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 18 | ||
cache: "yarn" | ||
- name: Install dependencies | ||
run: yarn | ||
- name: Build the app | ||
run: yarn build | ||
- name: Cypress run integration tests | ||
run: yarn test:integration:cypress |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
packages/cli/cypress/e2e/__integration__/signupAndAuthenticate.cy.integration.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
describe("login tests", () => { | ||
before(() => { | ||
cy.task("db:reset"); | ||
}); | ||
|
||
it("should be able to signup, login, and everything else", () => { | ||
const email = "[email protected]"; | ||
cy.visit("/signup"); | ||
cy.location("pathname").should("eq", "/signup"); | ||
|
||
cy.get("h1").should("contain", "Signup"); | ||
cy.get("input#email").should("exist"); | ||
|
||
// invalid email should give an error | ||
cy.get("input#email").type("test"); | ||
cy.get("form").submit(); | ||
cy.get(".form-error").should("contain", "email is invalid"); | ||
|
||
// invalid password (blank) should give an error | ||
cy.get("input#email").clear().type(email); | ||
cy.get("form").submit(); | ||
cy.get(".form-error").should( | ||
"contain", | ||
"password should be at least 8 characters" | ||
); | ||
|
||
// fill in email and passord fields with valid values and then submit the form | ||
cy.get("input#email").clear().type(email); | ||
cy.get("input#password").type("password"); | ||
cy.get("form").submit(); | ||
|
||
// it should redirect to the login page | ||
cy.location("pathname").should("eq", "/login"); | ||
cy.get("h1").should("contain", "Login"); | ||
|
||
// fill in email and passord fields and then submit the form | ||
cy.get("input#email").type(email); | ||
cy.get("input#password").type("password"); | ||
cy.get("form").submit(); | ||
|
||
// it should redirect you to the settings page | ||
cy.location("pathname").should("eq", "/settings"); | ||
cy.get("h1").should("contain", "Settings"); | ||
|
||
// you should see a default api key that was created | ||
cy.get("#api-keys tbody tr").should("have.length", 1); | ||
|
||
// you should see a button to add an API key | ||
cy.get("button").should("contain", "New API Key"); | ||
|
||
// click the button to add an API key | ||
cy.get("button").click(); | ||
|
||
// you should see 2 api keys in the tbody instead of 1 | ||
cy.get("#api-keys tbody tr").should("have.length", 2); | ||
|
||
// you should get a 404 if you try to go back to /signup, only 1 user is allowed to signup | ||
cy.visit("/signup", { failOnStatusCode: false }); | ||
cy.request({ | ||
url: "/signup", | ||
followRedirect: false, | ||
failOnStatusCode: false, | ||
}).then((response) => { | ||
expect(response.status).to.eq(404); | ||
expect(response.redirectedToUrl).to.eq(undefined); | ||
}); | ||
|
||
// logout | ||
cy.request({ | ||
url: "/api/logout", | ||
}).then((response) => { | ||
expect(response.status).to.eq(200); | ||
}); | ||
|
||
cy.visit("/settings", { failOnStatusCode: false }); | ||
cy.request({ | ||
url: "/settings", | ||
followRedirect: false, | ||
failOnStatusCode: false, | ||
}).then((response) => { | ||
expect(response.status).to.eq(307); | ||
expect(response.redirectedToUrl).to.eq("http://localhost:3883/login"); | ||
}); | ||
|
||
// you can visit the login page | ||
cy.visit("/login"); | ||
cy.location("pathname").should("eq", "/login"); | ||
cy.get("h1").should("contain", "Login"); | ||
|
||
// it should give you an error if you try to login with the wrong password | ||
cy.get("input#email").type(email); | ||
cy.get("input#password").type("wrongpassword"); | ||
cy.get("form").submit(); | ||
|
||
cy.get(".form-error").should("contain", "invalid password"); | ||
}); | ||
|
||
it("should show the user an error message if they try to login with an invalid email", () => { | ||
// visit the login page | ||
cy.visit("/login"); | ||
cy.location("pathname").should("eq", "/login"); | ||
cy.get("h1").should("contain", "Login"); | ||
|
||
// fill in email and passord fields and then submit the form | ||
cy.get("input#email").type("[email protected]"); | ||
cy.get("input#password").type("password"); | ||
cy.get("form").submit(); | ||
|
||
// it should show an error message | ||
cy.get("div.form-error").should( | ||
"contain", | ||
"no user exists with that email" | ||
); | ||
}); | ||
|
||
it("login is required on /settings", () => { | ||
cy.visit("/settings", { failOnStatusCode: false }); | ||
cy.request({ | ||
url: "/settings", | ||
followRedirect: false, | ||
failOnStatusCode: false, | ||
}).then((response) => { | ||
expect(response.status).to.eq(307); | ||
expect(response.redirectedToUrl).to.eq("http://localhost:3883/login"); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { defineConfig } from "cypress"; | ||
import cliPrisma from "./prisma"; | ||
import webPrisma from "../../packages/web/prisma"; | ||
import type { PrismaTableName } from "../../testUtilIntegration"; | ||
|
||
const resetDb = async () => { | ||
await truncateDatabases(); | ||
return null; | ||
}; | ||
|
||
export default defineConfig({ | ||
e2e: { | ||
specPattern: "**/*.cy.integration.{js,jsx,ts,tsx}", | ||
defaultCommandTimeout: 10000, | ||
baseUrl: "http://localhost:3883", | ||
setupNodeEvents(on, _config) { | ||
on("task", { | ||
"db:reset": resetDb, | ||
}); | ||
}, | ||
}, | ||
}); | ||
|
||
// copied from testUtilIntegration.ts | ||
|
||
export async function truncateCliDatabase() { | ||
await truncateTables(cliPrisma); | ||
} | ||
|
||
export async function truncateWebDatabase() { | ||
await truncateTables(webPrisma); | ||
} | ||
|
||
export async function truncateDatabases() { | ||
return Promise.all([truncateCliDatabase(), truncateWebDatabase()]); | ||
} | ||
|
||
async function truncateTables(client: any) { | ||
const tables = | ||
(await client.$queryRaw`SELECT table_name FROM information_schema.tables where table_schema = 'public' AND table_name NOT like '_prisma%';`) as PrismaTableName[]; | ||
|
||
const joinedTableNames = tables | ||
.map((t: PrismaTableName) => `"${t.table_name}"`) | ||
.join(", "); | ||
|
||
const query = `TRUNCATE ${joinedTableNames} CASCADE;`; | ||
await client.$executeRawUnsafe(query); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1499e90
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
web – ./packages/web
web-sofn.vercel.app
web-rho-puce.vercel.app
web-git-main-sofn.vercel.app
www.mailing.run
mailing.run
1499e90
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
mailing-dynamic-demo – ./
mailing-dynamic-demo.vercel.app
mailing-dynamic-demo-git-main-sofn.vercel.app
mailing-dynamic-demo-sofn.vercel.app
demo.mailing.run