Getting Started
Your First Visual Regression Test in 10 Minutes
Visual regression testing catches unintended UI changes by comparing screenshots. In this guide you will go from zero to a working Playwright visual test, learn how diffs work, and set up CI so regressions never reach production.
Before You Start
Prerequisites
- Node.js 18 or later installed
- A web app running locally (any framework)
- Basic comfort with the terminal
- No Playwright experience required
Step 1: Install Playwright
Playwright ships with built-in screenshot comparison. One command gets you everything: the test runner, browser binaries, and config scaffolding.
This creates a playwright.config.ts file and a tests/ directory. The config is where you control screenshot thresholds, browser selection, and viewport sizes.
Step 2: Write Your First Screenshot Test
A visual regression test navigates to a page and calls toHaveScreenshot(). Playwright handles the rest: capturing the image, storing the baseline, and comparing future runs pixel by pixel.
The maxDiffPixelRatio option tells Playwright to allow up to 1% of pixels to differ. This accounts for minor rendering variations across operating systems without letting real regressions through.
Step 3: Generate the Baseline
The first time you run the test it will fail because no baseline exists yet. Playwright tells you to update snapshots.
Playwright saves the baseline image to a tests/visual.spec.ts-snapshots/ directory. Commit this directory to version control so every team member compares against the same baseline.
Step 4: Detect a Regression
Change something in your UI (swap a color, move a button, change font size) and run the test again without the update flag.
Playwright generates three files in the test results: the expected image, the actual image, and a diff highlighting every changed pixel. Open the diff to see exactly what changed.
Step 5: Test Specific Components
Full-page screenshots are a good starting point, but they break often because any change anywhere on the page triggers a diff. For more targeted tests, screenshot individual elements.
Element-level screenshots are less noisy than full-page captures. When the footer changes, your navbar test stays green.
Step 6: Handle Dynamic Content
Dates, avatars, ads, and animations will cause false failures if you screenshot them as-is. Playwright lets you mask or hide dynamic elements before capturing.
Masked elements are replaced with a solid color block in the screenshot. The test compares everything else normally. This is the single most important technique for keeping visual tests stable.
Step 7: Add CI Integration
Visual tests should run on every pull request. GitHub Actions works well because Playwright can install browsers in the CI environment.
When a test fails in CI, the diff images upload as artifacts. Reviewers can download them to see exactly what changed before approving the PR.
Mistakes Beginners Make (and How to Avoid Them)
Running on different operating systems
Font rendering differs between macOS, Windows, and Linux. Generate baselines on the same OS your CI uses (usually Linux). Use Docker or generate baselines in CI itself.
Screenshotting before the page is ready
Images, fonts, and animations that have not finished loading produce different screenshots every run. Always call waitForLoadState('networkidle') or wait for specific elements before capturing.
Setting the threshold too tight
A 0% pixel diff threshold sounds safe but generates constant false positives from anti-aliasing differences. Start at 1% and tighten only if you find real regressions slipping through.
Never updating baselines
When you intentionally change the UI, update baselines with --update-snapshots. Leaving stale baselines trains the team to ignore failures.
Skip the boilerplate
Assrt generates real Playwright visual tests from plain English descriptions. Open source, self-hosted, no vendor lock-in.
Get Started →