Assertions now follow the eighteen prerenderable paths, the gist dialog, and the six-case evidence set. Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import AxeBuilder from '@axe-core/playwright';
|
|
import { expect, test } from '@playwright/test';
|
|
import { pagePath } from './helpers';
|
|
|
|
const AXE_PATHS = [
|
|
pagePath('home', 'de'),
|
|
pagePath('home', 'en'),
|
|
pagePath('pitch', 'de'),
|
|
pagePath('pitch', 'en'),
|
|
pagePath('projects', 'de'),
|
|
pagePath('projects', 'en'),
|
|
pagePath('services', 'de'),
|
|
pagePath('services', 'en'),
|
|
pagePath('contact', 'de'),
|
|
pagePath('contact', 'en'),
|
|
pagePath('imprint', 'de'),
|
|
pagePath('imprint', 'en'),
|
|
'/missing-route',
|
|
'/en/missing-route',
|
|
];
|
|
|
|
test.describe('accessibility', () => {
|
|
test('revealed content stays visible under reduced motion', async ({ page }) => {
|
|
await page.emulateMedia({ reducedMotion: 'reduce' });
|
|
await page.goto(pagePath('home', 'de'));
|
|
const pending = page.locator('.reveal-pending');
|
|
await expect(pending).toHaveCount(0);
|
|
await expect(page.locator('app-case-card').first()).toBeVisible();
|
|
|
|
await page.goto(pagePath('services', 'de'));
|
|
await expect(page.locator('.reveal-pending')).toHaveCount(0);
|
|
await expect(page.locator('app-systems-map')).toBeVisible();
|
|
});
|
|
|
|
for (const path of AXE_PATHS) {
|
|
test(`axe has no serious or critical violations on ${path}`, async ({ page }) => {
|
|
await page.goto(path);
|
|
const results = await new AxeBuilder({ page }).analyze();
|
|
const blocking = results.violations.filter(
|
|
(violation) => violation.impact === 'serious' || violation.impact === 'critical',
|
|
);
|
|
|
|
const details = blocking
|
|
.map((violation) => {
|
|
const nodes = violation.nodes.map((node) => node.target.join(' ')).join(', ');
|
|
return `${violation.id} (${violation.impact}): ${nodes}`;
|
|
})
|
|
.join('\n');
|
|
|
|
expect(blocking, details).toEqual([]);
|
|
});
|
|
}
|
|
});
|