PW Visual Regression
State check before you start
This repo has no snapshot testing today: no toHaveScreenshot call, no *-snapshots/
directory, and snapshotPathTemplate is unset in playwright.config.ts. You are introducing it,
so say so, and get the baseline strategy agreed before generating files.
Two settings here directly affect snapshots and must be dealt with first:
| Setting | Value | Consequence |
|---|---|---|
headless |
false |
Headed and headless render differently. CI runs headed under xvfb-run, so baselines must be generated the same way or every comparison fails. |
viewport |
1920x1080 | Baselines are locked to this size. Changing it invalidates all of them. |
| projects | chromium only |
One platform of baselines. Adding a browser means regenerating. |
Workflow
- Snapshot a component, not a full page, unless the whole page is the contract.
expect(locator).toHaveScreenshot()beatsexpect(page). - Mask anything non-deterministic: dates, prices, avatars, the cart badge count.
mask: [page.locator('[data-test="shopping-cart-badge"]')]. - Set
maxDiffPixelRatiorather than chasing a zero-diff that anti-aliasing will never give you. - Generate baselines with
--update-snapshots, then open every generated PNG before committing. An unreviewed baseline locks in whatever bug was on screen. - Commit baselines. Note
.gitignorecurrently excludes/test-results/and/playwright-report/but not a snapshots directory, so the default location is safe.
Output shape
import { test, expect } from '@fixtures/test-base';
test('@Visual inventory grid matches the baseline', async ({ loginWithInventory, page }) => {
await expect(page.locator('[data-test="inventory-container"]')).toHaveScreenshot('inventory-grid.png', {
mask: [page.locator('[data-test="shopping-cart-badge"]')],
maxDiffPixelRatio: 0.01,
animations: 'disabled',
});
});
Verify
npx playwright test --grep @Visual --update-snapshots # first run, then REVIEW the PNGs
npx playwright test --grep @Visual # must pass twice in a row
Passing once proves nothing. A baseline that is not stable across two runs is not a baseline.