65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import AxeBuilder from "@axe-core/playwright";
|
|
import { expect, test } from "@playwright/test";
|
|
import { newIsolatedContext } from "./helpers";
|
|
|
|
async function expectAccessible(page: import("@playwright/test").Page): Promise<void> {
|
|
const results = await new AxeBuilder({ page }).analyze();
|
|
|
|
expect(
|
|
results.violations,
|
|
results.violations
|
|
.map(
|
|
(violation) =>
|
|
`${violation.id}: ${violation.help}\n${violation.nodes
|
|
.map((node) => ` ${node.target.join(" ")}: ${node.failureSummary}`)
|
|
.join("\n")}`,
|
|
)
|
|
.join("\n\n"),
|
|
).toEqual([]);
|
|
}
|
|
|
|
test("public pages are accessible by keyboard in light and dark themes", async ({ browser }) => {
|
|
const context = await newIsolatedContext(browser);
|
|
const page = await context.newPage();
|
|
|
|
await page.goto("/");
|
|
await page.keyboard.press("Tab");
|
|
await expect(page.getByRole("link", { name: "Skip to main content" })).toBeFocused();
|
|
await page.keyboard.press("Enter");
|
|
await expect(page.locator("#main-content")).toBeFocused();
|
|
|
|
for (const theme of ["light", "dark"] as const) {
|
|
await page.getByRole("button", { name: `Use ${theme} theme` }).click();
|
|
await expect(page.locator("html")).toHaveAttribute("data-theme", theme);
|
|
|
|
for (const path of ["/", "/safety", "/users/log-in", "/users/register"]) {
|
|
await page.goto(path);
|
|
await expectAccessible(page);
|
|
}
|
|
}
|
|
|
|
await context.close();
|
|
});
|
|
|
|
test("public navigation does not overflow narrow or wide viewports", async ({ browser }) => {
|
|
for (const viewport of [
|
|
{ width: 360, height: 800 },
|
|
{ width: 768, height: 1024 },
|
|
{ width: 1440, height: 900 },
|
|
]) {
|
|
const context = await newIsolatedContext(browser);
|
|
const page = await context.newPage();
|
|
await page.setViewportSize(viewport);
|
|
await page.goto("/");
|
|
|
|
const dimensions = await page.evaluate(() => ({
|
|
clientWidth: document.documentElement.clientWidth,
|
|
scrollWidth: document.documentElement.scrollWidth,
|
|
}));
|
|
|
|
expect(dimensions.scrollWidth).toBeLessThanOrEqual(dimensions.clientWidth);
|
|
await expect(page.getByRole("navigation", { name: "Primary navigation" })).toBeVisible();
|
|
await context.close();
|
|
}
|
|
});
|