How to Test Websites with Screenshot Diffs in Percy
Add Percy visual checks to your existing test suite, capture stable UI states, review diffs, and choose baselines that fit your team.
Percy adds visual regression checks to an existing browser or component test workflow. Your test suite captures named page states, Percy processes those states and renders screenshots across configured browsers and widths, and your team reviews the resulting diffs against a baseline.
The key distinction: Percy’s SDK captures and serializes the page state, while Percy’s infrastructure renders the screenshots. The screenshots are not captured inside the test suite. The exact package, snapshot call, command, and configuration depend on your framework and Percy SDK, so use the current Percy integration guide for your stack for version-specific setup.
1. Set up Percy in your existing test workflow
Start with the test runner you already use. Percy provides SDKs for web applications and component libraries, and its CI integrations add visual checks alongside existing tests. The general sequence is:
- Choose the current Percy SDK guide for your test runner or component framework.
- Install and configure that SDK as its guide specifies, including the project token or other required credentials.
- Add snapshot calls at test points where the intended UI state is ready.
- Run the suite with Percy enabled in local development or CI.
- Wait for the Percy build, inspect its screenshots and diffs, then approve or reject the changes using your baseline strategy.
Keep SDK setup and visual capture in the same workflow as the code under review. This gives reviewers a direct path from a changed page to the visual result. Percy documents integrations for code review, pull or merge requests, Slack, and webhooks.
2. Choose stable snapshot points
A snapshot should represent a state a user can actually see and that the team wants to protect. Useful states include a route’s default view, a responsive layout, a completed form, an error state, or an opened modal. Give snapshots names that identify both the page and state, such as “account settings — validation error” or “pricing — mobile”.
Wait for the application-specific readiness condition before calling the Percy snapshot function. Prefer a test-runner condition tied to the content or state being checked over a fixed delay: a delay may be too short on a slow run and waste time on a fast one. Make test data, viewport, authentication, and other state inputs repeatable so an unrelated data change does not create noisy diffs.
Capture states that answer a review question. A small, intentional set of representative states is easier to understand than snapshots at arbitrary points in the test.
3. Know what Percy captures and renders
When the snapshot function runs, the Percy SDK serializes the current DOM state. Its documented capture includes form values and CSSOM, and supports accessible iframes and canvas. A video without a poster is serialized as a still image of its current frame. Percy then discovers the assets needed to render the captured page. By default, asset discovery captures assets on the same hostname as the test.
Percy’s infrastructure renders the captured state across configured browsers and widths. This remote rendering stage is separate from the browser running your tests. DOM capture supports Firefox and Chromium; Shadow DOM capture is documented as Chrome-only. During rendering, JavaScript is disabled by default because the page’s JavaScript has already run before capture. Enabling it can cause unexpected behavior when the captured DOM is already formed. Percy also removes noscript elements and freezes CSS animations while rendering.
These stages explain why a page that looks correct in the test browser can still have a Percy issue: asset discovery may not reach an external host or authenticated resource, or the remote rendering environment may differ from the local browser.
4. Run the build and review diffs
- Run the Percy-enabled test workflow and confirm the snapshots were captured.
- Wait for Percy to finish processing the visual build.
- Open the snapshots and compare the rendered result with its baseline.
- For each difference, decide whether the change is intentional or a regression. Check the relevant code change and state before approving.
- Approve or reject at the build or snapshot level according to the selected baseline strategy.
Keep visual review close to the code review that caused the change. CI, pull or merge request integrations, Slack notifications, and webhooks can help route results to the right reviewers.
5. Choose a baseline strategy
A baseline is the previously approved visual state used for comparison. Percy documents two strategies; choose the one that matches how your team reviews changes.
| Strategy | How comparison works | Review unit | Best fit |
|---|---|---|---|
| Git | A build compares against a build from a base branch found through Git commit history. | Approve or reject the whole build. | Teams running Percy in CI on feature branches. Percy says most teams should use this strategy. |
| Visual Git | Comparisons use the latest approved snapshots on each branch and do not require Git history. | Approve individual snapshots. | Teams that approve snapshots one at a time or run visual tests outside the development pipeline. |
For Percy CLI projects, PERCY_BRANCH can select the base build manually. If diffs look unrelated to the current change, first verify which branch and build Percy used as the baseline. A baseline strategy that does not match your review process can make the comparison confusing.
6. Fix common capture and rendering problems
| Symptom | Likely cause | What to do |
|---|---|---|
| External images, fonts, or styles are missing | Asset discovery captures the test hostname by default. | Allow the additional hostnames through the SDK’s asset discovery configuration. |
| Authenticated content or protected assets are absent | The remote discovery browser does not have the credentials used by the test browser. | Configure the required request headers, authorization, or cookies using the SDK’s discovery settings. |
| A page snapshot appears before an asset finishes loading | Asset discovery’s default network-idle timeout is 100 ms with no new network requests; the page may make more requests afterward. | Increase the discovery network-idle timeout using the relevant SDK configuration and ensure the application has reached the intended state before capture. |
| A form value or canvas drawing is absent | The state may be held in page memory rather than represented as ordinary DOM markup. | Percy documents serialization for form values and canvas drawings. Check that the snapshot call happens after the state is set and that the SDK captures the intended page. |
| Shadow DOM content differs or is missing | Shadow DOM capture is documented as Chrome-only. | Use Chrome for the capture workflow when you need Shadow DOM serialization, and check the current SDK guide for its supported configuration. |
| Local browser and Percy output disagree | Capture runs in the test browser, but screenshots are rendered remotely; the environments have different responsibilities. | Check asset access, configured browsers and widths, dynamic state, and whether JavaScript should remain disabled during rendering. |
| You need to inspect capture without creating a build | Uploading a full visual build makes local investigation slower or unnecessary. | Use Percy CLI --debug to run SDK capture and asset discovery without creating a build or uploading snapshots. Use --verbose for detailed logging while still uploading snapshots. |
7. Keep visual checks reliable and efficient
- Make state deterministic. Control test data, authentication, responsive dimensions, and the UI state being captured.
- Wait for the actual page condition. A selector or application-ready signal is more dependable than assuming one fixed delay covers all environments.
- Review asset access. Include required hostnames and credentials in discovery configuration so the remote renderer can retrieve protected resources.
- Limit snapshots to useful states. Descriptive snapshots make review faster and reduce repeated coverage of the same view.
- Use debug modes deliberately. Run
--debugwhile investigating local capture or discovery, and--verbosewhen you need logs for an uploaded build.
Percy’s documented workflow distributes screenshot rendering across its infrastructure, so the test suite’s browser is responsible for capturing page state rather than producing every final cross-browser screenshot itself. No universal runtime or cost estimate follows from the workflow documentation: execution time and service cost depend on the current plan, project configuration, and number of snapshots. Check Percy’s current product materials for plan terms rather than relying on a generic estimate.
8. Or skip the browser setup
If you need a clean capture of a URL without wiring a browser into a one-off script, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request options and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
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 fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
- Cookie banners are accepted and removed before capture, along with 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers say whether the page was clean and whether it was billed.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up free for ScreenshotNeo and get 1,000 screenshots a month with no card.
9. FAQ
Does Percy take screenshots inside my test runner?
No. The SDK captures and serializes the page state; Percy’s infrastructure renders the screenshots.
Do I need a fixed wait before every snapshot?
No universal delay is reliable. Wait for the specific UI state your test is checking.
Which baseline should a team start with?
Percy says most teams should use Git, especially when running visual tests in CI on feature branches. Choose Visual Git when per-snapshot approvals or workflows without Git history fit better.
Can I use Percy with a page behind authentication?
Yes, but asset discovery may need the relevant headers, authorization, or cookies configured so protected resources can be fetched.


