37 lines
1.8 KiB
JavaScript
37 lines
1.8 KiB
JavaScript
// 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();
|
|
const page = await browser.newPage({ viewport: { width: 1280, height: 900 }, 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('.kbb-kpis');
|
|
await scan('dashboard');
|
|
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;
|