SoftwareTestPilot
Module 09 · Lab 1
Advanced
10 min read

Visual Regression Testing in Playwright — Screenshots & Diffs

Catch unintended UI changes with Playwright's screenshot comparison. Pixel-perfect diffs, baseline management, and masking — all built in.

1. await expect(page).toHaveScreenshot()

Playwright's toHaveScreenshot matcher auto-baselines on the first run and diffs on every subsequent run. No third-party service required — baselines live next to your tests in git.

import { test, expect } from '@playwright/test';

test('homepage looks right', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('home.png');
});

On a failed diff Playwright writes expected, actual, and diff PNGs into test-results/ so you can eyeball exactly what changed.

2. Updating baselines

When a change is intentional, regenerate the baseline. Commit the new PNGs alongside the code that changed them.

npx playwright test --update-snapshots
# or narrow to one spec
npx playwright test homepage.spec.ts --update-snapshots

3. Masking dynamic regions

Timestamps, avatars, and ad slots will flake every visual test. Mask them — Playwright paints a solid box over each locator before snapshotting.

await expect(page).toHaveScreenshot({
  mask: [page.locator('.timestamp'), page.locator('.avatar')],
});

Tune tolerance with maxDiffPixels or threshold for anti-aliasing noise — but mask first, loosen tolerance second.

4. Cross-browser visual matrix

Playwright keeps a separate baseline per project. Add Chromium, Firefox, and WebKit to playwright.config.ts and the same test produces three diff folders — one per engine.

projects: [
  { name: 'chromium', use: devices['Desktop Chrome'] },
  { name: 'firefox',  use: devices['Desktop Firefox'] },
  { name: 'webkit',   use: devices['Desktop Safari'] },
],

File layout: home.spec.ts-snapshots/home-chromium-linux.png, home-firefox-linux.png, etc.

5. Hands-on task

Add a visual test for your app's homepage. Run it once to capture the baseline, ship a small CSS change, and watch the test fail with a diff PNG. Then update the baseline and re-run green.

6. What's next

Next, move into Module 10: Framework architecture — pull everything together into a maintainable suite you can hand to a new teammate.

Up next in the learning path

Module 10: Framework architecture