38 lines
1.3 KiB
JavaScript
38 lines
1.3 KiB
JavaScript
import AxeBuilder from "@axe-core/playwright";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
for (const route of ["/", "/sample/resources", "/not-found"]) {
|
|
test(`@a11y ${route} has no critical or serious axe violations`, async ({
|
|
page,
|
|
}) => {
|
|
await page.goto(route);
|
|
await expect(page.getByRole("main")).toBeVisible();
|
|
const results = await new AxeBuilder({ page })
|
|
.withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"])
|
|
.analyze();
|
|
const blocking = results.violations.filter((violation) =>
|
|
["critical", "serious"].includes(violation.impact ?? ""),
|
|
);
|
|
expect(blocking).toEqual([]);
|
|
});
|
|
}
|
|
|
|
test("@a11y keyboard reaches the primary route action with visible focus", async ({
|
|
page,
|
|
}) => {
|
|
await page.goto("/");
|
|
await page.keyboard.press("Tab");
|
|
const action = page.getByRole("link", { name: "샘플 리소스" });
|
|
await expect(action).toBeFocused();
|
|
await expect(action).toHaveCSS("outline-style", "solid");
|
|
});
|
|
|
|
test("@a11y reduced-motion policy disables long animation", async ({ page }) => {
|
|
await page.emulateMedia({ reducedMotion: "reduce" });
|
|
await page.goto("/");
|
|
const duration = await page
|
|
.locator("body")
|
|
.evaluate((body) => getComputedStyle(body).animationDuration);
|
|
expect(["0s", "0.00001s", "1e-05s"]).toContain(duration);
|
|
});
|