What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Playwright Test’s expect(page).toHaveScreenshot() to compare a page with a reviewed reference image, or expect(locator).toHaveScreenshot() to compare just one component. The first run creates the reference; later runs compare new renders against it. Reliable screenshot diffing depends less on taking an image than on making the page state and rendering environment repeatable, setting a measured tolerance, and reviewing changes before updating the reference.
How Playwright screenshot diffing works
Visual regression testing checks whether a rendered page or component has changed in a way that matters. Playwright Test’s screenshot assertions capture the current render and compare it with an expected image stored alongside your tests. On the first run, the expected image does not exist, so Playwright creates it. On later runs, a mismatch fails the assertion and produces images you can inspect.
Use the page assertion when the overall page is the subject of the test. Use the locator assertion when the important contract is a particular element, such as a navigation bar, pricing card, or dialog. These screenshot assertions belong to the Playwright Test runner; they are not a generic image-diff method for arbitrary scripts.
Playwright waits for two consecutive screenshot captures to match before comparing the final capture with the reference. This helps with transient rendering, but it cannot make changing data, external content, or unpredictable application state deterministic.
Write a visual regression test
The following TypeScript example assumes a Playwright Test project and a page in your application at /pricing. Replace the path and any test setup with the route and state your application needs.
import { test, expect } from '@playwright/test';
test('pricing page matches its visual reference', async ({ page }) => {
await page.goto('/pricing');
await expect(page).toHaveScreenshot('pricing-page.png');
});
For a focused comparison, target a locator instead:
import { test, expect } from '@playwright/test';
test('primary plan card matches its visual reference', async ({ page }) => {
await page.goto('/pricing');
const card = page.getByTestId('plan-card-primary');
await expect(card).toHaveScreenshot('primary-plan-card.png');
});
Run the test with your project’s normal Playwright Test command, for example npx playwright test. If the reference is missing, the run creates it; inspect the resulting image and commit it with the test. Snapshot names and locations are associated with test identity and project context, and can be configured, so use a stable, descriptive name and keep the generated snapshot directory in version control.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Create and maintain trustworthy baselines
Generate the first reference deliberately
- Choose a page or component state that matters to users and that your test can reproduce.
- Run the test to create the missing reference image.
- Open the image and confirm it represents the intended state, viewport, and content.
- Commit the test and reference image together so future runs compare against the same reviewed expectation.
Review changes before updating
When an assertion fails, inspect the expected image, actual image, and generated difference image. Decide whether the rendering change is a defect or an intentional design change. For an intentional update, run npx playwright test --update-snapshots, review the new image, and include it in the same code review as the change that caused it. Updating references without inspection turns a regression check into a mechanism for accepting whatever rendered.
Make screenshot captures repeatable
Visual output can vary with the host operating system, browser version, settings, hardware, power source, and headless mode. Match the operating system and browser versions used to establish your baseline, especially when comparing images in CI. A baseline created on one environment may differ from a render on another even when the application code is unchanged.
- Control visible data: use stable fixtures or controlled network responses for content that affects the screenshot. Avoid live timestamps, randomized values, changing advertisements, and third-party content where practical.
- Wait for the right state: navigate to the actual state under test and wait for relevant content or application conditions. The assertion’s consecutive-capture settling behavior is helpful, but it does not replace deterministic test data.
- Keep the pointer out of the way: move it away from hover-sensitive controls before capture if hover styling is not what the test intends to exercise.
- Suppress transient elements selectively: use the screenshot assertion’s
stylePathoption to hide volatile elements, such as a rotating promotion or live clock. Its stylesheet can pierce Shadow DOM and inner frames. Avoid hiding the UI whose correctness you are trying to test. - Use animation handling intentionally: screenshot assertions disable animations by default. If the animation itself is under test, account for that behavior rather than assuming the screenshot captures an arbitrary frame.
- Keep capture scale consistent: the assertion can capture in CSS-pixel or device-pixel scale. Device-pixel images can be larger on high-DPI settings. Use the same choice for baselines and later runs.
PNG is the default screenshot format. A snapshot name ending in .webp can use WebP; Playwright documents both PNG and WebP as lossless for assertion snapshots. Do not change formats or capture scale casually after baselines have been established, because the comparison target itself will change.
Set a meaningful difference tolerance
Playwright uses pixelmatch for visual comparisons. Its threshold controls the acceptable perceived color difference for an individual pixel, in YIQ color space; the documented default is 0.2. That value does not mean that 20% of the image may differ. Larger threshold values allow more per-pixel color variation to be treated as a match.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Separate options bound how many pixels may differ overall:
maxDiffPixelssets an absolute limit on the number of differing pixels.maxDiffPixelRatiosets a limit on the proportion of differing pixels.
For example, a test can set a small absolute allowance while keeping the per-pixel threshold deliberate:
await expect(page).toHaveScreenshot('dashboard.png', {
threshold: 0.2,
maxDiffPixels: 25,
});
This is an example configuration, not a universal recommended tolerance. Choose values after inspecting the kinds of rendering variation your environment produces. If a test repeatedly fails on irrelevant noise, first stabilize the page and environment or hide only genuinely volatile content. Raising thresholds broadly can also make meaningful visual regressions pass.
Run screenshot tests reliably in CI
Install Playwright’s required browsers and operating-system dependencies in the CI environment, then run the same test suite against a predictable browser and platform setup. Playwright’s CI guidance recommends one worker in CI for stability and reproducibility; sharding can increase throughput across multiple jobs. Containers can also help keep visual-regression environments consistent. If you choose parallel workers on a capable self-hosted machine, verify that the parallel configuration does not introduce resource contention or unstable rendering.
Free tools Windows power users keep installed
One-click scans. No signup required.
Keep test reports and relevant screenshot artifacts when a run fails so reviewers can inspect the expected, actual, and diff images. Treat snapshot updates as code changes: the reviewer should be able to see what the test now accepts, not just that a command regenerated files.
Rank #4
Common Playwright screenshot-diff failures
The first run fails because a snapshot is missing
This is the baseline-creation step, not evidence that the page failed visually. Run the test to generate the reference, inspect the image, and commit it. If it was generated under an unintended project or environment, correct that setup before establishing the baseline.
The test fails intermittently with small differences
Look for changing content, animations, hover state, asynchronous updates, or environment differences. Stabilize test data and timing, move the pointer away when appropriate, use the built-in animation handling, and consider a narrowly scoped stylePath rule for irrelevant volatile elements. Do not start by increasing tolerance without identifying the source of the variation.
The diff is large after a browser or machine change
Check the operating system, browser version, headless mode, and capture scale against the environment that produced the baseline. Make the environments consistent where possible. If the environment change is deliberate, regenerate and review references as a coordinated update rather than accepting unexplained differences piecemeal.
Recommended Free Tools
An intentional UI change keeps failing
Inspect the actual render first. If it is the new approved design, update references with npx playwright test --update-snapshots and review the resulting images. If the render is not intended, fix the application or test state instead of replacing the reference.
Best Value
A test passes despite a visible mismatch
Review the configured threshold, maxDiffPixels, and maxDiffPixelRatio. A permissive per-pixel threshold can ignore color changes, while generous pixel-count limits can allow broad changed areas. Tighten the relevant limit and reduce capture noise rather than assuming a passing assertion means every visual change is harmless.
When to use hosted visual-testing services
Playwright’s built-in assertions are a practical starting point when your team wants reference images in its repository, direct integration with Playwright Test, and control over comparison settings. Hosted products may suit teams that need a different baseline-review or browser-coverage workflow, but their documented capabilities do not establish independent comparative quality or pricing here.
- Applitools Eyes for Playwright: its documentation describes integration into existing Playwright tests, visual checkpoints, hosted baselines, and cross-browser rendering through its service.
- Chromatic for Playwright: its documentation describes a Playwright integration that captures pages and related assets for cloud comparison and a hosted visual-review workflow.
Before choosing a hosted service, compare the comparison approach, local versus hosted baseline management, browser and viewport coverage, approval workflow, CI integration, and current pricing directly with the vendor. If local reference images and manual review fit your team, adding a service is not a prerequisite for screenshot diffing.
Or skip the browser setup
If you need a screenshot capture rather than an in-test baseline assertion, ScreenshotNeo can return a page image with one GET request. It is a capture API and MCP server; it does not replace Playwright’s reference-image comparison assertion. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture by default, with each step configurable. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify page verdict and billing status in headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for AI agents.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
For other supported options and setup details, see the ScreenshotNeo API documentation. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan to try it.
Frequently Asked Questions
Can I use `toHaveScreenshot()` outside Playwright Test?
No. Playwright’s screenshot assertion is part of the Playwright Test runner; use a separate image-comparison approach if you need a standalone script.
Does `threshold: 0.2` mean 20% of the screenshot may change?
No. It is the documented pixelmatch default for per-pixel perceived color difference in YIQ space; aggregate difference is controlled separately by `maxDiffPixels` or `maxDiffPixelRatio`.
Can ScreenshotNeo replace Playwright visual regression assertions?
No. ScreenshotNeo captures images through an API, while `toHaveScreenshot()` compares a Playwright render with a stored reference.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

