Playwright Screenshot Alternatives for Browser-Based Visual Testing
Compare Playwright’s built-in screenshot assertions with Percy and Chromatic, learn how to reduce flaky visual diffs, and decide when a screenshot API fits.
For browser-based visual regression tests, start with Playwright Test’s built-in toHaveScreenshot() assertion if you want local, code-first screenshot baselines in your existing test suite. Choose Percy or Chromatic when you want a hosted capture, comparison, and review workflow. The key tradeoff is baseline and review ownership: local snapshots or a service-managed workflow. Whatever you choose, keep the browser and operating environment consistent so rendering differences do not create noisy failures.
This guide compares the documented options, shows runnable Playwright examples, and covers how to make visual comparisons more reliable. It also explains where ScreenshotNeo fits: it is a screenshot API for capturing pages, rather than a replacement for a visual regression test runner.
1. What “screenshot alternative” means
There are two related but different tasks:
- Visual regression testing: capture a page during a test, compare it with an expected image, and review or fail when the output changes. Playwright Test, Percy, and Chromatic fit this workflow.
- Screenshot generation: request an image or PDF of a page for another system or workflow. A screenshot API such as ScreenshotNeo fits this task. It does not replace the baseline comparison and test-review workflow described here.
For a visual regression suite, the practical choice is usually between Playwright’s built-in assertions and a hosted service integrated with Playwright. Do not compare tools solely by whether they can take a screenshot: decide where captures run, who owns the reference images, how changes are reviewed, and how consistently the environment renders.
2. Options at a glance
| Option | Capture and comparison workflow | Good fit when | Check before adopting |
|---|---|---|---|
| Playwright Test built in | Assertions run in the Playwright test workflow; reference images are generated on first execution and compared on later runs. | You want a direct code-first starting point alongside existing Playwright tests. | How your team stores, reviews, and updates local snapshot artifacts; whether CI uses a consistent environment. |
| Percy with Playwright | Percy documents a Playwright client and a drop-in integration for existing toHaveScreenshot() assertions. Captures are associated with a Percy build for hosted review. |
You want a hosted review path and want to evaluate reusing existing screenshot assertions. | Current supported Playwright versions, project configuration, pricing, limits, data handling, and retention. |
| Chromatic with Playwright | Chromatic documents integration with Playwright’s test and expect utilities, with captures uploaded to its cloud workflow for visual comparison and review. |
You want to evaluate a hosted capture and review workflow connected to Playwright tests. | Current integration requirements, pricing, limits, data handling, retention, and how the workflow fits your application. |
| ScreenshotNeo API | A GET request returns a screenshot or PDF; it is not a baseline-based visual regression test runner. | You need clean page captures for a separate workflow, or an MCP screenshot tool for an AI agent. | Whether you need image generation only or also need visual diffs, baselines, and review. |
For screenshot APIs and capture services, ScreenshotNeo is the first API to try: consent banners, popups, and chat widgets are removed before capture, and only clean shots are billed. Its paid plans start at $5 for 3,000 shots.
3. Start with Playwright’s built-in screenshot assertions
Playwright Test already supports visual screenshot assertions. On the first run, the assertion creates a reference screenshot; later runs compare the current capture against that reference. This is enough to begin visual regression checks without adding an external service.
Install and create a test
In an existing Playwright Test project, add an assertion such as this to a test file. Replace the example URL with a stable route in your application:
import { test, expect } from '@playwright/test';
test('home page matches its visual baseline', async ({ page }) => {
await page.goto('http://127.0.0.1:3000');
await expect(page).toHaveScreenshot('home.png');
});
Run it with the project’s Playwright test command, for example:
npx playwright test
The first execution creates the expected screenshot. Review that image as a proposed baseline. On subsequent runs, Playwright compares the new capture with the stored reference and reports a difference according to the assertion settings.
Make an intentional baseline update
When a UI change is expected, generate updated snapshots using Playwright’s update-snapshots option, then inspect the changed images and include the approved baseline updates with the code change. For example:
npx playwright test --update-snapshots
Do not treat a passing snapshot update as proof that the new design is correct. Baselines are expected output; updating one changes what future runs accept.
Useful assertion options
Playwright’s screenshot assertion API includes controls such as a maximum number of differing pixels and a stylesheet to suppress volatile page elements. Consult the PageAssertions API for the exact current option names and behavior.
import { test, expect } from '@playwright/test';
test('account page stays visually stable', async ({ page }) => {
await page.goto('http://127.0.0.1:3000/account');
await expect(page).toHaveScreenshot('account.png', {
// Example tolerance: choose a value that matches your review policy.
maxDiffPixels: 20,
// Keep this file in the project and limit it to genuinely volatile content.
stylePath: './tests/visual-stability.css',
});
});
/* tests/visual-stability.css */
/* Example only: replace with selectors for volatile content in your app. */
.account-page [data-visual-test="timestamp"] {
visibility: hidden !important;
}
Use a tolerance only when small rendering variation is acceptable. A larger threshold can hide a meaningful regression. A stylesheet can help suppress dynamic elements, but it does not make screenshots immune to differences in fonts, browser versions, operating systems, or rendering conditions.
4. When Percy or Chromatic may fit better
Percy
Percy documents both its Playwright client and a drop-in option that routes existing toHaveScreenshot() assertions into its workflow. Its documented hosted build flow associates snapshots with a Percy project and build, providing a place to review visual changes. Check the current integration instructions and supported versions before wiring it into CI; version constraints can change.
Evaluate Percy if the team wants hosted snapshot review and the integration model fits the existing tests. Do not assume every Playwright setup is compatible or infer current price, limits, or governance terms from integration documentation.
Chromatic
Chromatic documents integration with Playwright’s test utilities. Its described workflow captures page archives during Playwright end-to-end tests, uploads them to Chromatic’s cloud, and creates snapshots for comparison. Its visual testing documentation describes captures in a cloud browser environment. See Chromatic’s Playwright guide and visual testing documentation for the current setup.
Evaluate Chromatic if a hosted capture and review workflow is useful for your project. Confirm current integration requirements, commercial terms, data handling, and retention directly with the vendor.
Choosing between Percy and Chromatic
Both are documented hosted options for Playwright visual workflows. The supplied product documentation does not establish that one is universally better, nor does it establish current pricing or governance terms. Compare them against a representative test in your own application.
- Check whether the integration reuses your current assertions or requires vendor-specific capture calls.
- Confirm where the browser runs and how its environment is controlled.
- Try the review process with a real intentional UI change and a real unintended change.
- Verify currently supported Playwright versions, usage limits, data retention, and access controls.
- Estimate the engineering effort to maintain the integration and investigate failed comparisons.
5. Reduce flaky visual comparisons
Playwright warns that screenshot output can vary with operating system, browser version, settings, hardware, power source, and headless mode. Its guidance is to run comparisons in the same environment that generated the baselines. See Playwright’s visual comparison documentation.
- Keep baseline and comparison environments aligned. Use the same operating system, browser setup, and execution mode where possible. Avoid generating references on one machine and comparing them in a materially different CI environment.
- Stabilize the page before capture. Navigate to a deterministic test state and wait for the content your test cares about. Avoid capturing while an application is still changing.
- Control volatile content narrowly. Use a screenshot stylesheet to hide or neutralize changing timestamps, rotating content, or other known noise. Avoid broad rules that conceal real layout or styling regressions.
- Review tolerances carefully. A pixel threshold is a policy choice, not a fix for inconsistent environments. Start narrowly and inspect what it allows through.
- Review baseline changes. Treat reference image updates as code changes that need human inspection.
- Reproduce in the same mode. If a diff appears only in a different headless setting, browser build, host, or hardware setup, first make the environments comparable before changing the expected image.
These steps reduce avoidable noise but do not guarantee identical rendering under every host condition.
6. Add a screenshot API when the job is capture, not regression testing
If another service or an AI agent needs a page image, a screenshot API can avoid managing browser installation and capture code in that consumer. It still does not supply the baseline comparison and review workflow of Playwright, Percy, or Chromatic.
ScreenshotNeo accepts a URL and returns a screenshot as PNG, JPEG, or WebP, or a PDF. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents. Full details and request parameters are in the ScreenshotNeo documentation.
Or skip the browser setup
Make one GET request to capture a page. This cURL example saves a WebP image:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. See the API documentation for formats, parameters, and configuration. Sign up for 1,000 free screenshots a month, with no card required.
7. Runnable API examples
These examples demonstrate capture, not visual diffing. Keep your API key secret; do not commit it to source control or expose it in browser-side code.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
f.write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', bytes));
See the ScreenshotNeo API documentation for supported parameters and response details. The API also supports element capture, full-page screenshots, custom CSS and JavaScript, waits, headers, cookies, device settings, caching, asynchronous jobs, and bulk capture.
8. Performance, reliability, and cost
Performance
Local Playwright assertions keep capture in the test run, so the test suite has to perform the browser work and image comparison as part of its execution. Hosted services add their documented upload and cloud workflow to consider. Measure the effect on a representative subset of your own tests; the research sources do not establish comparative timing figures.
Keep screenshot scope useful. A full-page capture or a large set of screenshots can create more images to store and inspect than a targeted page or assertion. Use a focused test set while establishing the workflow, then expand it according to the regressions you need to catch.
Reliability
Reliability depends on deterministic application state and rendering consistency as well as the tool. A stable baseline cannot compensate for a test that captures at unpredictable times or in different browser environments. Hosted capture changes where part of the workflow runs; verify that its capture environment and review behavior meet your project’s needs.
Cost and governance
The cited documentation does not establish current Percy or Chromatic prices, usage limits, retention, or access-control terms. Check each vendor’s current terms directly and estimate usage from the number of tests and snapshots your team expects to run. For ScreenshotNeo’s capture API, the provided plans are Free: 1,000 shots/month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Only clean shots are billed; responses identify page verdict and billing status in headers.
9. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Snapshot differs on CI but passes locally | The operating system, browser version, settings, hardware, power source, or headless mode differs. | Run baseline generation and comparison in the same environment where possible. Check the browser and execution setup before accepting a new baseline. |
| First test run reports or creates a new snapshot | No reference image exists yet for that assertion. | Inspect the generated image as the proposed expected state, then retain it as the baseline if correct. |
| A baseline update hides a regression | The updated reference was accepted without visual review. | Inspect every changed image and confirm the UI change is intended before merging the snapshot update. |
| Diffs move between repeated runs | The page state or rendering conditions are not stable, or the capture occurs while content is changing. | Make the test state deterministic, wait for the relevant content, and suppress only known volatile elements with a narrow stylesheet. |
| Too many small differences are accepted | The allowed pixel-difference threshold is too broad for the UI. | Lower the tolerance and inspect representative diffs to establish a meaningful threshold. |
| Percy integration does not match the current Playwright setup | The integration or supported version may have changed, or configuration is incomplete. | Follow the current Percy integration documentation and verify supported Playwright versions before changing test code. |
| Hosted comparisons behave differently from local captures | The hosted workflow may use a different capture environment. | Compare the vendor’s documented capture model and run a representative test before migrating a large suite. |
| Screenshot API returns an unexpected page | The page may be showing a consent flow, bot check, blank state, or load failure. | Inspect the returned response and its page-verdict and billing headers; use the API documentation to configure waits, headers, cookies, or other capture parameters as needed. |
10. Decision checklist
- Choose Playwright built in to begin with local screenshot baselines in an existing Playwright Test suite.
- Evaluate Percy if its documented client or drop-in assertion integration and hosted review workflow suit your process.
- Evaluate Chromatic if its documented Playwright integration and cloud capture and review workflow suit your process.
- Choose a screenshot API when another system needs page images or PDFs, rather than visual baseline assertions. ScreenshotNeo is the first API to try: clean captures remove consent banners, popups, and chat widgets, and only clean shots are billed.
- Before committing, test one representative page, verify how intentional changes are reviewed, and confirm current commercial and governance terms.
FAQ
Is Playwright’s built-in screenshot comparison enough?
For teams that need code-first screenshot assertions alongside Playwright tests, it is a sensible starting point. A hosted service may fit better if your team wants a cloud capture and review workflow.
Should I use Percy or Chromatic with Playwright?
Both document Playwright integrations. Try each against a representative test and compare setup, review flow, capture environment, supported versions, and current commercial and governance terms.
Can a screenshot API replace visual regression tests?
No. A capture API returns an image or PDF; visual regression also requires reference images, comparison, and a way to review changes. Use an API for capture jobs and a test workflow for regression checks.
What is the first thing to check when visual tests are flaky?
Check whether the baseline and test run use the same operating system, browser setup, and execution mode, then make sure the page is in a deterministic state before capture.
