import { expect, test, type Page } from "@playwright/test"; // Visual-regression lock (plan P6): pixel baselines for the §2 design // system on the primary surfaces. Baselines are PER-PLATFORM (rendering // differs across OSes); CI excludes @visual until linux baselines are // generated there — see ci.yml. Regenerate intentionally with: // npx playwright test visual --update-snapshots const OWNER_EMAIL = "owner@acme.test"; const OWNER_PASSWORD = "e2e-password"; const SCREENSHOT = { animations: "disabled" as const, maxDiffPixelRatio: 0.02, }; async function signIn(page: Page) { await page.goto("/login"); await page.getByLabel("Email").fill(OWNER_EMAIL); await page.getByLabel("Password").fill(OWNER_PASSWORD); await page.getByRole("button", { name: "Sign in" }).click(); // Wait for the real workspace home — the login page also has a lowercase // "clawmates" heading, so confirm navigation and match case-sensitively. await page.waitForURL((url) => !url.pathname.endsWith("/login")); await expect( page.getByRole("heading", { name: "Clawmates", exact: true }), ).toBeVisible(); } test("login page looks right @visual", async ({ page }) => { await page.goto("/login"); await expect(page.getByRole("button", { name: "Sign in" })).toBeVisible(); await expect(page).toHaveScreenshot("login.png", SCREENSHOT); }); test("workspace home looks right @visual", async ({ page }) => { await signIn(page); await expect(page).toHaveScreenshot("workspace-home.png", SCREENSHOT); }); test("chat welcome and computer panel look right @visual", async ({ page, }) => { await signIn(page); await page.getByRole("link", { name: /Scout/ }).click(); await expect(page).toHaveURL(/\/claws\/.+\/chat\//); const before = page.url(); await page.getByRole("button", { name: "New" }).click(); await page.waitForURL((url) => url.toString() !== before); await expect( page.getByRole("heading", { name: /Hi, I'm Scout/ }), ).toBeVisible(); await expect(page).toHaveScreenshot("chat-welcome.png", SCREENSHOT); await page.getByRole("button", { name: "Computer" }).click(); const panel = page.getByRole("complementary", { name: "Computer" }); await expect(panel.getByText(/Scout's Computer/)).toBeVisible(); await expect(page).toHaveScreenshot("computer-home.png", SCREENSHOT); }); test("credits page looks right @visual", async ({ page }) => { await signIn(page); await page.getByRole("link", { name: "Credits" }).click(); await expect(page.getByText("Available credits")).toBeVisible(); await expect(page).toHaveScreenshot("credits.png", { ...SCREENSHOT, // Balance and usage are live numbers — mask them, lock the layout. // Balance and the whole usage card are live (and the runway line // appears/disappears with burn) — mask them, lock the layout. mask: [ page.getByTestId("credit-balance"), page.getByTestId("usage-card"), ], }); }); test("marketing landing looks right @visual", async ({ page, context }) => { await context.clearCookies(); await page.goto("/"); await expect( page.getByRole("heading", { name: /AI coworkers/ }), ).toBeVisible(); await page.evaluate(() => Promise.allSettled(document.getAnimations().map((a) => a.finished)), ); await expect(page).toHaveScreenshot("marketing.png", { ...SCREENSHOT, fullPage: true, }); }); test("team org chart looks right @visual", async ({ page }) => { await signIn(page); await page.getByRole("link", { name: "Team", exact: true }).click(); await page.getByRole("tab", { name: "Claw org chart" }).click(); await expect(page.getByRole("tab", { name: "Claw org chart" })).toHaveAttribute( "aria-selected", "true", ); await expect(page).toHaveScreenshot("team-orgchart.png", SCREENSHOT); });