import AxeBuilder from "@axe-core/playwright"; import { expect, test } from "../support/browser/strict-browser-test.ts"; import { gotoTechLog, TECH_LOG_CANONICAL_ROUTES, } from "../support/browser/tech-log-fixtures.ts"; for (const route of TECH_LOG_CANONICAL_ROUTES.filter( ({ routeId }) => routeId !== "NOT_FOUND", )) { test(`@a11y ${route.routeId} has no critical or serious Axe violations`, async ({ page, }) => { await gotoTechLog(page, route.path); const results = await new AxeBuilder({ page }) .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"]) .analyze(); expect( results.violations.filter((violation) => ["critical", "serious"].includes(violation.impact ?? ""), ), ).toEqual([]); }); } test("@a11y NOT_FOUND preserves the source raw non-HTML response", async ({ request, }) => { const response = await request.get("/definitely-not-a-product-route"); expect(response.status()).toBe(404); expect(response.headers()["content-type"]).toBe("text/plain;charset=UTF-8"); expect(await response.text()).toBe("Not Found"); }); test("@a11y keyboard reaches a visible Public navigation focus indicator", async ({ page, }) => { await gotoTechLog(page, "/"); const action = page.getByRole("link", { name: "TechLog 홈" }); await action.focus(); await expect(action).toBeFocused(); await expect(action).toHaveCSS("outline-style", "solid"); }); test("@a11y reduced-motion preference leaves no running document animations", async ({ page, }) => { await gotoTechLog(page, "/"); expect(await page.evaluate(() => document.getAnimations().length)).toBe(0); });