Files
nexarch/scripts/token-mode-a11y.js
patrickandClaude Sonnet 5 28aaad65ed
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
UX-14: a11y-fixture um Mail-/E-Rechnung-Daten erweitert, Token-Modus-a11y-Lauf in gesamt-token-smoke.sh
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 23:52:45 +02:00

48 lines
2.4 KiB
JavaScript

// UX-10/UX-11: axe-Lauf im echten Token-Modus gegen dms-browser + dms-app,
// mit einem echten Sitzungscookie vom Kontodienst (kein Fixture-Mock).
// node token-mode-a11y.js <base> <cookieName> <cookieValue>
const fs = require("fs");
const path = require("path");
const nm = process.env.A11Y_NODE_MODULES || "/usr/local/lib/node_modules/pa11y/node_modules";
const puppeteer = require(path.join(nm, "puppeteer-core"));
const axeSource = fs.readFileSync(path.join(nm, "axe-core", "axe.min.js"), "utf8");
const [, , base, cookieName, cookieValue] = process.argv;
if (!base || !cookieName || !cookieValue) {
console.error("usage: token-mode-a11y.js <base> <cookieName> <cookieValue>");
process.exit(2);
}
const host = new URL(base).hostname;
const pages = ["/browse", "/trash", "/mail-accounts", "/mail-rules", "/clarification"];
(async () => {
const browser = await puppeteer.launch({ executablePath: process.env.A11Y_CHROME, args: ["--no-sandbox", "--disable-setuid-sandbox"] });
let failed = false;
for (const p of pages) {
const page = await browser.newPage();
await page.setCookie({ name: cookieName, value: cookieValue, domain: host, path: "/", httpOnly: true });
let entry = { url: base + p };
try {
await page.goto(base + p, { waitUntil: "networkidle0", timeout: 30000 });
await new Promise((r) => setTimeout(r, 500));
const loginRedirect = await page.evaluate(() => document.body.innerText.includes("anmelden") || document.body.innerText.includes("Anmeldung"));
await page.evaluate(axeSource);
const axe = await page.evaluate(() =>
axe.run(document, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"] } }).then((r) => ({
violations: r.violations.map((v) => ({ id: v.id, impact: v.impact, nodes: v.nodes.length })),
}))
);
entry.axe = axe;
entry.loginRedirect = loginRedirect;
} catch (e) {
entry.error = String(e.message || e);
}
await page.close();
const serious = entry.axe && entry.axe.violations.some((x) => x.impact === "critical" || x.impact === "serious");
if (entry.error || serious) failed = true;
console.log(`${entry.error ? "FEHLER " + entry.error : "ok"}\t${entry.url}\taxe: ${entry.axe ? entry.axe.violations.map((v) => `${v.id}(${v.impact},${v.nodes})`).join(", ") || "keine" : "-"}\tanmeldeseite: ${entry.loginRedirect}`);
}
await browser.close();
process.exit(failed ? 1 : 0);
})();