test(#147): add axe-core accessibility spec with color-contrast enabled
Introduces the wcag2a/wcag2aa E2E suite from the test-suite branch with the color-contrast rule active — no disableRules exclusion. Also adds /coverage/ to .prettierignore so generated lcov reports don't fail the lint hook. This commit intentionally fails the axe suite until the contrast fixes land in the next commits. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,3 +16,4 @@ bun.lockb
|
||||
# Test artifacts
|
||||
/test-results/
|
||||
/e2e/.auth/
|
||||
/coverage/
|
||||
|
||||
58
frontend/e2e/accessibility.spec.ts
Normal file
58
frontend/e2e/accessibility.spec.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Automated accessibility checks using axe-core (wcag2a + wcag2aa).
|
||||
* Authenticated pages use the stored admin session from playwright.config.ts.
|
||||
* The login page test overrides to an unauthenticated context.
|
||||
*/
|
||||
|
||||
const AUTHENTICATED_PAGES = [
|
||||
{ name: 'home', path: '/' },
|
||||
{ name: 'persons', path: '/persons' },
|
||||
{ name: 'admin', path: '/admin' }
|
||||
];
|
||||
|
||||
function buildAxe(page: Parameters<typeof AxeBuilder>[0]['page']) {
|
||||
return new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']);
|
||||
}
|
||||
|
||||
test.describe('Accessibility — authenticated pages', () => {
|
||||
for (const { name, path } of AUTHENTICATED_PAGES) {
|
||||
test(`${name} page has no critical wcag2a/wcag2aa violations`, async ({ page }) => {
|
||||
await page.goto(path);
|
||||
await page.waitForSelector('[data-hydrated]');
|
||||
|
||||
const results = await buildAxe(page).analyze();
|
||||
|
||||
if (results.violations.length > 0) {
|
||||
const summary = results.violations
|
||||
.map((v) => `[${v.impact}] ${v.id}: ${v.description} (${v.nodes.length} node(s))`)
|
||||
.join('\n');
|
||||
console.log(`\nAccessibility violations on ${name}:\n${summary}`);
|
||||
}
|
||||
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test.describe('Accessibility — login page', () => {
|
||||
test.use({ storageState: { cookies: [], origins: [] } });
|
||||
|
||||
test('login page has no critical wcag2a/wcag2aa violations', async ({ page }) => {
|
||||
await page.goto('/login');
|
||||
await expect(page.getByLabel('Benutzername')).toBeVisible();
|
||||
|
||||
const results = await buildAxe(page).analyze();
|
||||
|
||||
if (results.violations.length > 0) {
|
||||
const summary = results.violations
|
||||
.map((v) => `[${v.impact}] ${v.id}: ${v.description} (${v.nodes.length} node(s))`)
|
||||
.join('\n');
|
||||
console.log(`\nAccessibility violations on login:\n${summary}`);
|
||||
}
|
||||
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user