import { expect, test } from "@playwright/test"; const routes = [ "/", "/waterbodies", "/tackle", "/records", "/report", "/status", "/media", "/rules", "/waterbodies/р-вьюнок", "/fish/pike", "/admin", "/admin/moderation", "/admin/external-sources", "/admin/media", ]; const viewports = [ { width: 320, height: 800 }, { width: 390, height: 844 }, { width: 768, height: 900 }, { width: 1280, height: 900 }, ]; const themes = ["system", "light", "dark"] as const; test("ROADMAP visual matrix keeps routes within the viewport", async ({ page, context }) => { for (const theme of themes) { await context.clearCookies(); if (theme !== "system") { await context.addCookies([{ name: "rf4-theme", value: theme, url: "http://127.0.0.1:4321" }]); } await page.emulateMedia({ colorScheme: theme === "system" ? "light" : theme }); for (const viewport of viewports) { await page.setViewportSize(viewport); for (const route of routes) { await page.goto(route); const state = await page.evaluate(() => ({ clientWidth: document.documentElement.clientWidth, scrollWidth: document.documentElement.scrollWidth, hasMain: Boolean(document.querySelector("main")), hasHeading: Boolean(document.querySelector("h1")), theme: document.documentElement.dataset.theme || "system", })); expect(state.scrollWidth, `${theme} ${viewport.width}px ${route} overflows`).toBeLessThanOrEqual(state.clientWidth); expect(state.hasMain, `${route} has no main landmark`).toBe(true); expect(state.hasHeading, `${route} has no h1`).toBe(true); expect(state.theme, `${theme} SSR theme mismatch on ${route}`).toBe(theme); } } } });