import AxeBuilder from "@axe-core/playwright"; import { expect, test } from "@playwright/test"; const pages = [ ["repository-list", "/"], ["home", "/alpha/home"], ["timeline", "/alpha/timeline"], ["tree", "/alpha/tree?ci=tip"], ["org-document", "/alpha/doc/tip/docs/org-support.org"], ["org-wiki", "/alpha/wiki?name=Org%20Wiki"], ["login", "/alpha/login"], ]; for (const colorScheme of ["light", "dark"]) { for (const [name, path] of pages) { test(`${name} is legible in ${colorScheme} mode`, async ({ page }) => { await page.emulateMedia({ colorScheme }); await page.goto(path); await expect(page.locator("body")).toContainText("Copland"); const viewportOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(viewportOverflow).toBe(false); let accessibilityScan = new AxeBuilder({ page }) .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"]) .disableRules(["html-has-lang"]) .exclude(".submenu"); if (name === "login") { accessibilityScan = accessibilityScan.exclude("form"); } const accessibility = await accessibilityScan.analyze(); expect(accessibility.violations).toEqual([]); const screenshotMasks = [page.locator(".site-footer span:last-child")]; if (name === "login") { screenshotMasks.push(page.locator("form")); } await expect(page).toHaveScreenshot(`${name}-${colorScheme}.png`, { fullPage: true, animations: "disabled", mask: screenshotMasks, maxDiffPixelRatio: 0.001, }); }); } } test.describe("mobile", () => { test.use({ viewport: { width: 320, height: 720 } }); test("navigation remains usable", async ({ page }) => { await page.goto("/alpha/timeline"); await expect(page.locator(".site-brand")).toHaveText("Copland"); await expect(page.locator(".mainmenu")).toBeVisible(); const viewportOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(viewportOverflow).toBe(false); await expect(page).toHaveScreenshot("timeline-mobile.png", { fullPage: true, mask: [page.locator(".site-footer span:last-child")], }); }); test("Org documentation remains readable", async ({ page }) => { await page.goto("/alpha/doc/tip/docs/org-support.org"); await expect(page.locator(".org-document")).toBeVisible(); await expect(page.locator(".org-toc")).toBeVisible(); const viewportOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(viewportOverflow).toBe(false); await expect(page).toHaveScreenshot("org-document-mobile.png", { fullPage: true, mask: [page.locator(".site-footer span:last-child")], }); }); test("Org wiki remains readable", async ({ page }) => { await page.goto("/alpha/wiki?name=Org%20Wiki"); await expect(page.locator(".org-document")).toBeVisible(); await expect(page.locator(".org-toc")).toBeVisible(); const viewportOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(viewportOverflow).toBe(false); await expect(page).toHaveScreenshot("org-wiki-mobile.png", { fullPage: true, mask: [page.locator(".site-footer span:last-child")], }); }); });