From 9c7f641c0b3844dc3bf71b08eb7cfd6803b7e90b Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Mon, 28 Nov 2022 18:11:28 -0800 Subject: [PATCH 01/22] Run tests+checks on push/PR to all branches This makes it so that you don't have to wait to PR to see the github workflow, if you've created a new development branch to work on your feature. --- .github/workflows/node.js.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 2f253063..897518e2 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -5,9 +5,9 @@ name: Tests, style checks, and type checks on: push: - branches: ['main', 'beta', 'development', 'test-system'] + branches: '**' pull_request: - branches: ['main', 'beta', 'development', 'test-system'] + branches: '**' jobs: test-unit: From fbbd0cc25aaeddf2a35a3a718c66fde29560344a Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Mon, 28 Nov 2022 17:18:59 -0800 Subject: [PATCH 02/22] Allow e2e test retries both locally and in CI Chromium tests are flaking pretty frequently. This will allow for less frequent manually rerunning while doing local e2e test runs. --- playwright.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index f5056bb5..b81b4bca 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -25,8 +25,8 @@ const config: PlaywrightTestConfig = { fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, + /* Retry on both CI and local dev */ + retries: 2, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ From 19e449a4eb9988d6868f1cb60de9de62b3e3b0ef Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Mon, 28 Nov 2022 14:59:30 -0800 Subject: [PATCH 03/22] Write e2e tests for cert creation I've added two basic tests: - Just create a cert and check that we end up on the right page - Create a cert and verify that the fields are filled out I've added some TODOs to verify even more fields than I've checked so far. --- tests/e2e/create-cert.test.ts | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/e2e/create-cert.test.ts diff --git a/tests/e2e/create-cert.test.ts b/tests/e2e/create-cert.test.ts new file mode 100644 index 00000000..096c3354 --- /dev/null +++ b/tests/e2e/create-cert.test.ts @@ -0,0 +1,70 @@ +import { type Page, expect, test } from '@playwright/test' + +const proofText = 'https://forum.effectivealtruism.org' +const counterfactualText = 'I would be sitting around doing nothing.' +const descriptionText = 'Just a random description.' + +test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:3000/') + await page.click('text=Log in') + await page.click('text=Sign in with Mock Login') +}) + +test.describe('Create Certificate', () => { + test('should allow creating new certificate', async ({ page }) => { + const titleText = 'My test project 0001' + + await page.click('text=New project') + await fillInDefaultValues(page, titleText) + await page.locator('button:has-text("Submit")').click() + + // Check we've landed on the cert page. + await expect(page).toHaveTitle(new RegExp('.*' + titleText + '.*')) + }) + + test('should fill in all certificate values', async ({ page }) => { + const titleText = 'My test project 0002' + + await page.click('text=New project') + await fillInDefaultValues(page, titleText) + await page.locator('button:has-text("Submit")').click() + + // Check we've landed on the cert page. + await expect(page).toHaveTitle(new RegExp('.*' + titleText + '.*')) + + // Verify certificate values. + await expect(page.getByRole('heading', { level: 1 })).toContainText( + titleText + ) + await expect(page.locator('text=Proof of ownership')).toHaveAttribute( + 'href', + proofText + ) + await page.locator('text=' + descriptionText).click() // Just clicking to verify it's there. + }) +}) + +async function fillInDefaultValues(page: Page, titleText: string) { + await page.getByRole('textbox', { name: 'title' }).fill(titleText) + await page.getByRole('textbox', { name: 'proof' }).fill(proofText) + + // TODO: start + end dates + //await page.getByRole('textbox', { name: 'actionStart' }).fill(actionStartText) + //await page.getByRole('textbox', { name: 'actionEnd' }).fill(actionEndText) + + await page + .getByRole('textbox', { name: 'counterfactual' }) + .fill(counterfactualText) + + // TODO: Tags + //await page.selectOption('#tags', [{label: tagLabel}]) + + await page.locator(':nth-match(textarea, 1)').fill(descriptionText) + + // TODO: Advanced options + + await page.click('text=I will never sell these rights more than once') + await page.click( + 'text=I am happy for this record to be publicly accessible forever' + ) +} From fef526c08300af5a5fee100bcca889f9723675bf Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Tue, 29 Nov 2022 22:48:10 +0100 Subject: [PATCH 04/22] Ignore my local backup of .env --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 72d7b966..0f8d03ac 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ yarn-error.log* .env.development.local .env.test.local .env.production.local +.env.backup # vercel .vercel From 6efa030d4b094d961977af0f28e3929b4c0b9c55 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Tue, 29 Nov 2022 22:48:41 +0100 Subject: [PATCH 05/22] Hopefully prevent the first test/s from failing --- playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index b81b4bca..57be221e 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -100,7 +100,7 @@ const config: PlaywrightTestConfig = { /* Run your local dev server before starting the tests */ webServer: { command: 'npm run dev', - port: 3000, + url: 'http://localhost:3000', }, } From 4629b1fca3449f7f624f4d0f3a1fc804690bf66c Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Tue, 29 Nov 2022 22:49:06 +0100 Subject: [PATCH 06/22] Expose the headless switch for easy switching --- playwright.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/playwright.config.ts b/playwright.config.ts index 57be221e..6bab1660 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -40,6 +40,8 @@ const config: PlaywrightTestConfig = { /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', + /* Switch to false to see the browser */ + headless: true, }, /* Configure projects for major browsers */ From 9cf399eef5705360df921e191a4baf12e322d82f Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Tue, 29 Nov 2022 22:49:25 +0100 Subject: [PATCH 07/22] Remove old sample test --- tests/e2e/gotopagesample.test.ts | 2 +- tests/e2e/sample.test.ts | 20 -------------------- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 tests/e2e/sample.test.ts diff --git a/tests/e2e/gotopagesample.test.ts b/tests/e2e/gotopagesample.test.ts index 8080c1d0..7a46a82a 100644 --- a/tests/e2e/gotopagesample.test.ts +++ b/tests/e2e/gotopagesample.test.ts @@ -1,4 +1,4 @@ -import { type Page, expect, test } from '@playwright/test' +import { expect, test } from '@playwright/test' test.beforeEach(async ({ page }) => { await page.goto('http://localhost:3000/') diff --git a/tests/e2e/sample.test.ts b/tests/e2e/sample.test.ts deleted file mode 100644 index 4b7c261f..00000000 --- a/tests/e2e/sample.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { expect, test } from '@playwright/test' - -test('homepage has title and links to intro page', async ({ page }) => { - await page.goto('https://playwright.dev/') - - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Playwright/) - - // create a locator - const getStarted = page.getByRole('link', { name: 'Get started' }) - - // Expect an attribute "to be strictly equal" to the value. - await expect(getStarted).toHaveAttribute('href', '/docs/intro') - - // Click the get started link. - await getStarted.click() - - // Expects the URL to contain intro. - await expect(page).toHaveURL(/.*intro/) -}) From 673957f55807f66bbeb385433c9354470f62f347 Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Thu, 1 Dec 2022 15:06:15 -0800 Subject: [PATCH 08/22] Delete the other sample test --- tests/e2e/gotopagesample.test.ts | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 tests/e2e/gotopagesample.test.ts diff --git a/tests/e2e/gotopagesample.test.ts b/tests/e2e/gotopagesample.test.ts deleted file mode 100644 index 7a46a82a..00000000 --- a/tests/e2e/gotopagesample.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { expect, test } from '@playwright/test' - -test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3000/') -}) - -test('homepage has title', async ({ page }) => { - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Markets/) -}) From 77556f530443c145e8aa3465fb9e548a258ecd80 Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Thu, 1 Dec 2022 15:42:01 -0800 Subject: [PATCH 09/22] Change test db to be different from normal db Now running the e2e tests locally won't modify your local im-app database anymore. They get their own im-app-test database. --- .env.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.test b/.env.test index cbabc3d2..e1b0ed5a 100644 --- a/.env.test +++ b/.env.test @@ -1,7 +1,7 @@ # Nonstandard port to avoid clashes with other local DB servers. # Also a unique port for testing, so users can run automated tests locally without clashing with # their local manual testing. -DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54322/im-app +DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54322/im-app-test NEXT_APP_URL= From 7bd18d696694ead809d98ce5431a4c521e58350a Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Thu, 1 Dec 2022 16:10:08 -0800 Subject: [PATCH 10/22] Use port 3001 for tests --- .env.test | 4 ++-- env/server.ts | 1 + lib/auth.ts | 2 +- playwright.config.ts | 6 +++--- tests/e2e/create-cert.test.ts | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.env.test b/.env.test index e1b0ed5a..571e5b45 100644 --- a/.env.test +++ b/.env.test @@ -3,9 +3,9 @@ # their local manual testing. DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54322/im-app-test -NEXT_APP_URL= +NEXT_APP_URL=http://localhost:3001 -NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_URL=http://localhost:3001 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= diff --git a/env/server.ts b/env/server.ts index c2ff74e5..460180f6 100644 --- a/env/server.ts +++ b/env/server.ts @@ -58,6 +58,7 @@ export const serverEnv = { allowEmpty: true, devDefault: 'http://localhost:3000', }), + NEXTAUTH_URL: str(), NEXTAUTH_SECRET: str({ devDefault: 'xxx', }), diff --git a/lib/auth.ts b/lib/auth.ts index 8383a77a..2079f2ef 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -53,7 +53,7 @@ if (serverEnv.MOCK_LOGIN) { authOptions.callbacks!.jwt = async ({ token }) => { const email = 'mock.user@example.com' const name = 'Mock User' - const image = 'http://localhost:3000/images/logo-min-light.png' + const image = serverEnv.NEXTAUTH_URL + '/images/logo-min-light.png' const role = Role.USER const user = await prisma.user.upsert({ select: { id: true, name: true, role: true, image: true, email: true }, diff --git a/playwright.config.ts b/playwright.config.ts index 6bab1660..e5aff6d2 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -36,7 +36,7 @@ const config: PlaywrightTestConfig = { /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ actionTimeout: 0, /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://localhost:3000', + // baseURL: 'http://localhost:3001', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -101,8 +101,8 @@ const config: PlaywrightTestConfig = { /* Run your local dev server before starting the tests */ webServer: { - command: 'npm run dev', - url: 'http://localhost:3000', + command: 'PORT=3001 npm run dev', + url: 'http://localhost:3001', }, } diff --git a/tests/e2e/create-cert.test.ts b/tests/e2e/create-cert.test.ts index 096c3354..7827212c 100644 --- a/tests/e2e/create-cert.test.ts +++ b/tests/e2e/create-cert.test.ts @@ -5,7 +5,7 @@ const counterfactualText = 'I would be sitting around doing nothing.' const descriptionText = 'Just a random description.' test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3000/') + await page.goto('http://localhost:3001/') await page.click('text=Log in') await page.click('text=Sign in with Mock Login') }) From 45b0b6353b02fb30f3a746c0840d5c4cd6a369f0 Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Thu, 1 Dec 2022 17:13:55 -0800 Subject: [PATCH 11/22] Use separate service and network name for test docker --- docker-compose.test.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docker-compose.test.yaml b/docker-compose.test.yaml index 91e0c04e..1e74cfc7 100644 --- a/docker-compose.test.yaml +++ b/docker-compose.test.yaml @@ -1,7 +1,7 @@ version: '3.5' services: - postgres: + postgres-test: image: 'postgres:14-alpine' volumes: - postgres-data:/var/lib/postgresql/data/ @@ -10,6 +10,12 @@ services: - POSTGRES_PASSWORD=empty ports: - '127.0.0.1:54322:5432' + networks: + - test + +networks: + test: + name: test volumes: postgres-data: From 6d4239c8f93307a89efb36408cebfa9204f1f860 Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Thu, 1 Dec 2022 17:15:50 -0800 Subject: [PATCH 12/22] Automatically use .env.test for running tests Now, locally, you don't need to run `cp .env.test .env` anymore. --- .github/workflows/node.js.yml | 4 +- package-lock.json | 73 +++++++++++++++++++++++++++-------- package.json | 2 + playwright.config.ts | 2 +- 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 897518e2..f7b6da4e 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -63,12 +63,10 @@ jobs: run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Set up environment variables for the test env - run: cp .env.test .env - name: Start the test database run: docker-compose -f docker-compose.test.yaml up -d - name: Create the database schema - run: npx prisma migrate deploy + run: npx dotenv -e .env.test -- npx prisma migrate deploy - name: Run Playwright tests run: npm run test:e2e - uses: actions/upload-artifact@v3 diff --git a/package-lock.json b/package-lock.json index 53b4d052..7f5aafd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,8 @@ "csstype": "^3.1.0", "cuid": "^2.1.8", "date-fns": "^2.29.1", + "dotenv": "^16.0.3", + "dotenv-cli": "^6.0.0", "envsafe": "^2.0.3", "gemoji": "^7.1.0", "isomorphic-dompurify": "^0.20.0", @@ -4423,7 +4425,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4857,6 +4858,36 @@ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/dotenv-cli": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-6.0.0.tgz", + "integrity": "sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "dotenv": "^16.0.0", + "dotenv-expand": "^8.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "dotenv": "cli.js" + } + }, + "node_modules/dotenv-expand": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", + "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==", + "engines": { + "node": ">=12" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.218", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.218.tgz", @@ -6789,8 +6820,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isomorphic-dompurify": { "version": "0.20.0", @@ -10186,7 +10216,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -11397,7 +11426,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -11409,7 +11437,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -12569,7 +12596,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -15984,7 +16010,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -16300,6 +16325,27 @@ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "dotenv-cli": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-6.0.0.tgz", + "integrity": "sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==", + "requires": { + "cross-spawn": "^7.0.3", + "dotenv": "^16.0.0", + "dotenv-expand": "^8.0.1", + "minimist": "^1.2.5" + } + }, + "dotenv-expand": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", + "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==" + }, "electron-to-chromium": { "version": "1.4.218", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.218.tgz", @@ -17703,8 +17749,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isomorphic-dompurify": { "version": "0.20.0", @@ -20238,8 +20283,7 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -21071,7 +21115,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -21079,8 +21122,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "shell-quote": { "version": "1.7.4", @@ -21940,7 +21982,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } diff --git a/package.json b/package.json index 520bfa67..ac2ea70d 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,8 @@ "csstype": "^3.1.0", "cuid": "^2.1.8", "date-fns": "^2.29.1", + "dotenv": "^16.0.3", + "dotenv-cli": "^6.0.0", "envsafe": "^2.0.3", "gemoji": "^7.1.0", "isomorphic-dompurify": "^0.20.0", diff --git a/playwright.config.ts b/playwright.config.ts index e5aff6d2..528f04fa 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,7 +5,7 @@ import { devices } from '@playwright/test' * Read environment variables from file. * https://github.com/motdotla/dotenv */ -// require('dotenv').config(); +require('dotenv').config({ path: '.env.test' }) /** * See https://playwright.dev/docs/test-configuration. From c26542cfffeefaf73eb589e468c44248e91d7162 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sat, 3 Dec 2022 20:14:37 +0100 Subject: [PATCH 13/22] Rename env var --- .env.example | 2 +- .env.test | 2 +- env/server.ts | 2 +- lib/auth.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index e7824c42..ad0e899b 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,7 @@ DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54321/im-app NEXT_APP_URL= -NEXTAUTH_URL=http://localhost:3000 +FRONTEND_URL=http://localhost:3000 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= diff --git a/.env.test b/.env.test index 571e5b45..9c59f3e8 100644 --- a/.env.test +++ b/.env.test @@ -5,7 +5,7 @@ DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54322/im-app-test NEXT_APP_URL=http://localhost:3001 -NEXTAUTH_URL=http://localhost:3001 +FRONTEND_URL=http://localhost:3001 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= diff --git a/env/server.ts b/env/server.ts index 460180f6..f7a3feb9 100644 --- a/env/server.ts +++ b/env/server.ts @@ -58,7 +58,7 @@ export const serverEnv = { allowEmpty: true, devDefault: 'http://localhost:3000', }), - NEXTAUTH_URL: str(), + FRONTEND_URL: str(), NEXTAUTH_SECRET: str({ devDefault: 'xxx', }), diff --git a/lib/auth.ts b/lib/auth.ts index 2079f2ef..07d93e8e 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -53,7 +53,7 @@ if (serverEnv.MOCK_LOGIN) { authOptions.callbacks!.jwt = async ({ token }) => { const email = 'mock.user@example.com' const name = 'Mock User' - const image = serverEnv.NEXTAUTH_URL + '/images/logo-min-light.png' + const image = serverEnv.FRONTEND_URL + '/images/logo-min-light.png' const role = Role.USER const user = await prisma.user.upsert({ select: { id: true, name: true, role: true, image: true, email: true }, From c39bf96ce89a73dcba1f218294d031c66c02a1c8 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:04:20 +0100 Subject: [PATCH 14/22] Optimize .env.example for dev --- .env.example | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/.env.example b/.env.example index ad0e899b..47337abc 100644 --- a/.env.example +++ b/.env.example @@ -1,36 +1,20 @@ # Nonstandard port to avoid clashes with other local DB servers DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54321/im-app -NEXT_APP_URL= - -FRONTEND_URL=http://localhost:3000 +NEXT_APP_URL=http://localhost:3000 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= -GITHUB_ID= -GITHUB_SECRET= -GITHUB_ALLOWED_ORG= - -OKTA_CLIENT_ID= -OKTA_CLIENT_SECRET= -OKTA_ISSUER= - -NEXTAUTH_SECRET= +# https://next-auth.js.org/configuration/options#nextauth_url +NEXTAUTH_SECRET=foobar +NEXTAUTH_URL=${NEXT_APP_URL} NEXT_PUBLIC_ENABLE_IMAGE_UPLOAD= CLOUDINARY_CLOUD_NAME= CLOUDINARY_API_KEY= CLOUDINARY_API_SECRET= -ENABLE_SLACK_POSTING= -SLACK_WEBHOOK_URL= - NEXT_PUBLIC_INTERCOM_APP_ID=gbn0p3de -ROLLBAR_SERVER_TOKEN= -NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN= - -DEBUG=false - -MOCK_LOGIN=false +DEBUG=true \ No newline at end of file From e22eea8303fd2ff262a5cd197b39f0158be45ffd Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:07:04 +0100 Subject: [PATCH 15/22] Revert/restore Next Auth URL variable --- .env.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.env.test b/.env.test index 9c59f3e8..ab5c2abb 100644 --- a/.env.test +++ b/.env.test @@ -5,7 +5,9 @@ DATABASE_URL=postgresql://im-app:empty@127.0.0.1:54322/im-app-test NEXT_APP_URL=http://localhost:3001 -FRONTEND_URL=http://localhost:3001 +# https://next-auth.js.org/configuration/options#nextauth_url +NEXTAUTH_SECRET=foobar +NEXTAUTH_URL=${NEXT_APP_URL} GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= From fab32b4f99341023164e9342b5fe1bda5eea3852 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:07:37 +0100 Subject: [PATCH 16/22] Condense .env.test --- .env.test | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/.env.test b/.env.test index ab5c2abb..36b31679 100644 --- a/.env.test +++ b/.env.test @@ -9,32 +9,12 @@ NEXT_APP_URL=http://localhost:3001 NEXTAUTH_SECRET=foobar NEXTAUTH_URL=${NEXT_APP_URL} -GOOGLE_CLIENT_ID= -GOOGLE_CLIENT_SECRET= - -GITHUB_ID= -GITHUB_SECRET= -GITHUB_ALLOWED_ORG= - -OKTA_CLIENT_ID= -OKTA_CLIENT_SECRET= -OKTA_ISSUER= - -NEXTAUTH_SECRET= - -NEXT_PUBLIC_ENABLE_IMAGE_UPLOAD= -CLOUDINARY_CLOUD_NAME= -CLOUDINARY_API_KEY= -CLOUDINARY_API_SECRET= - ENABLE_SLACK_POSTING= SLACK_WEBHOOK_URL= - NEXT_PUBLIC_INTERCOM_APP_ID=gbn0p3de -ROLLBAR_SERVER_TOKEN= -NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN= +MOCK_LOGIN=true -DEBUG=false +NODE_ENV=test -MOCK_LOGIN=true +PORT=3001 \ No newline at end of file From 58166fa87158493940d3c01e0d91332e7a0114cc Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:08:47 +0100 Subject: [PATCH 17/22] Upgrade Playwright to fix bug #18865 --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f5aafd5..57df89b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "zod": "^3.17.10" }, "devDependencies": { - "@playwright/test": "^1.28.0", + "@playwright/test": "^1.28.1", "@tailwindcss/forms": "^0.5.2", "@tailwindcss/typography": "^0.5.4", "@trivago/prettier-plugin-sort-imports": "^3.4.0", @@ -2259,13 +2259,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.0.tgz", - "integrity": "sha512-vrHs5DFTPwYox5SGKq/7TDn/S4q6RA1zArd7uhO6EyP9hj3XgZBBM12ktMbnDQNxh/fL1IUKsTNLxihmsU38lQ==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.1.tgz", + "integrity": "sha512-xN6spdqrNlwSn9KabIhqfZR7IWjPpFK1835tFNgjrlysaSezuX8PYUwaz38V/yI8TJLG9PkAMEXoHRXYXlpTPQ==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.28.0" + "playwright-core": "1.28.1" }, "bin": { "playwright": "cli.js" @@ -10359,9 +10359,9 @@ } }, "node_modules/playwright-core": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.0.tgz", - "integrity": "sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.1.tgz", + "integrity": "sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag==", "dev": true, "bin": { "playwright": "cli.js" @@ -14407,13 +14407,13 @@ "integrity": "sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA==" }, "@playwright/test": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.0.tgz", - "integrity": "sha512-vrHs5DFTPwYox5SGKq/7TDn/S4q6RA1zArd7uhO6EyP9hj3XgZBBM12ktMbnDQNxh/fL1IUKsTNLxihmsU38lQ==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.1.tgz", + "integrity": "sha512-xN6spdqrNlwSn9KabIhqfZR7IWjPpFK1835tFNgjrlysaSezuX8PYUwaz38V/yI8TJLG9PkAMEXoHRXYXlpTPQ==", "dev": true, "requires": { "@types/node": "*", - "playwright-core": "1.28.0" + "playwright-core": "1.28.1" } }, "@prisma/client": { @@ -20382,9 +20382,9 @@ } }, "playwright-core": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.0.tgz", - "integrity": "sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.1.tgz", + "integrity": "sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag==", "dev": true }, "postcss": { diff --git a/package.json b/package.json index ac2ea70d..9c188409 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "zod": "^3.17.10" }, "devDependencies": { - "@playwright/test": "^1.28.0", + "@playwright/test": "^1.28.1", "@tailwindcss/forms": "^0.5.2", "@tailwindcss/typography": "^0.5.4", "@trivago/prettier-plugin-sort-imports": "^3.4.0", From d145d3b62f52f17327ff235f48e6c592f569e3b1 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:09:13 +0100 Subject: [PATCH 18/22] Test the production build --- playwright.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index 528f04fa..8aad207d 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -101,8 +101,9 @@ const config: PlaywrightTestConfig = { /* Run your local dev server before starting the tests */ webServer: { - command: 'PORT=3001 npm run dev', + command: 'next build --no-lint && next start', url: 'http://localhost:3001', + timeout: 5 * 60 * 1000, }, } From 4487bed8d4a4fa91e2e2c076b327e18c73f976bc Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:10:00 +0100 Subject: [PATCH 19/22] Set more obvious dev defaults --- env/browser.ts | 2 +- env/server.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/env/browser.ts b/env/browser.ts index ef65b81c..3f35ed81 100644 --- a/env/browser.ts +++ b/env/browser.ts @@ -14,6 +14,6 @@ export const browserEnv = envsafe({ NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN: str({ input: process.env.NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN, allowEmpty: false, - devDefault: process.env.NODE_ENV, + devDefault: 'foobar', }), }) diff --git a/env/server.ts b/env/server.ts index f7a3feb9..ce1fff62 100644 --- a/env/server.ts +++ b/env/server.ts @@ -58,9 +58,8 @@ export const serverEnv = { allowEmpty: true, devDefault: 'http://localhost:3000', }), - FRONTEND_URL: str(), NEXTAUTH_SECRET: str({ - devDefault: 'xxx', + devDefault: 'foobar', }), DEBUG: bool({ default: false }), MOCK_LOGIN: bool({ default: false }), @@ -79,7 +78,7 @@ export const serverEnv = { SLACK_WEBHOOK_URL: slackParser({ allowEmpty: true, default: '' }), ROLLBAR_SERVER_TOKEN: rollbarParser({ allowEmpty: false, - devDefault: process.env.NODE_ENV, + devDefault: 'foobar', }), }), } From 67468939409a32f86971883861b1b5d05bb75755 Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:10:17 +0100 Subject: [PATCH 20/22] Fix variable name --- lib/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/auth.ts b/lib/auth.ts index 07d93e8e..72e8f6de 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -53,7 +53,7 @@ if (serverEnv.MOCK_LOGIN) { authOptions.callbacks!.jwt = async ({ token }) => { const email = 'mock.user@example.com' const name = 'Mock User' - const image = serverEnv.FRONTEND_URL + '/images/logo-min-light.png' + const image = serverEnv.NEXT_APP_URL + '/images/logo-min-light.png' const role = Role.USER const user = await prisma.user.upsert({ select: { id: true, name: true, role: true, image: true, email: true }, From 90322eb88f5c62ddca80db93dd82a706b546d0ce Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:12:31 +0100 Subject: [PATCH 21/22] Skip one page load --- tests/e2e/create-cert.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/e2e/create-cert.test.ts b/tests/e2e/create-cert.test.ts index 7827212c..c4a6cb69 100644 --- a/tests/e2e/create-cert.test.ts +++ b/tests/e2e/create-cert.test.ts @@ -5,8 +5,7 @@ const counterfactualText = 'I would be sitting around doing nothing.' const descriptionText = 'Just a random description.' test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3001/') - await page.click('text=Log in') + await page.goto('http://localhost:3001/api/auth/signin') await page.click('text=Sign in with Mock Login') }) From d5709f20ab2d58a0de3a07fe833fd7d6fcd2814c Mon Sep 17 00:00:00 2001 From: Dawn Drescher Date: Sun, 4 Dec 2022 04:15:31 +0100 Subject: [PATCH 22/22] Remove separate run for PRs --- .github/workflows/node.js.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index f7b6da4e..eb81576e 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -6,8 +6,6 @@ name: Tests, style checks, and type checks on: push: branches: '**' - pull_request: - branches: '**' jobs: test-unit: