// Automated a11y scan (axe-core, WCAG 2.2 AA rules) of the main views. Run against `pnpm preview`. import { readFile } from 'node:fs/promises'; import { chromium } from 'playwright-core'; const axeSrc = await readFile('node_modules/axe-core/axe.min.js', 'utf8'); const URL = process.env.URL ?? 'http://localhost:4173/'; const browser = await chromium.launch(); // VIEWPORT=390x844 runs the same scan with a phone-sized (touch) viewport const [vw, vh] = (process.env.VIEWPORT ?? '1280x900').split('x').map(Number); const page = await browser.newPage({ viewport: { width: vw, height: vh }, isMobile: vw < 700, hasTouch: vw < 700, locale: 'pl-PL' }); let bad = 0; async function scan(name) { await page.addScriptTag({ content: axeSrc }); const r = await page.evaluate(() => axe.run(document, { runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa', 'best-practice'] } })); console.log(`${name}: ${r.violations.length} violation(s)`); for (const v of r.violations) { bad++; console.log(` [${v.impact}] ${v.id}: ${v.help} — ${v.nodes.length} node(s), e.g. ${v.nodes[0].target.join(' ')}`); } } await page.goto(URL, { waitUntil: 'networkidle' }); await scan('login'); await page.click('text=Zaloguj jako Maria Wiśniewska'); await page.waitForSelector('[role=tablist]'); for (const [tab, name] of [['Zgłoszenia', 'dashboard: reports'], ['Przejścia', 'dashboard: crossings'], ['Jakość', 'dashboard: quality'], ['Eksport', 'dashboard: export']]) { await page.click(`[role=tab]:has-text("${tab}")`); await scan(name); } await page.click('nav >> text=Miejsca'); await page.waitForSelector('#q'); await scan('places'); await page.fill('#q', 'Sukiennice'); await page.click('button[id^=place-]'); await page.waitForSelector('text=Szczegóły dostępności'); await scan('place detail'); await page.click('nav >> text=Trasa'); await page.click('text=Sukiennice → Zamek Królewski na Wawelu'); await page.waitForSelector('text=Opis trasy tekstem'); await scan('route'); await page.click('nav >> text=Profil'); await page.waitForSelector('#st1'); await scan('profile + settings'); await page.click('nav >> text=Dane'); await scan('about'); await browser.close(); process.exitCode = bad ? 1 : 0;