import AxeBuilder from '@axe-core/playwright'; import { expect, test, type Page } from '@playwright/test'; import { contextForUser } from './helpers'; /** * A11y-Smoke-Pack (issue #171): axe-core-Scan der Kern-Oberflächen gegen * WCAG 2.1 A/AA. Regressionsschutz für das Audit vom 21.07.2026 (Bericht im * Workspace, Befunde A11Y-001…024) — die Screens hier waren nach den Fixes * der Issues #162–#170 verletzungsfrei; jede neue Verletzung bricht den * Build. Best-Practice-Regeln (axe-Tag best-practice) prüfen wir hier * bewusst NICHT, nur normative WCAG-Kriterien. */ const BASE = process.env.E2E_BASE_URL ?? 'http://localhost:5173'; const TAGS = ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa']; /** Bewusst tolerierte Regel-IDs — nur mit Begründung ergänzen. */ const ALLOWED_RULES: string[] = []; async function expectClean(page: Page, label: string): Promise { const results = await new AxeBuilder({ page }).withTags(TAGS).analyze(); const violations = results.violations.filter((v) => !ALLOWED_RULES.includes(v.id)); expect( violations.map((v) => ({ rule: v.id, impact: v.impact, help: v.help, nodes: v.nodes.slice(0, 5).map((n) => n.target), })), `axe-Verletzungen auf ${label}`, ).toEqual([]); } test('login page passes the axe WCAG A/AA scan', async ({ page }) => { await page.goto('/login'); await page.waitForLoadState('networkidle'); await expectClean(page, '/login'); }); test('reading and editing a page passes the axe WCAG A/AA scan', async ({ browser }) => { const context = await contextForUser(browser, BASE, 'fixture-user'); const page = await context.newPage(); await page.goto('/p/content-fixtures/every-element'); await page.waitForLoadState('networkidle'); await expectClean(page, 'Lesemodus every-element'); await page.locator('.editor-page__mode-toggle').click(); await page.locator('.ProseMirror[contenteditable="true"]').waitFor({ timeout: 10_000 }); await page.waitForTimeout(500); await expectClean(page, 'Editor every-element'); await context.close(); }); test('user settings pass the axe WCAG A/AA scan', async ({ browser }) => { const context = await contextForUser(browser, BASE, 'fixture-user'); const page = await context.newPage(); await page.goto('/settings'); await page.waitForLoadState('networkidle'); await expectClean(page, '/settings'); await context.close(); });