Lifts the three-API-call seeding (create sender, create receiver, create document) out of briefwechsel-a11y.spec.ts and into a dedicated fixtures module. The spec now calls seedBilateralPair() in beforeAll and cleanupBilateralPair() in afterAll so the test DB doesn't accrue seeded rows across reruns. Two caveats captured in the helper docstring: the backend has no person-delete endpoint (only the document is purged), and the timestamped last names make leftover persons collision-free. Refs #305 Fixes @saraholt follow-up 1 + 2 from PR round-2 review Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import AxeBuilder from '@axe-core/playwright';
|
|
import { test, expect } from '@playwright/test';
|
|
import {
|
|
seedBilateralPair,
|
|
cleanupBilateralPair,
|
|
type BilateralPair
|
|
} from './fixtures/bilateral-correspondence';
|
|
|
|
// Accessibility coverage for the briefwechsel thumbnail-row layout. Seeds
|
|
// two persons + a bilateral document via the shared fixture so the page
|
|
// reaches the results state (not the hero), then runs axe-core
|
|
// (wcag2a + wcag2aa) across three viewports and two color schemes.
|
|
|
|
const VIEWPORTS = [
|
|
{ name: 'mobile', width: 375, height: 812 },
|
|
{ name: 'tablet', width: 768, height: 1024 },
|
|
{ name: 'desktop', width: 1280, height: 800 }
|
|
] as const;
|
|
|
|
const THEMES = ['light', 'dark'] as const;
|
|
|
|
let pair: BilateralPair;
|
|
|
|
test.describe('Accessibility — /briefwechsel row layout', () => {
|
|
test.beforeAll(async ({ request }) => {
|
|
pair = await seedBilateralPair(request, 'A11y');
|
|
});
|
|
|
|
test.afterAll(async ({ request }) => {
|
|
await cleanupBilateralPair(request, pair);
|
|
});
|
|
|
|
for (const vp of VIEWPORTS) {
|
|
for (const theme of THEMES) {
|
|
test(`${vp.name} / ${theme} has no wcag2a/wcag2aa violations`, async ({ page }) => {
|
|
await page.setViewportSize({ width: vp.width, height: vp.height });
|
|
await page.emulateMedia({ colorScheme: theme });
|
|
await page.goto(
|
|
`/briefwechsel?senderId=${encodeURIComponent(pair.senderId)}&receiverId=${encodeURIComponent(pair.receiverId)}`
|
|
);
|
|
await page.waitForSelector('[data-hydrated]');
|
|
|
|
// Assert we actually reached the row layout, not the hero — otherwise
|
|
// the axe sweep silently scans the wrong DOM.
|
|
await expect(page.getByTestId('conv-person-bar')).toBeVisible();
|
|
|
|
const results = await new AxeBuilder({ page })
|
|
.withTags(['wcag2a', 'wcag2aa'])
|
|
.include('main')
|
|
.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 briefwechsel (${vp.name}/${theme}):\n${summary}`
|
|
);
|
|
}
|
|
|
|
expect(results.violations).toEqual([]);
|
|
});
|
|
}
|
|
}
|
|
});
|