diff --git a/package-lock.json b/package-lock.json index d7b22ab..b334966 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,9 +6,23 @@ "": { "name": "intotheeast-tests", "devDependencies": { + "@axe-core/playwright": "^4.11.3", "@playwright/test": "^1.48.0" } }, + "node_modules/@axe-core/playwright": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.3.tgz", + "integrity": "sha512-h/kfksv4F0cVIDlKpT4700OehdRgpvuVskuQ2nb7/JmtWUXpe9ftHAPtwyXGvVSsa6SJ64A9ER7Zrzc/sIvC4w==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "axe-core": "~4.11.4" + }, + "peerDependencies": { + "playwright-core": ">= 1.0.0" + } + }, "node_modules/@playwright/test": { "version": "1.61.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.0.tgz", @@ -25,6 +39,16 @@ "node": ">=18" } }, + "node_modules/axe-core": { + "version": "4.11.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.4.tgz", + "integrity": "sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", diff --git a/package.json b/package.json index 1a9a6be..1210e8e 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "test:ui": "playwright test" }, "devDependencies": { + "@axe-core/playwright": "^4.11.3", "@playwright/test": "^1.48.0" } } diff --git a/tests/ui/accessibility.spec.js b/tests/ui/accessibility.spec.js index 4a7422c..e7314a4 100644 --- a/tests/ui/accessibility.spec.js +++ b/tests/ui/accessibility.spec.js @@ -95,3 +95,30 @@ test('A5: GPX delete buttons have unique aria-labels per filename', async ({ pag await expect(deleteBtn).toBeVisible(); await expect(deleteBtn).toHaveAttribute('aria-label', 'Delete tokyo-day1.gpx'); }); + +// ── AX1–AX5: axe-core WCAG 2.1 AA regression scans ─────────────────────────── +const { AxeBuilder } = require('@axe-core/playwright'); + +const WCAG_TAGS = ['wcag2a', 'wcag2aa']; +const BLOCKING = ['critical', 'serious']; + +function axeScan(id, url) { + test(`${id}: ${url} passes axe WCAG 2.1 AA (critical/serious)`, async ({ page }) => { + await page.goto(url); + const results = await new AxeBuilder({ page }).withTags(WCAG_TAGS).analyze(); + const violations = results.violations.filter(v => BLOCKING.includes(v.impact)); + expect( + violations, + violations.map(v => + `[${v.impact}] ${v.id}: ${v.description}\n ` + + v.nodes.map(n => n.html).join('\n ') + ).join('\n\n') + ).toHaveLength(0); + }); +} + +axeScan('AX1', '/'); +axeScan('AX2', '/trips/japan-korea-2026'); +axeScan('AX3', '/trips/japan-korea-2026/dailies'); +axeScan('AX4', '/trips/japan-korea-2026/dailies/2026-06-17.entry'); +axeScan('AX5', '/trips'); diff --git a/user b/user index a2cdbd7..c403ea9 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit a2cdbd7506ab0fac9ee1119becc4e09d3eaf9e19 +Subproject commit c403ea9593939c660d2046a920575a67d94e3531