Free tools Windows power users keep installed
One-click scans. No signup required.
Add a visual assertion after your functional test has reached and verified the UI state you want to protect. In Playwright Test, use toHaveScreenshot() for a page or locator. In Cypress, cy.screenshot() captures an image but does not compare it with a baseline, so add a comparison integration. Keep functional and accessibility checks: a screenshot diff checks appearance, not behavior or accessibility.
What a visual assertion adds to a functional test
A functional test drives the application and checks behavior or state: a form submits, a message appears, or a dialog opens. A visual assertion compares the rendered page or component with an approved reference image. Together, the checks can catch both a broken interaction and a rendering regression such as missing styling, overlap, or a layout shift.
Place the screenshot checkpoint after the functional actions have produced the state that matters. First assert that the expected state exists; then compare how it looks. A baseline is an approved reference, not proof that the implementation is correct.
How to compare screenshots in Playwright Test
Playwright Test includes screenshot assertions for pages and locators. This example checks a meaningful state, then snapshots the page:
import { test, expect } from '@playwright/test';
test('welcome page looks correct', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
await expect(page).toHaveScreenshot();
});
The first run can create a reference image; subsequent runs compare the current rendering with that reference and report differences. Review the generated diff. If the UI change is intentional, update the baseline deliberately and include that change in review rather than treating every mismatch as something to suppress.
Choose page or locator scope
- Page screenshot: useful for page-level layout and interactions between regions, but more exposed to unrelated content changes.
- Locator screenshot: useful when the contract belongs to one component or region. It narrows the comparison and can make a failure easier to assign.
Use a locator for a focused component state and a page snapshot when the surrounding layout is part of what you intend to protect.
Does Cypress compare screenshots?
No. Cypress’s built-in cy.screenshot() captures an image; it does not compare that image with a baseline. Cypress describes the general workflow as capturing a page or element, comparing it with an approved baseline, and reviewing differences. Add an integration that provides comparison, and place its snapshot command after an assertion confirms the relevant state has settled. See the Cypress visual testing guide.
For focused component states, Cypress Component Testing can help keep the rendering context controlled. Cypress lists Applitools, Argos, Chromatic, Happo, LambdaTest SmartUI, Percy, Sauce Labs Visual, SmartBear VisualTest, and Wopee.io as services with Cypress integrations. That list establishes integration options, not a current ranking of quality, pricing, or terms.
Recommended Free Tools
How to make visual checks less flaky
Wait for the intended state
Take the snapshot after data updates and relevant rendering finish. A capture during a loading transition or animation may record an accidental intermediate frame. Prefer a state-based wait or assertion over an arbitrary delay when the application exposes a reliable signal.
Control rendering inputs
- Use a fixed viewport and consistent browser and operating-system environment where practical.
- Use fixtures or intercepted responses to make API data repeatable.
- Keep browser version, fonts, display scaling, and other rendering inputs consistent where possible; differences can alter pixels.
- Account for third-party content that changes independently of your application.
Mask only genuinely uncontrolled regions
If a small region cannot be made deterministic, mask that target narrowly. Broad masks can conceal real defects. Prefer a targeted mask over increasing tolerance across the whole image, which can make meaningful changes harder to detect.
Rank #4
Choose checkpoints with an owner
Protect important pages, shared components, and user-visible states rather than attaching snapshots to every functional test. Each checkpoint produces a diff that someone must review. Match scope to ownership: a component-sized diff is often easier to route than an entire page diff.
Keep functional, visual, and accessibility checks distinct
- Functional assertions check behavior and state, such as successful submission, visible text, or an updated class.
- Visual assertions compare rendered pixels or another visual representation against an approved reference.
- Accessibility checks evaluate semantic structure and accessibility requirements.
A screenshot cannot establish that contrast meets a standard or that content works with assistive technology. Keep focused accessibility checks and manual assessment as appropriate. Playwright ARIA snapshots can check accessible structure, but an order-sensitive ARIA snapshot is not an image comparison. See the Cypress accessibility testing guide and Playwright accessibility testing guide.
Best Value
When to use a visual testing service
If your team uses Playwright Test and local reference images with a workable review process meet your needs, start with its built-in screenshot assertions. Consider a managed service when managed baselines, review dashboards, cross-browser rendering, or pull-request workflows address a real team need. Cypress users need a comparison integration because its core screenshot command only captures.
Compare options on framework and language support, page versus element capture, baseline management, browser and viewport coverage, dynamic-region handling, diff review and approval, CI integration, and cost and terms. Do not choose solely on claims that AI diffing or a larger tolerance eliminates false positives; validate the approach against your application’s actual rendering variability and review needs.
ScreenshotNeo as an API option
For teams that want a screenshot API rather than configuring browser capture themselves, ScreenshotNeo returns an image or PDF from a GET request. Its clean-shot workflow accepts consent banners like a visitor and removes known consent platforms, newsletter popups, and chat widgets before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. It also offers an MCP server for AI agents. The free plan includes 1,000 shots per month with no card, and paid plans start at $5 for 3,000 shots. An API capture is useful for obtaining screenshots, but it is not by itself a baseline comparison or a replacement for assertions in the test runner.
Or skip the browser setup
Make one request for a screenshot; check the ScreenshotNeo API docs for parameters and response details.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its 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. Sign up for free.
Troubleshooting visual assertion failures
- The screenshot differs on every run: check whether the page is captured mid-transition, data varies, third-party content changes, or the browser and rendering environment differ. Wait for the actual ready state and control inputs before adjusting comparison tolerance.
- A large page diff obscures a small component change: switch to a locator screenshot when the component is the intended contract, or keep the page capture if broad layout is what matters.
- Cypress saves a screenshot but the test passes despite a visual change: that is expected from
cy.screenshot()alone; add a comparison integration and an approved baseline. - A baseline update hides a regression: inspect the diff and confirm the design change is intended before accepting the new reference. Do not update snapshots simply to make a failing run green.
- The visual test passes but the feature is unusable: retain behavior assertions and accessibility checks; an image match does not prove either.
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.




