summaryrefslogtreecommitdiff
path: root/tools/copland/tests/visual.spec.mjs
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
committercashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
commit4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch)
treec296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /tools/copland/tests/visual.spec.mjs
downloadrelic-4f49b16079b27d7ce633619e4cddfdf2bffbc952.tar.gz
initial commitHEADmaster
Diffstat (limited to 'tools/copland/tests/visual.spec.mjs')
-rw-r--r--tools/copland/tests/visual.spec.mjs94
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/copland/tests/visual.spec.mjs b/tools/copland/tests/visual.spec.mjs
new file mode 100644
index 0000000..73559e1
--- /dev/null
+++ b/tools/copland/tests/visual.spec.mjs
@@ -0,0 +1,94 @@
+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")],
+ });
+ });
+});