Playwright includes built-in visual regression via toHaveScreenshot() and toMatchSnapshot(). Compare current renders against committed baseline images and fail when pixels differ beyond a threshold.
Screenshot Assertions
First run generates baseline PNGs stored in a *-snapshots/ folder next to your spec. Subsequent runs pixel-compare against baselines. Update baselines intentionally with --update-snapshots after verified UI changes.
Mask dynamic regions (timestamps, ads, avatars) with mask: [locator] so immaterial differences do not fail tests.
Baselines live in spec-file-name-snapshots/ directories.
maxDiffPixels and threshold tune sensitivity.
mask hides dynamic elements from comparison.
Run visual tests in consistent viewport and project settings.
Visual Testing Reference
API and CLI for snapshots.
API / Flag
Purpose
toHaveScreenshot()
Full page or viewport snapshot
locator.toHaveScreenshot()
Single component snapshot
--update-snapshots
Regenerate baselines after UI change
maxDiffPixels
Allow small pixel drift
mask
Exclude dynamic regions
Project-specific dirs
Separate baselines per browser
Per-Browser Baselines
Fonts and anti-aliasing differ across Chromium, Firefox, and WebKit. Store separate snapshot directories per project or run visual tests only on one canonical browser for stability.
Updating Baselines in PRs
When UI changes intentionally, run --update-snapshots locally, commit new PNGs in the PR, and require design review on snapshot diffs — treat them like code changes.
Common Mistakes
Running visual tests across all browsers without separate baselines — constant false positives.
Not masking clocks, random IDs, or animation frames.
Updating snapshots blindly without reviewing pixel diffs.
Different viewport sizes locally vs CI causing mismatches.
Key Takeaways
toHaveScreenshot() compares against committed baseline PNGs.
Use mask for dynamic content and tune maxDiffPixels.
Update baselines with --update-snapshots after intentional UI changes.
Consider one canonical browser for visual tests to reduce noise.
Pro Tip
Stabilize pages before snapshots: await expect(locator).toBeVisible() and wait for fonts with document.fonts.ready if text shifts.
Continue with Accessibility Testing to build on what you learned here.