2026-05-23 16:34:14 +02:00
|
|
|
import { test, expect } from "@playwright/test";
|
|
|
|
|
|
2026-05-25 19:32:22 +02:00
|
|
|
// Visual-regression baselines for @whynot/design.
|
|
|
|
|
//
|
|
|
|
|
// Two example pages are covered:
|
|
|
|
|
// 1. examples/showcase/index.html — every component, one page
|
|
|
|
|
// 2. examples/whynot-control/index.html — full app composition
|
2026-05-23 16:34:14 +02:00
|
|
|
//
|
|
|
|
|
// To update intentionally: pnpm test:visual:update
|
|
|
|
|
|
2026-06-26 21:08:06 +02:00
|
|
|
// The design-tokens stylesheet (colors_and_type.css) @imports IBM Plex from
|
|
|
|
|
// Google Fonts, but every token font stack is system-ui based — the webfont is
|
|
|
|
|
// unused. Left live it intermittently hangs in CI, blocking the page's module
|
|
|
|
|
// <script> (a pending stylesheet defers script execution) so custom elements
|
|
|
|
|
// never register. Abort the font CDNs so baselines are deterministic & offline.
|
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
|
|
await page.route(/fonts\.(googleapis|gstatic)\.com/, (route) => route.abort());
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-25 19:32:22 +02:00
|
|
|
test.describe("showcase — every component", () => {
|
2026-06-26 21:08:06 +02:00
|
|
|
// KNOWN BROKEN — tracked as adhoc against WHYNOT-WP-0002. The showcase page
|
|
|
|
|
// (every component on one page) wedges the renderer main thread when its
|
|
|
|
|
// module executes: components + vendored lit render fine in isolation, but
|
|
|
|
|
// one demo composition on this page infinite-loops, so the page never
|
|
|
|
|
// reaches `load` and no `showcase.png` baseline can be captured. The four
|
|
|
|
|
// whynot-control baselines are unaffected. Remove `.fixme` once the looping
|
|
|
|
|
// component is fixed and regenerate the baseline.
|
|
|
|
|
test.fixme("renders", async ({ page }) => {
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.goto("/examples/showcase/index.html");
|
|
|
|
|
// Wait for custom elements to register + Lit to render.
|
|
|
|
|
await page.waitForFunction(() => !!customElements.get("wn-button"));
|
|
|
|
|
await page.waitForTimeout(800);
|
|
|
|
|
await expect(page).toHaveScreenshot("showcase.png", { fullPage: true });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-23 16:34:14 +02:00
|
|
|
test.describe("whynot-control UI kit", () => {
|
|
|
|
|
test("prototypes index", async ({ page }) => {
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.goto("/examples/whynot-control/index.html");
|
2026-05-23 16:34:14 +02:00
|
|
|
await page.waitForFunction(() => !!document.querySelector("aside"));
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.waitForTimeout(800);
|
2026-05-23 16:34:14 +02:00
|
|
|
await expect(page).toHaveScreenshot("01-prototypes.png", { fullPage: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("inbox", async ({ page }) => {
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.goto("/examples/whynot-control/index.html");
|
2026-05-23 16:34:14 +02:00
|
|
|
await page.waitForFunction(() => !!document.querySelector("aside a"));
|
|
|
|
|
await page.click("aside a:has-text('Inbox')");
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.waitForTimeout(500);
|
2026-05-23 16:34:14 +02:00
|
|
|
await expect(page).toHaveScreenshot("02-inbox.png", { fullPage: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("signals", async ({ page }) => {
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.goto("/examples/whynot-control/index.html");
|
2026-05-23 16:34:14 +02:00
|
|
|
await page.waitForFunction(() => !!document.querySelector("aside a"));
|
|
|
|
|
await page.click("aside a:has-text('Signals')");
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.waitForTimeout(500);
|
2026-05-23 16:34:14 +02:00
|
|
|
await expect(page).toHaveScreenshot("03-signals.png", { fullPage: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("control doc — INTENT.md", async ({ page }) => {
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.goto("/examples/whynot-control/index.html");
|
2026-05-23 16:34:14 +02:00
|
|
|
await page.waitForFunction(() => !!document.querySelector("aside a"));
|
|
|
|
|
await page.click("aside a:has-text('INTENT.md')");
|
2026-05-25 19:32:22 +02:00
|
|
|
await page.waitForTimeout(500);
|
|
|
|
|
await expect(page).toHaveScreenshot("04-doc-intent.png", { fullPage: true });
|
2026-05-23 16:34:14 +02:00
|
|
|
});
|
|
|
|
|
});
|