Skip to content

Commit d86a12b

Browse files
committed
test: add playwright axe accessibility baseline
1 parent 1590ba6 commit d86a12b

6 files changed

Lines changed: 110 additions & 21 deletions

File tree

docs/ACCESSIBILITY_TRACKER.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ Accessibility work is tracked in `/docs/plan/M07-ux-accessibility-and-design-sys
1313
- Manual keyboard/screen reader checks for core flows.
1414
- Automated checks in CI where available.
1515

16+
## Latest automated baseline (2026-02-11)
17+
18+
- Command: `npm run test:a11y`
19+
- Coverage routes:
20+
- `/`
21+
- `/dockets`
22+
- `/comments/search`
23+
- `/contact`
24+
- `/agency/login`
25+
- Result: no Axe `critical` violations detected on covered routes.
26+
1627
## Verification Checklist (WCAG 2.1 AA)
1728

1829
- Public docket browse/search:

docs/plan/M07-ux-accessibility-and-design-system.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ Consolidate UX architecture and enforce accessible, coherent UI patterns.
3939
- 2026-02-11: Added baseline design tokens and surface styling in `src/index.css` and applied to shared layouts (`PublicLayout`, `AdminLayout`, root app shell).
4040
- 2026-02-11: Expanded `docs/ACCESSIBILITY_TRACKER.md` with a concrete WCAG 2.1 AA verification checklist for primary public and agency workflows.
4141
- 2026-02-11: Removed unused legacy pages (`src/pages/AgencyDashboard.tsx`, `src/pages/AgencyLogin.tsx`) that contained stale placeholder/duplicate agency UI, leaving canonical `/pages/agency/*` surfaces as the single implementation path.
42+
- 2026-02-11: Added Playwright + Axe automated accessibility baseline (`tests/playwright/accessibility.pw.ts`) and verified no `critical` violations on primary entry routes; recorded in `docs/ACCESSIBILITY_TRACKER.md`.

package-lock.json

Lines changed: 47 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
"preview": "vite preview",
1212
"db:migrate": "npx supabase db push",
1313
"db:custom-migrate": "node apply-migrations.js",
14-
"test": "vitest",
15-
"test:ci": "vitest --run --passWithNoTests",
16-
"test:watch": "vitest --watch",
17-
"test:coverage": "vitest --coverage",
14+
"test": "vitest --exclude tests/playwright/**",
15+
"test:ci": "vitest --run --passWithNoTests --exclude tests/playwright/**",
16+
"test:watch": "vitest --watch --exclude tests/playwright/**",
17+
"test:coverage": "vitest --coverage --exclude tests/playwright/**",
1818
"test:a11y": "npx playwright test tests/playwright/accessibility.spec.ts",
1919
"cypress:open": "cypress open",
2020
"cypress:run": "cypress run",
@@ -33,6 +33,7 @@
3333
"devDependencies": {
3434
"@axe-core/playwright": "^4.10.2",
3535
"@eslint/js": "^9.9.1",
36+
"@playwright/test": "^1.58.2",
3637
"@testing-library/jest-dom": "^6.6.4",
3738
"@testing-library/react": "^16.3.0",
3839
"@testing-library/user-event": "^14.6.1",

playwright.config.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { defineConfig } from '@playwright/test'
2+
3+
export default defineConfig({
4+
testDir: 'tests/playwright',
5+
timeout: 60_000,
6+
fullyParallel: false,
7+
retries: 0,
8+
use: {
9+
baseURL: 'http://127.0.0.1:4173',
10+
headless: true,
11+
trace: 'on-first-retry'
12+
},
13+
webServer: {
14+
command: 'npm run dev -- --host 127.0.0.1 --port 4173',
15+
url: 'http://127.0.0.1:4173',
16+
reuseExistingServer: true,
17+
timeout: 120_000
18+
}
19+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { test, expect } from '@playwright/test'
2+
import AxeBuilder from '@axe-core/playwright'
3+
4+
const routesToCheck = [
5+
'/',
6+
'/dockets',
7+
'/comments/search',
8+
'/contact',
9+
'/agency/login'
10+
]
11+
12+
for (const route of routesToCheck) {
13+
test(`axe baseline has no critical accessibility violations on ${route}`, async ({ page }) => {
14+
await page.goto(route)
15+
await page.waitForLoadState('networkidle')
16+
17+
const results = await new AxeBuilder({ page }).analyze()
18+
const criticalViolations = results.violations.filter((violation) => violation.impact === 'critical')
19+
20+
expect(
21+
criticalViolations,
22+
criticalViolations
23+
.map((violation) => `${violation.id}: ${violation.help} (${violation.nodes.length} nodes)`)
24+
.join('\n')
25+
).toEqual([])
26+
})
27+
}

0 commit comments

Comments
 (0)