64 lines
2.8 KiB
TypeScript
64 lines
2.8 KiB
TypeScript
import AxeBuilder from "@axe-core/playwright";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
for (const path of [
|
|
"/", "/records", "/report", "/rules", "/privacy",
|
|
"/admin", "/admin/moderation", "/admin/external-sources", "/admin/media",
|
|
]) {
|
|
test(`${path} has no serious accessibility violations`, async ({ page }) => {
|
|
await page.goto(path);
|
|
const results = await new AxeBuilder({ page }).withTags(["wcag2a", "wcag2aa", "wcag21aa"]).analyze();
|
|
expect(results.violations.filter(item => ["critical", "serious"].includes(item.impact ?? ""))).toEqual([]);
|
|
});
|
|
}
|
|
|
|
test("admin keyboard navigation keeps focus out of the document body", async ({ page }) => {
|
|
await page.goto("/admin");
|
|
await page.keyboard.press("Tab");
|
|
await expect(page.locator(".skip-link")).toBeFocused();
|
|
|
|
const focusedLabels: string[] = [];
|
|
for (let index = 0; index < 20; index += 1) {
|
|
await page.keyboard.press("Tab");
|
|
focusedLabels.push(await page.evaluate(() => {
|
|
const active = document.activeElement;
|
|
if (active?.tagName === "BODY") return "BODY";
|
|
if (active?.matches(".admin-login input")) return "ADMIN_TOKEN_INPUT";
|
|
if (active?.matches(".admin-login button")) return "ADMIN_PANEL_BUTTON";
|
|
return (active?.getAttribute("aria-label") || active?.textContent || active?.tagName || "").trim().slice(0, 80);
|
|
}));
|
|
}
|
|
|
|
expect(focusedLabels).not.toContain("BODY");
|
|
expect(focusedLabels).toContain("ADMIN_TOKEN_INPUT");
|
|
expect(focusedLabels).toContain("ADMIN_PANEL_BUTTON");
|
|
});
|
|
|
|
test("print media keeps a light color scheme and removes hero image filters", async ({ page }) => {
|
|
await page.emulateMedia({ media: "print" });
|
|
await page.goto("/");
|
|
const printState = await page.evaluate(() => ({
|
|
colorScheme: getComputedStyle(document.documentElement).colorScheme,
|
|
heroFilter: document.querySelector(".lake-card img") ? getComputedStyle(document.querySelector(".lake-card img")!).filter : "none",
|
|
}));
|
|
expect(printState.colorScheme).toBe("light");
|
|
expect(printState.heroFilter).toBe("none");
|
|
});
|
|
|
|
test("forced colors keeps theme controls visibly bordered", async ({ page }) => {
|
|
await page.emulateMedia({ forcedColors: "active" });
|
|
await page.goto("/admin");
|
|
const forcedColorsState = await page.evaluate(() => {
|
|
const control = document.querySelector(".theme-switcher button");
|
|
const pressed = document.querySelector(".theme-switcher button[aria-pressed='true']");
|
|
return {
|
|
borderStyle: control ? getComputedStyle(control).borderStyle : "",
|
|
borderWidth: control ? getComputedStyle(control).borderWidth : "",
|
|
activeBackground: pressed ? getComputedStyle(pressed).backgroundColor : "",
|
|
};
|
|
});
|
|
expect(forcedColorsState.borderStyle).toBe("solid");
|
|
expect(forcedColorsState.borderWidth).toBe("1px");
|
|
expect(forcedColorsState.activeBackground).not.toBe("transparent");
|
|
});
|