From 39c58a5d426e5fc1224294d7bbd2f0def9a95da6 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Mon, 19 Jan 2026 09:10:26 -0800 Subject: [PATCH 01/14] updates for playwright --- .devcontainer/devcontainer.json | 3 ++- .gitignore | 3 +++ package.json | 2 +- playwright.config.ts | 39 +++++++++++++++++++-------------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ae6e22c3..2be219ed 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -31,7 +31,8 @@ "github.vscode-pull-request-github", "ms-vsliveshare.vsliveshare", "irongeek.vscode-env", - "csstools.postcss" + "csstools.postcss", + "ms-playwright.playwright" ], "settings": { "files.eol": "\n", diff --git a/.gitignore b/.gitignore index 490cee38..eaa270dc 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ /coverage /playwright-report/* /test-results/* +/blob-report/ +/playwright/.cache/ +/playwright/.auth/ # next.js /.next/ diff --git a/package.json b/package.json index 62f73fc6..869ac41e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "test:e2e": "playwright test", "test:e2e:ui": "playwright test --ui", "test:e2e:headed": "playwright test --headed", - "playwright:install": "playwright install", + "playwright:install": "playwright install-deps && playwright install", "clean": "rm -rf .next out build dist coverage test-results playwright-report", "check-licenses": "tsx scripts/check-licenses.ts", "db:push": "prisma db push", diff --git a/playwright.config.ts b/playwright.config.ts index 1e87c2f8..8ecea4cf 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,21 +4,28 @@ import { defineConfig, devices } from '@playwright/test' * @see https://playwright.dev/docs/test-configuration */ export default defineConfig({ - testDir: './e2e', + /* Where to look for test files */ + testDir: './tests', + /* Run tests in files in parallel */ 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, + /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ ['html'], ['json', { outputFile: 'playwright-report/results.json' }], ['junit', { outputFile: 'playwright-report/results.xml' }] ], + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ @@ -50,6 +57,13 @@ export default defineConfig({ name: 'webkit', use: { ...devices['Desktop Safari'] }, }, + /* Test against branded browsers. */ + // Currently Microsoft Edge for Linux is not available for arm64 systems + // Can uncomment when support is added + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, /* Test against mobile viewports. */ { @@ -61,22 +75,15 @@ export default defineConfig({ use: { ...devices['iPhone 12'] }, }, - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { ...devices['Desktop Edge'], channel: 'msedge' }, - // }, - // { - // name: 'Google Chrome', - // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, - // }, + ], /* Run your local dev server before starting the tests */ - webServer: { - command: 'npm run dev', - url: 'http://localhost:3000', - reuseExistingServer: !process.env.CI, - timeout: 120 * 1000, - }, + /* Uncomment if running locally instead of in DevContainer */ + // webServer: { + // command: 'npm run dev', + // url: 'http://localhost:3000', + // reuseExistingServer: !process.env.CI, + // timeout: 120 * 1000, + // }, }) From 6d2b3b2b7195f2b8c70aa1c93fe512ab4cec0cdc Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Mon, 19 Jan 2026 09:10:47 -0800 Subject: [PATCH 02/14] testing playwright file --- tests/example.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/example.spec.ts diff --git a/tests/example.spec.ts b/tests/example.spec.ts new file mode 100644 index 00000000..54a906a4 --- /dev/null +++ b/tests/example.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from '@playwright/test'; + +test('has title', async ({ page }) => { + await page.goto('https://playwright.dev/'); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Playwright/); +}); + +test('get started link', async ({ page }) => { + await page.goto('https://playwright.dev/'); + + // Click the get started link. + await page.getByRole('link', { name: 'Get started' }).click(); + + // Expects page to have a heading with the name of Installation. + await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible(); +}); From 9f73304808f9e1cd28856f11049263a089b14a0a Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Wed, 21 Jan 2026 10:33:07 -0800 Subject: [PATCH 03/14] update test and add accessibility testing --- package.json | 2 ++ src/app/page.tsx | 3 ++- tests/example.spec.ts | 25 ++++++++++++++----------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 869ac41e..f4df7e34 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "test:e2e": "playwright test", "test:e2e:ui": "playwright test --ui", "test:e2e:headed": "playwright test --headed", + "test:e2e:report": "playwright show-report", "playwright:install": "playwright install-deps && playwright install", "clean": "rm -rf .next out build dist coverage test-results playwright-report", "check-licenses": "tsx scripts/check-licenses.ts", @@ -52,6 +53,7 @@ "zustand": "5.0.7" }, "devDependencies": { + "@axe-core/playwright": "4.11.0", "@biomejs/biome": "2.1.3", "@playwright/test": "1.54.1", "@tailwindcss/aspect-ratio": "0.4.2", diff --git a/src/app/page.tsx b/src/app/page.tsx index 451b8dbb..0d434b73 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,12 +4,13 @@ import { ExampleModal } from "@/components/examples/ExampleModal" export default function Home() { return (
-

TEST

+

TEST

Some body content here
+ {/*
This should fail
*/}
) } diff --git a/tests/example.spec.ts b/tests/example.spec.ts index 54a906a4..c0b1e6de 100644 --- a/tests/example.spec.ts +++ b/tests/example.spec.ts @@ -1,18 +1,21 @@ import { test, expect } from '@playwright/test'; +import AxeBuilder from '@axe-core/playwright'; -test('has title', async ({ page }) => { - await page.goto('https://playwright.dev/'); +test.describe('homepage', () => { + test('has paragraph', async ({ page }) => { + await page.goto('http://localhost:3000/'); - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Playwright/); -}); + // Expect a title "to contain" a substring. + await expect(page.locator('h1')).toContainText('TEST'); + }); -test('get started link', async ({ page }) => { - await page.goto('https://playwright.dev/'); + test('should not have any automatically detectable accessibility issues', async ({ page }) => { + await page.goto('http://localhost:3000/'); - // Click the get started link. - await page.getByRole('link', { name: 'Get started' }).click(); + const accessibilityScanResults = await new AxeBuilder({ page }) + .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) + .analyze(); - // Expects page to have a heading with the name of Installation. - await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible(); + expect(accessibilityScanResults.violations).toEqual([]); + }); }); From c725704e3fda0286e026cbefe4354fa1781c74c7 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Wed, 28 Jan 2026 15:10:07 -0800 Subject: [PATCH 04/14] fixing playwright reports and config --- .gitignore | 4 ++-- package.json | 10 +++++----- playwright.config.ts | 30 ++++++++++++++++-------------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index eaa270dc..1ae6545c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,8 @@ # testing /coverage -/playwright-report/* -/test-results/* +/playwright/report/* +/playwright/test-results/* /blob-report/ /playwright/.cache/ /playwright/.auth/ diff --git a/package.json b/package.json index f4df7e34..58baf4f7 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,11 @@ "test:run": "vitest run", "test:coverage": "vitest run --coverage", "test:e2e": "playwright test", - "test:e2e:ui": "playwright test --ui", - "test:e2e:headed": "playwright test --headed", - "test:e2e:report": "playwright show-report", - "playwright:install": "playwright install-deps && playwright install", - "clean": "rm -rf .next out build dist coverage test-results playwright-report", + "test:e2e-ui": "playwright test --ui", + "test:e2e-headed": "playwright test --headed", + "test:e2e-report": "playwright show-report playwright/report", + "test:e2e-install": "playwright install-deps && playwright install", + "clean": "rm -rf .next out build dist coverage playwright/test-results playwright/report", "check-licenses": "tsx scripts/check-licenses.ts", "db:push": "prisma db push", "db:migrate": "prisma migrate dev", diff --git a/playwright.config.ts b/playwright.config.ts index 8ecea4cf..930fd162 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,7 +5,9 @@ import { defineConfig, devices } from '@playwright/test' */ export default defineConfig({ /* Where to look for test files */ - testDir: './tests', + testDir: './playwright/tests', + /* Where to store the test results */ + outputDir: './playwright/test-results/', /* Run tests in files in parallel */ fullyParallel: true, @@ -21,9 +23,8 @@ export default defineConfig({ /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ - ['html'], - ['json', { outputFile: 'playwright-report/results.json' }], - ['junit', { outputFile: 'playwright-report/results.xml' }] + ['html', { outputFolder: 'playwright/report'}], + ['json', { outputFile: 'playwright/report/results.json' }] ], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ @@ -48,10 +49,11 @@ export default defineConfig({ use: { ...devices['Desktop Chrome'] }, }, - { - name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - }, + // Uncomment to test in Firefox - this currently hits issues on my Mac because permissions with HTTP and DNS maybe? + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, { name: 'webkit', @@ -80,10 +82,10 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ /* Uncomment if running locally instead of in DevContainer */ - // webServer: { - // command: 'npm run dev', - // url: 'http://localhost:3000', - // reuseExistingServer: !process.env.CI, - // timeout: 120 * 1000, - // }, + webServer: { + command: 'npm run dev', + url: 'http://localhost:3000', + reuseExistingServer: !process.env.CI, + timeout: 120 * 1000, + }, }) From 3452af6ca559dd6df80b891d5d8d51658b38aee0 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Wed, 28 Jan 2026 15:10:29 -0800 Subject: [PATCH 05/14] updating tests --- playwright/tests/customAxeBuilder.ts | 22 +++++++++++++++++++++ {tests => playwright/tests}/example.spec.ts | 8 +++----- src/app/page.tsx | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 playwright/tests/customAxeBuilder.ts rename {tests => playwright/tests}/example.spec.ts (63%) diff --git a/playwright/tests/customAxeBuilder.ts b/playwright/tests/customAxeBuilder.ts new file mode 100644 index 00000000..6487c8ee --- /dev/null +++ b/playwright/tests/customAxeBuilder.ts @@ -0,0 +1,22 @@ +import { test as base } from '@playwright/test'; +import AxeBuilder from '@axe-core/playwright'; + +type AxeFixture = { + makeAxeBuilder: () => AxeBuilder; +}; + +// Extend base test by providing "makeAxeBuilder" +// +// This new "test" can be used in multiple test files, and each of them will get +// a consistently configured AxeBuilder instance. +export const test = base.extend({ + makeAxeBuilder: async ({ page }, use) => { + const makeAxeBuilder = () => new AxeBuilder({ page }) + .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) + .exclude('#commonly-reused-element-with-known-issue'); + + await use(makeAxeBuilder); + } +}); + +export { expect } from '@playwright/test'; diff --git a/tests/example.spec.ts b/playwright/tests/example.spec.ts similarity index 63% rename from tests/example.spec.ts rename to playwright/tests/example.spec.ts index c0b1e6de..b7ccf349 100644 --- a/tests/example.spec.ts +++ b/playwright/tests/example.spec.ts @@ -1,5 +1,4 @@ -import { test, expect } from '@playwright/test'; -import AxeBuilder from '@axe-core/playwright'; +import { test, expect } from './customAxeBuilder'; test.describe('homepage', () => { test('has paragraph', async ({ page }) => { @@ -9,11 +8,10 @@ test.describe('homepage', () => { await expect(page.locator('h1')).toContainText('TEST'); }); - test('should not have any automatically detectable accessibility issues', async ({ page }) => { + test('should not have any automatically detectable accessibility issues', async ({ page, makeAxeBuilder }) => { await page.goto('http://localhost:3000/'); - const accessibilityScanResults = await new AxeBuilder({ page }) - .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) + const accessibilityScanResults = await makeAxeBuilder() .analyze(); expect(accessibilityScanResults.violations).toEqual([]); diff --git a/src/app/page.tsx b/src/app/page.tsx index 0d434b73..f8c8b341 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,7 +10,7 @@ export default function Home() { - {/*
This should fail
*/} +
This should fail
) } From e3b383c738b2afb9efbab00c26ce232d1a847faf Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Wed, 28 Jan 2026 16:02:00 -0800 Subject: [PATCH 06/14] accessibility testing first fix --- playwright/tests/customAxeBuilder.ts | 3 +-- playwright/tests/example.spec.ts | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/playwright/tests/customAxeBuilder.ts b/playwright/tests/customAxeBuilder.ts index 6487c8ee..cf4e72b1 100644 --- a/playwright/tests/customAxeBuilder.ts +++ b/playwright/tests/customAxeBuilder.ts @@ -12,8 +12,7 @@ type AxeFixture = { export const test = base.extend({ makeAxeBuilder: async ({ page }, use) => { const makeAxeBuilder = () => new AxeBuilder({ page }) - .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) - .exclude('#commonly-reused-element-with-known-issue'); + .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'best-practice']); await use(makeAxeBuilder); } diff --git a/playwright/tests/example.spec.ts b/playwright/tests/example.spec.ts index b7ccf349..ee4eb283 100644 --- a/playwright/tests/example.spec.ts +++ b/playwright/tests/example.spec.ts @@ -8,12 +8,18 @@ test.describe('homepage', () => { await expect(page.locator('h1')).toContainText('TEST'); }); - test('should not have any automatically detectable accessibility issues', async ({ page, makeAxeBuilder }) => { + test('should not have any automatically detectable accessibility issues', async ({ page, makeAxeBuilder }, testInfo) => { await page.goto('http://localhost:3000/'); const accessibilityScanResults = await makeAxeBuilder() .analyze(); + // Send test results to reporter to see more info + await testInfo.attach('accessibility-scan-results', { + body: JSON.stringify(accessibilityScanResults, null, 2), + contentType: 'application/json' + }) + expect(accessibilityScanResults.violations).toEqual([]); }); }); From b913cc8f95564513f04f191109658522b1083614 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Thu, 29 Jan 2026 09:20:05 -0800 Subject: [PATCH 07/14] messy merge main --- .devcontainer/compose.yml | 24 +----------------------- .devcontainer/devcontainer.json | 24 ++++-------------------- Dockerfile | 17 ++++------------- package.json | 12 ++++++------ tsconfig.json | 24 +++++++++++++++++++----- 5 files changed, 34 insertions(+), 67 deletions(-) diff --git a/.devcontainer/compose.yml b/.devcontainer/compose.yml index 7d20d025..23e5b4f0 100644 --- a/.devcontainer/compose.yml +++ b/.devcontainer/compose.yml @@ -3,7 +3,7 @@ services: tty: true init: true build: - context: ../ + context: .. dockerfile: Dockerfile args: NODE_TAG: 22-bullseye-slim @@ -14,10 +14,8 @@ services: environment: - PORT=3001 - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/sbc_queue - - RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672 depends_on: - postgres - - rabbitmq ports: - "127.0.0.1:3000:3001" networks: @@ -42,29 +40,9 @@ services: timeout: 5s retries: 5 - rabbitmq: - image: rabbitmq:3-management-alpine - restart: unless-stopped - environment: - - RABBITMQ_DEFAULT_USER=guest - - RABBITMQ_DEFAULT_PASS=guest - volumes: - - rabbitmq_data:/var/lib/rabbitmq - ports: - - "5672:5672" # AMQP port - - "15672:15672" # Management UI port - networks: - - sbc-queue-network - healthcheck: - test: ["CMD", "rabbitmq-diagnostics", "ping"] - interval: 10s - timeout: 5s - retries: 5 - volumes: node_modules: postgres_data: - rabbitmq_data: networks: sbc-queue-network: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2be219ed..b0a17d43 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,16 +10,12 @@ "CHOKIDAR_INTERVAL": "150" }, - // Override command to prevent conflicts - "overrideCommand": false, + "overrideCommand": true, - // Init configuration "init": true, - // Disable features that don't work well with Podman on Windows "features": {}, - // Configure tool-specific properties "customizations": { "vscode": { "extensions": [ @@ -54,11 +50,9 @@ } }, - // Additional Podman compatibility settings "shutdownAction": "none", - // Use 'forwardPorts' to make a list of ports inside the container available locally - "forwardPorts": [3000, 5432, 5672, 15672], + "forwardPorts": [3000, 5432], "portsAttributes": { "3000": { "label": "Next.js App", @@ -66,22 +60,12 @@ }, "5432": { "label": "PostgreSQL" - }, - "5672": { - "label": "RabbitMQ AMQP" - }, - "15672": { - "label": "RabbitMQ Management UI", - "onAutoForward": "openBrowser" } }, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root "remoteUser": "node", - // Use 'postCreateCommand' to run commands after the container is created - "postCreateCommand": "npm install && npm run db:generate && npm run db:migrate", + "postCreateCommand": "npm ci --no-fund && npm run db:generate && npm run db:migrate", - // Use 'postStartCommand' to run commands after the container starts - "postStartCommand": "echo 'Dev container is ready! 🚀'" + "postStartCommand": "npm run dev" } diff --git a/Dockerfile b/Dockerfile index 8427ed55..dd3ab52e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,25 +24,16 @@ WORKDIR /workspace # Ensure dev dependencies are available ENV NODE_ENV=development -# Copy package files first for better Docker layer caching -COPY package.json ./ - -# Install dependencies first (this creates platform-specific binaries) -RUN npm install - -# Copy the rest of the files -COPY . . +# Don’t copy app code or install deps in the image for a bind-mounted devcontainer. # Clean npm cache and rebuild all native dependencies for this architecture RUN npm cache clean --force && \ rm -rf node_modules/.cache && \ npm rebuild --verbose -# Change ownership of workspace to node user -RUN chown -R node:node /workspace - # Switch to non-root user USER node -# Default command -CMD ["npm", "run", "dev"] +# Keep the container alive for VS Code to attach. +# Start the dev server via devcontainer.json postStartCommand instead. +CMD ["bash", "-lc", "sleep infinity"] diff --git a/package.json b/package.json index 58baf4f7..c9790db2 100644 --- a/package.json +++ b/package.json @@ -38,16 +38,16 @@ }, "dependencies": { "@bcgov/bc-sans": "2.1.0", - "@headlessui/react": "2.2.7", + "@headlessui/react": "2.2.9", "@heroicons/react": "2.2.0", "@prisma/adapter-pg": "7.0.1", "@prisma/client": "7.1.0", "@tailwindcss/postcss": "4.1.11", "dotenv": "17.2.3", - "next": "15.4.5", + "next": "16.1.4", "postcss": "8.5.2", - "react": "19.1.1", - "react-dom": "19.1.1", + "react": "19.2.3", + "react-dom": "19.2.3", "typescript": "5.9.2", "zod": "4.0.14", "zustand": "5.0.7" @@ -63,8 +63,8 @@ "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.5.2", "@types/node": "24.1.0", - "@types/react": "19.1.9", - "@types/react-dom": "19.1.7", + "@types/react": "19.2.9", + "@types/react-dom": "19.2.3", "@types/supertest": "6.0.3", "@vitejs/plugin-react": "4.3.4", "@vitest/coverage-v8": "3.2.4", diff --git a/tsconfig.json b/tsconfig.json index eeacc1d0..fbd46e67 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2023", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -11,7 +15,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ { @@ -19,9 +23,19 @@ } ], "paths": { - "@/*": ["./src/*"], + "@/*": [ + "./src/*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } From 98f960c66e9d2e2080cdf95402e2a6dcef15fcc3 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Thu, 29 Jan 2026 12:04:39 -0800 Subject: [PATCH 08/14] break tests apart, and attach accessibility report to playwright report --- package.json | 1 + playwright/tests/accessibilityTest.spec.ts | 52 ++++++++++++++++++++++ playwright/tests/example.spec.ts | 22 +++------ 3 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 playwright/tests/accessibilityTest.spec.ts diff --git a/package.json b/package.json index c9790db2..95b25cf1 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "@vitejs/plugin-react": "4.3.4", "@vitest/coverage-v8": "3.2.4", "@vitest/ui": "3.2.4", + "axe-html-reporter": "2.2.11", "jsdom": "26.0.0", "license-checker": "25.0.1", "prisma": "7.1.0", diff --git a/playwright/tests/accessibilityTest.spec.ts b/playwright/tests/accessibilityTest.spec.ts new file mode 100644 index 00000000..144e0059 --- /dev/null +++ b/playwright/tests/accessibilityTest.spec.ts @@ -0,0 +1,52 @@ +import { test, expect } from './customAxeBuilder'; +import { createHtmlReport } from 'axe-html-reporter'; +import fs from 'fs'; + +const reportDir = 'playwright/report/accessibility/'; + +// List of URLS to check for accessibility +// may have to work on this to get a way to log in first +const urlsToCheck = [ + { + url: 'http://localhost:3000/', + name: 'Homepage', + }, +]; + +test.describe('Accessibility Testing', () => { + urlsToCheck.forEach(({ url, name }) => { + + test(`should pass accessibility tags: ${url}`, async ({ page, makeAxeBuilder }, testInfo) => { + await page.goto(url); + const reportName = `${name}.html`; + + const accessibilityScanResults = await makeAxeBuilder() + .analyze(); + + const reportHTML = createHtmlReport({ + results: accessibilityScanResults, + options: { + outputDir: reportDir, + reportFileName: reportName, + }, + }); + + const reportPath = `${reportDir}${reportName}` + + // Save HTML report to a file + if (!fs.existsSync(reportPath)) { + fs.mkdirSync(reportPath, { recursive: true }); + } + fs.writeFileSync(reportPath, reportHTML); + + // OPTIONAL: Write report to Playwright HTML report. + // Send test results to reporter to see more info + await testInfo.attach('accessibility-scan-results', { + path: reportPath, + }) + + expect.soft(accessibilityScanResults.violations).toEqual([]); + expect.soft(accessibilityScanResults.incomplete).toEqual([]); + }); + }); +}); diff --git a/playwright/tests/example.spec.ts b/playwright/tests/example.spec.ts index ee4eb283..445e9cee 100644 --- a/playwright/tests/example.spec.ts +++ b/playwright/tests/example.spec.ts @@ -1,25 +1,15 @@ -import { test, expect } from './customAxeBuilder'; +import { test, expect } from '@playwright/test'; + +/** + * Example test that doesn't use the Axe Builder + */ test.describe('homepage', () => { test('has paragraph', async ({ page }) => { await page.goto('http://localhost:3000/'); // Expect a title "to contain" a substring. + // Can test how failing tests are reported by changing 'h1' or 'TEST' here to any other string await expect(page.locator('h1')).toContainText('TEST'); }); - - test('should not have any automatically detectable accessibility issues', async ({ page, makeAxeBuilder }, testInfo) => { - await page.goto('http://localhost:3000/'); - - const accessibilityScanResults = await makeAxeBuilder() - .analyze(); - - // Send test results to reporter to see more info - await testInfo.attach('accessibility-scan-results', { - body: JSON.stringify(accessibilityScanResults, null, 2), - contentType: 'application/json' - }) - - expect(accessibilityScanResults.violations).toEqual([]); - }); }); From 06b5e0facd6917445b3df313e9026c83fe038c88 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Mon, 2 Feb 2026 11:18:13 -0800 Subject: [PATCH 09/14] refine tests so they catch and report colour contrast better --- package.json | 2 +- playwright/tests/accessibilityTest.spec.ts | 34 +++--- playwright/tests/customAxeBuilder.ts | 115 ++++++++++++++++++++- 3 files changed, 135 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 95b25cf1..44df0db3 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test:e2e-headed": "playwright test --headed", "test:e2e-report": "playwright show-report playwright/report", "test:e2e-install": "playwright install-deps && playwright install", - "clean": "rm -rf .next out build dist coverage playwright/test-results playwright/report", + "clean": "rm -rf .next out build dist coverage playwright/test-results playwright/report && playwright clear-cache", "check-licenses": "tsx scripts/check-licenses.ts", "db:push": "prisma db push", "db:migrate": "prisma migrate dev", diff --git a/playwright/tests/accessibilityTest.spec.ts b/playwright/tests/accessibilityTest.spec.ts index 144e0059..2aeced6f 100644 --- a/playwright/tests/accessibilityTest.spec.ts +++ b/playwright/tests/accessibilityTest.spec.ts @@ -1,8 +1,10 @@ -import { test, expect } from './customAxeBuilder'; +import { test, parseResults } from './customAxeBuilder'; +import { expect } from '@playwright/test'; import { createHtmlReport } from 'axe-html-reporter'; import fs from 'fs'; -const reportDir = 'playwright/report/accessibility/'; + +const reportDir = 'playwright/report/accessibility'; // List of URLS to check for accessibility // may have to work on this to get a way to log in first @@ -18,7 +20,6 @@ test.describe('Accessibility Testing', () => { test(`should pass accessibility tags: ${url}`, async ({ page, makeAxeBuilder }, testInfo) => { await page.goto(url); - const reportName = `${name}.html`; const accessibilityScanResults = await makeAxeBuilder() .analyze(); @@ -26,27 +27,32 @@ test.describe('Accessibility Testing', () => { const reportHTML = createHtmlReport({ results: accessibilityScanResults, options: { - outputDir: reportDir, - reportFileName: reportName, + doNotCreateReportFile:true, + // If you want to save the report to a file uncomment below and comment out the above line + // outputDir: reportDir, + // reportFileName: `${name}.html`, }, }); - const reportPath = `${reportDir}${reportName}` + // Uncomment if you want to save HTML report to a file - // Save HTML report to a file - if (!fs.existsSync(reportPath)) { - fs.mkdirSync(reportPath, { recursive: true }); - } - fs.writeFileSync(reportPath, reportHTML); + // const reportPath = `${reportDir}${name}.html`; + // if (!fs.existsSync(reportPath)) { + // fs.mkdirSync(reportPath, { recursive: true }); + // } + // fs.writeFileSync(reportPath, reportHTML); // OPTIONAL: Write report to Playwright HTML report. // Send test results to reporter to see more info await testInfo.attach('accessibility-scan-results', { - path: reportPath, + body: reportHTML, + contentType: 'text/html' }) - expect.soft(accessibilityScanResults.violations).toEqual([]); - expect.soft(accessibilityScanResults.incomplete).toEqual([]); + // Get better error to write to report and console + const accessibilityReport = parseResults(accessibilityScanResults); + + expect.soft(accessibilityReport.violation).toEqual('No accessibility violations found.'); }); }); }); diff --git a/playwright/tests/customAxeBuilder.ts b/playwright/tests/customAxeBuilder.ts index cf4e72b1..2539eb3f 100644 --- a/playwright/tests/customAxeBuilder.ts +++ b/playwright/tests/customAxeBuilder.ts @@ -1,5 +1,6 @@ import { test as base } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; +import { parse } from 'path'; type AxeFixture = { makeAxeBuilder: () => AxeBuilder; @@ -18,4 +19,116 @@ export const test = base.extend({ } }); -export { expect } from '@playwright/test'; +type nodeItem = { + any?: { id: string; data?: { fontSize: string; contrastRatio: number } }[]; +} + +type incompleteItem = { + id: string; + nodes: nodeItem[]; +} + +type AxeResult = { + inapplicable: object[]; + passes: object[]; + violations: object[]; + incomplete: incompleteItem[]; +}; + +/** + * Given a playwright JSON scan result parse and return only useful data. Information for each + * group is from https://docs.deque.com/devtools-for-web/4/en/java-use-results#results-overview + * + */ +export const parseResults = (jsonData: AxeResult) => { + const {inapplicable, passes, violations, incomplete} = jsonData; + + /** + * Passed group - tests which ran and passed successfully. Can update the following to not + * report on information on passed tests. + */ + const passedStr = `${passes.length} accessibility checks passed.`; + + /** + * Incomplete group - tests which ran, but the results require further (manual) review to + * determine what category the results should ultimately fall into. A common test in this group + * is color contrast as there is no way to set what contrast level is acceptable. + */ + let failedColorContrast = []; + + if (incomplete.length > 0) { + // Process each incomplete item to check for failed color-contrast rules + for (const item of incomplete) { + if (item.id === 'color-contrast' && item.nodes) { + // Review each node in the color-contrast rule + for (const node of item.nodes) { + if (node.any && Array.isArray(node.any)) { + for (const check of node.any) { + if (check.id === 'color-contrast' && check.data) { + const { fontSize, contrastRatio } = check.data; + + // Extract pixel size from fontSize (e.g., "12.0pt (16px)" -> 16) + const fontSizeMatch = fontSize.match(/\((\d+)px\)/); + const sizeInPx = fontSizeMatch ? parseInt(fontSizeMatch[1], 10) : null; + + if (sizeInPx !== null && contrastRatio !== null) { + const isNormalText = sizeInPx < 18; + const isLargeText = sizeInPx >= 18; + + // Check if contrast ratio fails for the size category + const failsLargeText = isLargeText && contrastRatio < 3; + const failsNormalText = isNormalText && contrastRatio < 4.5; + + if (failsLargeText || failsNormalText) { + failedColorContrast.push({ + ...node, + contrastData: check.data, + sizeInPx, + failureReason: failsLargeText + ? `Large text (${sizeInPx}px) has contrast ${contrastRatio} < 3:1` + : `Normal text (${sizeInPx}px) has contrast ${contrastRatio} < 4.5:1` + }); + } + } + } + } + } + } + } + } + } + + let incompleteStr = ''; + if (incomplete.length - failedColorContrast.length > 0 ) { + incompleteStr = `${incomplete.length} accessibility checks require further review.`; + } + + /** + * Violation group - all the accessibility violations found in the scan. + */ + let violationStr = ''; + if (violations.length + failedColorContrast.length > 0) { + violationStr = `${violations.length + failedColorContrast.length} accessibility violations found.`; + } else { + violationStr = 'No accessibility violations found.'; + } + + /** + * Inapplicable group - no page content relevant to that particular test, + * such as form related tests on a page with no forms. Only included if there are any. + */ + let inapplicableStr = ``; + if (inapplicable.length > 0) { + inapplicableStr = `${inapplicable.length} tests were applied but not relevant to the page content.`; + } + + + const parsedResults = { + passed: passedStr, + incomplete: incompleteStr, + violation: violationStr, + inapplicable: inapplicableStr + } + + return parsedResults; +} From 5274875f9ad0ff6e9edf855b349d2332bc106bb3 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Mon, 2 Feb 2026 16:09:41 -0800 Subject: [PATCH 10/14] clean up and fix accessibility reporting --- playwright.config.ts | 1 + playwright/tests/accessibilityTest.spec.ts | 41 ++++++----- playwright/tests/customAxeBuilder.ts | 83 ++++------------------ src/app/page.tsx | 8 ++- 4 files changed, 46 insertions(+), 87 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 930fd162..0c2c7ad5 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -23,6 +23,7 @@ export default defineConfig({ /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ + ['line'], ['html', { outputFolder: 'playwright/report'}], ['json', { outputFile: 'playwright/report/results.json' }] ], diff --git a/playwright/tests/accessibilityTest.spec.ts b/playwright/tests/accessibilityTest.spec.ts index 2aeced6f..087844ea 100644 --- a/playwright/tests/accessibilityTest.spec.ts +++ b/playwright/tests/accessibilityTest.spec.ts @@ -1,10 +1,8 @@ import { test, parseResults } from './customAxeBuilder'; import { expect } from '@playwright/test'; import { createHtmlReport } from 'axe-html-reporter'; -import fs from 'fs'; - -const reportDir = 'playwright/report/accessibility'; +const reportDir = 'playwright/report'; // List of URLS to check for accessibility // may have to work on this to get a way to log in first @@ -24,23 +22,34 @@ test.describe('Accessibility Testing', () => { const accessibilityScanResults = await makeAxeBuilder() .analyze(); + // If there are incomplete tests get better error to write to report and console + if (accessibilityScanResults.incomplete.length > 0) { + + const failedColorContrast = parseResults(accessibilityScanResults.incomplete); + console.log(`Found ${failedColorContrast.length} color-contrast issues that need review.`); + + if (failedColorContrast.length != accessibilityScanResults.incomplete.length) { + // if not all the incomplete tests were color-contrast failures, report them as violations + expect.soft(accessibilityScanResults.incomplete.length).toEqual(0); + } else { + // add failed colour contrast tests to violations for reporting + accessibilityScanResults.violations.push(...failedColorContrast); + accessibilityScanResults.incomplete = []; + } + + } + const reportHTML = createHtmlReport({ results: accessibilityScanResults, options: { + // comment out this line if you want to have a report file created locally doNotCreateReportFile:true, - // If you want to save the report to a file uncomment below and comment out the above line - // outputDir: reportDir, - // reportFileName: `${name}.html`, + // uncomment these lines if you want to have a report file created locally + reportFileName: `${name}.html`, + outputDirPath: `./playwright/report/accessibility/` }, }); - - // Uncomment if you want to save HTML report to a file - - // const reportPath = `${reportDir}${name}.html`; - // if (!fs.existsSync(reportPath)) { - // fs.mkdirSync(reportPath, { recursive: true }); - // } - // fs.writeFileSync(reportPath, reportHTML); + console.log(`should save to ${reportDir}/${name}.html`); // OPTIONAL: Write report to Playwright HTML report. // Send test results to reporter to see more info @@ -49,10 +58,8 @@ test.describe('Accessibility Testing', () => { contentType: 'text/html' }) - // Get better error to write to report and console - const accessibilityReport = parseResults(accessibilityScanResults); + expect.soft(accessibilityScanResults.violations.length).toEqual(0); - expect.soft(accessibilityReport.violation).toEqual('No accessibility violations found.'); }); }); }); diff --git a/playwright/tests/customAxeBuilder.ts b/playwright/tests/customAxeBuilder.ts index 2539eb3f..2685c458 100644 --- a/playwright/tests/customAxeBuilder.ts +++ b/playwright/tests/customAxeBuilder.ts @@ -1,6 +1,6 @@ import { test as base } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; -import { parse } from 'path'; +import type {Result} from 'axe-core'; type AxeFixture = { makeAxeBuilder: () => AxeBuilder; @@ -19,35 +19,14 @@ export const test = base.extend({ } }); -type nodeItem = { - any?: { id: string; data?: { fontSize: string; contrastRatio: number } }[]; -} - -type incompleteItem = { - id: string; - nodes: nodeItem[]; -} - -type AxeResult = { - inapplicable: object[]; - passes: object[]; - violations: object[]; - incomplete: incompleteItem[]; -}; /** - * Given a playwright JSON scan result parse and return only useful data. Information for each - * group is from https://docs.deque.com/devtools-for-web/4/en/java-use-results#results-overview + * Given data from Axe-Core testing, parse incomplete object to determine if a violation has occurred or not. + * See detailed information on report groups here: + * https://docs.deque.com/devtools-for-web/4/en/java-use-results#results-overview * */ -export const parseResults = (jsonData: AxeResult) => { - const {inapplicable, passes, violations, incomplete} = jsonData; - - /** - * Passed group - tests which ran and passed successfully. Can update the following to not - * report on information on passed tests. - */ - const passedStr = `${passes.length} accessibility checks passed.`; +export const parseResults = (inapplicableData: Result[]) => { /** * Incomplete group - tests which ran, but the results require further (manual) review to @@ -55,10 +34,11 @@ export const parseResults = (jsonData: AxeResult) => { * is color contrast as there is no way to set what contrast level is acceptable. */ let failedColorContrast = []; + let failedNode = []; - if (incomplete.length > 0) { + if (inapplicableData.length > 0) { // Process each incomplete item to check for failed color-contrast rules - for (const item of incomplete) { + for (const item of inapplicableData) { if (item.id === 'color-contrast' && item.nodes) { // Review each node in the color-contrast rule for (const node of item.nodes) { @@ -80,55 +60,20 @@ export const parseResults = (jsonData: AxeResult) => { const failsNormalText = isNormalText && contrastRatio < 4.5; if (failsLargeText || failsNormalText) { - failedColorContrast.push({ - ...node, - contrastData: check.data, - sizeInPx, - failureReason: failsLargeText - ? `Large text (${sizeInPx}px) has contrast ${contrastRatio} < 3:1` - : `Normal text (${sizeInPx}px) has contrast ${contrastRatio} < 4.5:1` - }); + failedNode.push(node); } } } } } } + if (failedNode.length === item.nodes.length) { + // All nodes failed, add everything to violations. + failedColorContrast.push(item); + } } } } - let incompleteStr = ''; - if (incomplete.length - failedColorContrast.length > 0 ) { - incompleteStr = `${incomplete.length} accessibility checks require further review.`; - } - - /** - * Violation group - all the accessibility violations found in the scan. - */ - let violationStr = ''; - if (violations.length + failedColorContrast.length > 0) { - violationStr = `${violations.length + failedColorContrast.length} accessibility violations found.`; - } else { - violationStr = 'No accessibility violations found.'; - } - - /** - * Inapplicable group - no page content relevant to that particular test, - * such as form related tests on a page with no forms. Only included if there are any. - */ - let inapplicableStr = ``; - if (inapplicable.length > 0) { - inapplicableStr = `${inapplicable.length} tests were applied but not relevant to the page content.`; - } - - - const parsedResults = { - passed: passedStr, - incomplete: incompleteStr, - violation: violationStr, - inapplicable: inapplicableStr - } - - return parsedResults; + return failedColorContrast; } diff --git a/src/app/page.tsx b/src/app/page.tsx index f8c8b341..cc3eae0d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,7 +10,13 @@ export default function Home() { -
This should fail
+

Passing Lines

+
This should pass
+
+ {/*

Failing lines

*/} +
2
+
+
3
) } From 32a6241d720afee15c22d5921533b8e4c68ba26c Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Mon, 2 Feb 2026 16:20:01 -0800 Subject: [PATCH 11/14] tidy up of accessibility test file --- playwright/tests/accessibilityTest.spec.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/playwright/tests/accessibilityTest.spec.ts b/playwright/tests/accessibilityTest.spec.ts index 087844ea..cec06fea 100644 --- a/playwright/tests/accessibilityTest.spec.ts +++ b/playwright/tests/accessibilityTest.spec.ts @@ -2,8 +2,6 @@ import { test, parseResults } from './customAxeBuilder'; import { expect } from '@playwright/test'; import { createHtmlReport } from 'axe-html-reporter'; -const reportDir = 'playwright/report'; - // List of URLS to check for accessibility // may have to work on this to get a way to log in first const urlsToCheck = [ @@ -16,7 +14,7 @@ const urlsToCheck = [ test.describe('Accessibility Testing', () => { urlsToCheck.forEach(({ url, name }) => { - test(`should pass accessibility tags: ${url}`, async ({ page, makeAxeBuilder }, testInfo) => { + test(`should raise no accessibility violations: ${url} ${name}`, async ({ page, makeAxeBuilder }, testInfo) => { await page.goto(url); const accessibilityScanResults = await makeAxeBuilder() @@ -26,7 +24,6 @@ test.describe('Accessibility Testing', () => { if (accessibilityScanResults.incomplete.length > 0) { const failedColorContrast = parseResults(accessibilityScanResults.incomplete); - console.log(`Found ${failedColorContrast.length} color-contrast issues that need review.`); if (failedColorContrast.length != accessibilityScanResults.incomplete.length) { // if not all the incomplete tests were color-contrast failures, report them as violations @@ -45,13 +42,11 @@ test.describe('Accessibility Testing', () => { // comment out this line if you want to have a report file created locally doNotCreateReportFile:true, // uncomment these lines if you want to have a report file created locally - reportFileName: `${name}.html`, - outputDirPath: `./playwright/report/accessibility/` + // reportFileName: `${name}.html`, + // outputDirPath: `./playwright/report/accessibility/` }, }); - console.log(`should save to ${reportDir}/${name}.html`); - // OPTIONAL: Write report to Playwright HTML report. // Send test results to reporter to see more info await testInfo.attach('accessibility-scan-results', { body: reportHTML, From 357a8bce837c66eb581ccec50d49ee25c4c549fe Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Tue, 3 Feb 2026 15:55:06 -0800 Subject: [PATCH 12/14] trying to resolve github build fail --- package.json | 2 +- tsconfig.json | 3 ++- vitest.config.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0ad1d3d1..8f643186 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "test:e2e": "playwright test", "test:e2e-ui": "playwright test --ui", "test:e2e-headed": "playwright test --headed", - "test:e2e-install": "playwright install", + "test:e2e-install": "playwright install-deps && playwright install", "clean": "rm -rf .next out build dist coverage playwright/test-results playwright/report && playwright clear-cache", "check-licenses": "tsx scripts/check-licenses.ts" }, diff --git a/tsconfig.json b/tsconfig.json index fbd46e67..df0e6caa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -36,6 +36,7 @@ ".next/dev/types/**/*.ts" ], "exclude": [ - "node_modules" + "node_modules", + "playwright" ] } diff --git a/vitest.config.ts b/vitest.config.ts index f7f2f02b..5fed134f 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ '.next', 'coverage', 'e2e/**/*', - 'playwright-tests/**/*' + 'playwright/**/*' ], coverage: { provider: 'v8', From dbbc99536e833d7538c4850f6b82ba1e2f480913 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Wed, 4 Feb 2026 08:59:06 -0800 Subject: [PATCH 13/14] allow for multiple incompatible results --- playwright/tests/customAxeBuilder.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/playwright/tests/customAxeBuilder.ts b/playwright/tests/customAxeBuilder.ts index 2685c458..c95d8b01 100644 --- a/playwright/tests/customAxeBuilder.ts +++ b/playwright/tests/customAxeBuilder.ts @@ -34,12 +34,12 @@ export const parseResults = (inapplicableData: Result[]) => { * is color contrast as there is no way to set what contrast level is acceptable. */ let failedColorContrast = []; - let failedNode = []; if (inapplicableData.length > 0) { // Process each incomplete item to check for failed color-contrast rules for (const item of inapplicableData) { if (item.id === 'color-contrast' && item.nodes) { + let failedNode = []; // Review each node in the color-contrast rule for (const node of item.nodes) { if (node.any && Array.isArray(node.any)) { @@ -52,14 +52,7 @@ export const parseResults = (inapplicableData: Result[]) => { const sizeInPx = fontSizeMatch ? parseInt(fontSizeMatch[1], 10) : null; if (sizeInPx !== null && contrastRatio !== null) { - const isNormalText = sizeInPx < 18; - const isLargeText = sizeInPx >= 18; - - // Check if contrast ratio fails for the size category - const failsLargeText = isLargeText && contrastRatio < 3; - const failsNormalText = isNormalText && contrastRatio < 4.5; - - if (failsLargeText || failsNormalText) { + if ((sizeInPx < 18 && contrastRatio < 4.5 ) || (sizeInPx >= 18 && contrastRatio < 3)) { failedNode.push(node); } } From c96edef68e2aad5eb2854abc18e185d2ad6bd9a4 Mon Sep 17 00:00:00 2001 From: Taylor Friesen Date: Thu, 5 Feb 2026 07:52:28 -0800 Subject: [PATCH 14/14] set up branch for demo --- package.json | 1 + playwright.config.ts | 7 ++++--- playwright/tests/accessibilityTest.spec.ts | 6 +++--- playwright/tests/example.spec.ts | 2 +- src/app/page.tsx | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 8f643186..26b10ad6 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "test:e2e": "playwright test", "test:e2e-ui": "playwright test --ui", "test:e2e-headed": "playwright test --headed", + "test:e2e-report": "playwright show-report playwright/report", "test:e2e-install": "playwright install-deps && playwright install", "clean": "rm -rf .next out build dist coverage playwright/test-results playwright/report && playwright clear-cache", "check-licenses": "tsx scripts/check-licenses.ts" diff --git a/playwright.config.ts b/playwright.config.ts index 0c2c7ad5..37ec5bd7 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,8 +4,9 @@ import { defineConfig, devices } from '@playwright/test' * @see https://playwright.dev/docs/test-configuration */ export default defineConfig({ - /* Where to look for test files */ + /* Where to look and the name of file to match for test files */ testDir: './playwright/tests', + testMatch: '*.spec.ts', /* Where to store the test results */ outputDir: './playwright/test-results/', @@ -24,7 +25,7 @@ export default defineConfig({ /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ ['line'], - ['html', { outputFolder: 'playwright/report'}], + ['html', { outputFolder: 'playwright/report', open: 'never'}], ['json', { outputFile: 'playwright/report/results.json' }] ], @@ -82,7 +83,7 @@ export default defineConfig({ ], /* Run your local dev server before starting the tests */ - /* Uncomment if running locally instead of in DevContainer */ + /* Comment out if running with Docker container */ webServer: { command: 'npm run dev', url: 'http://localhost:3000', diff --git a/playwright/tests/accessibilityTest.spec.ts b/playwright/tests/accessibilityTest.spec.ts index cec06fea..da83f758 100644 --- a/playwright/tests/accessibilityTest.spec.ts +++ b/playwright/tests/accessibilityTest.spec.ts @@ -6,7 +6,7 @@ import { createHtmlReport } from 'axe-html-reporter'; // may have to work on this to get a way to log in first const urlsToCheck = [ { - url: 'http://localhost:3000/', + url: '/', name: 'Homepage', }, ]; @@ -42,8 +42,8 @@ test.describe('Accessibility Testing', () => { // comment out this line if you want to have a report file created locally doNotCreateReportFile:true, // uncomment these lines if you want to have a report file created locally - // reportFileName: `${name}.html`, - // outputDirPath: `./playwright/report/accessibility/` + reportFileName: `${name}.html`, + outputDir: `playwright/test-results/accessibility-reports/`, }, }); diff --git a/playwright/tests/example.spec.ts b/playwright/tests/example.spec.ts index 445e9cee..6dd4e8ad 100644 --- a/playwright/tests/example.spec.ts +++ b/playwright/tests/example.spec.ts @@ -6,7 +6,7 @@ import { test, expect } from '@playwright/test'; test.describe('homepage', () => { test('has paragraph', async ({ page }) => { - await page.goto('http://localhost:3000/'); + await page.goto('/'); // Expect a title "to contain" a substring. // Can test how failing tests are reported by changing 'h1' or 'TEST' here to any other string diff --git a/src/app/page.tsx b/src/app/page.tsx index cc3eae0d..334d8c5e 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -13,10 +13,10 @@ export default function Home() {

Passing Lines

This should pass

- {/*

Failing lines

*/} -
2
+ {/*

Failing lines

+
2 - Longer content that may fail accessibility checks

-
3
+
3
*/} ) }