diff --git a/frontend/e2e/playwright.config.ts b/frontend/e2e/playwright.config.ts index e6fcd9be..a6be7650 100644 --- a/frontend/e2e/playwright.config.ts +++ b/frontend/e2e/playwright.config.ts @@ -36,6 +36,11 @@ if (tier === 'stand' && !TIERS.stand.baseURL) { } export default defineConfig({ + // Playwright's 0.2 per-pixel default absorbs cross-machine rendering noise the + // pinned container removes by construction; it also let a palette change through + // while reporting green. Count differing pixels instead: glyph antialiasing + // jitters by 2, while the palette change that slipped moved 71. + expect: { toHaveScreenshot: { maxDiffPixels: 20, threshold: 0 } }, forbidOnly: isCI, fullyParallel: true, globalTimeout: isCI ? 10 * 60_000 : undefined, diff --git a/frontend/e2e/routes.ts b/frontend/e2e/routes.ts index 1aa12151..c8664b50 100644 --- a/frontend/e2e/routes.ts +++ b/frontend/e2e/routes.ts @@ -44,7 +44,9 @@ export const ROUTE_MANIFEST: RouteManifestEntry[] = [ { cassette: flowsCassette, path: routes.flow('5'), - ready: (page) => page.getByRole('button', { name: 'Flow actions' }), + // The terminal mounts after the header, and the visual spec masks it — + // capturing before it exists compares live pixels against a masked baseline. + ready: (page) => page.locator('.xterm').first(), sources: [ 'src/pages/flows', 'src/features/flows',