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
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
48 lines
2.4 KiB
JavaScript
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);
|
|
})();
|