You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
2.0 KiB
TypeScript
50 lines
2.0 KiB
TypeScript
// frontend/playwright/a11y.spec.ts — 3페이지 접근성 감사(라이트/다크) + 키보드
|
|
// color-contrast 제외(레퍼런스 액센트 팔레트가 디자인 정본) — 구조/시맨틱 WCAG 는 엄격.
|
|
import AxeBuilder from "@axe-core/playwright";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
const AXE = (page: import("@playwright/test").Page) =>
|
|
new AxeBuilder({ page }).withTags(["wcag2a", "wcag2aa", "wcag21aa"]).disableRules(["color-contrast"]);
|
|
|
|
const PAGES: [string, string][] = [
|
|
["/dashboard", "아리 브리핑"],
|
|
["/inbox", "스마트 인박스"],
|
|
["/tasks", "리스크 레이더"],
|
|
["/approvals", "아리 결재함"],
|
|
["/automation", "내 규칙"],
|
|
["/calendar", "내 캘린더"],
|
|
["/mail", "받은편지함"],
|
|
["/notifications", "트리아지"],
|
|
["/research", "새 조사"],
|
|
["/trip", "다가오는 출장"],
|
|
["/life", "연결된 데이터"],
|
|
["/journey", "오늘의 여정"],
|
|
];
|
|
|
|
for (const [path, marker] of PAGES) {
|
|
test(`a11y(axe): ${path} — 위반 0건`, async ({ page }) => {
|
|
await page.goto(path);
|
|
await page.getByText(marker).first().waitFor();
|
|
const r = await AXE(page).analyze();
|
|
expect(r.violations, JSON.stringify(r.violations, null, 2)).toEqual([]);
|
|
});
|
|
}
|
|
|
|
test("다크 테마 대시보드 — 위반 0건 + 테마 영속", async ({ page }) => {
|
|
await page.goto("/dashboard");
|
|
await page.getByText("아리 브리핑").waitFor();
|
|
await page.getByLabel("테마 전환").click();
|
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "dark");
|
|
const r = await AXE(page).analyze();
|
|
expect(r.violations).toEqual([]);
|
|
await page.reload();
|
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "dark"); // localStorage 영속
|
|
});
|
|
|
|
test("키보드 내비: Tab 으로 포커스 이동 가능", async ({ page }) => {
|
|
await page.goto("/dashboard");
|
|
await page.keyboard.press("Tab");
|
|
const focused = await page.evaluate(() => document.activeElement?.tagName);
|
|
expect(focused).toBeTruthy();
|
|
});
|