ScreenshotNeo

BlogHow-to

How to Test Web Page Layouts with Percy

Add Percy visual snapshots to Playwright tests, choose browsers and baselines, and review layout changes in CI.

By the ScreenshotNeo team4 October 20268 min read

Percy tests web page layouts by capturing a page or component state, comparing it with an approved baseline, and showing visual differences for a person to review. Add a Percy snapshot call to a functional test after it reaches the state you want to check. Percy helps catch visual regressions that functional assertions can miss; reviewers decide whether a difference is intended. Percy’s visual-testing overview explains this workflow.

This guide uses Playwright and JavaScript. It covers setup, stable page states, browser coverage, baselines, CI, common problems, and when to use a screenshot API instead of managing a browser test.

1. Choose the pages and states to check

Start with pages and components where an unintended visual change would matter: key landing pages, common flows, or representative components. A snapshot is only useful when the test reliably reaches the intended state first.

  1. Choose a representative page or component.
  2. Write or reuse a functional test that navigates there and establishes the state to inspect.
  3. Handle application-specific loading before taking the snapshot. The right wait depends on the page; a network-idle wait is only an example, not a guarantee for every app.
  4. Keep test data and the visible state consistent between runs where possible.

For example, if the important state is a menu opened after a click, the test should open that menu before calling Percy. A snapshot of the default page would not cover that interaction state.

2. Add Percy to a Playwright test

The documented JavaScript route uses a Percy Web project, a project token stored in PERCY_TOKEN, the @percy/playwright package, and a snapshot call. See the Playwright integration guide for current setup details.

Install the package and configure the token

npm install --save-dev @percy/playwright

Create a Percy Web project and put its project token in the environment as PERCY_TOKEN. Keep the token in your local environment or CI secret store; do not commit it to source control.

Runnable example

This example assumes the project already has Playwright configured and its test command runs Playwright tests. The test navigates to a page, waits for network activity to settle as in Percy’s documented example, takes a snapshot, and closes the browser.

import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';

test('homepage visual snapshot', async ({ page }) => {
  await page.goto('https://example.com');
  await page.waitForLoadState('networkidle');
  await percySnapshot(page, 'Homepage');
});

Replace the URL and snapshot name with your page and a descriptive label. Use the wait that matches your app’s loading behavior; long-lived network requests can make networkidle a poor fit.

Run locally and in CI

Run your existing Playwright test command with the Percy token available. For a typical Playwright project, the test command is:

PERCY_TOKEN=YOUR_PERCY_PROJECT_TOKEN npx percy exec -- npx playwright test

On Windows or in a CI system that manages environment variables separately, set PERCY_TOKEN using that environment’s supported method, then run the command after --. Check your project’s Percy and CI integration instructions because setup varies by framework and CI provider. The Percy integrations documentation lists integration paths.

3. Review the snapshot build

After the run, open the Percy build and inspect the captured snapshots and their visual differences. Compare each change with the intended code change and product behavior. Approve changes that are intentional; request changes or reject the relevant build when a difference is a regression. Percy presents diffs for review; it does not determine whether a change is correct.

Useful snapshot names identify the page or state, such as Pricing page – annual plan selected. Keep the test’s state setup close to the snapshot call so a reviewer can understand what the image represents.

4. Choose browser coverage deliberately

Percy can render snapshots across enabled browsers. Each enabled browser creates a separate rendering and counts separately toward usage. Broader coverage can reveal browser-specific layout changes, and it also creates more results to review. Select browsers that matter for your audience and application rather than enabling every option without a review plan. See Percy’s cross-browser visual testing documentation.

Choice What it means
Percy Web Percy manages browser selection through the Percy project.
Percy on Automate Browser selection follows capabilities configured for the Automate session.

Operating systems and browsers can render fonts, native form controls, and scrollbars differently. Review browser-specific results before treating a difference as noise or as an application regression.

5. Pick a baseline strategy

A Percy build is compared with a base build. The baseline strategy controls how approved changes become the reference for later comparisons. Percy documents Git and Visual Git workflows in its baseline management overview.

Strategy Approval scope How the base is selected Fits when
Git Approve or reject a complete build. Uses Git history and a base branch. You want visual review aligned with branch and build history. BrowserStack says this is the choice most teams should use.
Visual Git Accept or reject individual snapshots; snapshots can become baselines independently. Does not require Git history for baseline selection. You need to approve snapshots individually or run visual checks outside the development pipeline.

Agree on a baseline approach for the team. Otherwise, developers may be unsure whether a snapshot should be approved in isolation or together with the rest of a build.

6. Connect Percy to pull requests and CI

Percy can run as part of a test suite and CI/CD workflow, with source-control and notification integrations available. A reviewed visual build can feed into pull-request review. The exact steps depend on your repository, framework, and CI service, so use the provider-specific instructions from Percy’s integrations documentation or its integrations page.

  1. Store the Percy project token as a CI secret.
  2. Run the functional test and Percy command in the relevant build workflow.
  3. Review the Percy results alongside the code change.
  4. Approve intentional visual updates or ask for a fix before merging.

7. Adjust diff sensitivity and reduce false positives

A visual diff can include rendering variation as well as a meaningful layout change. First check whether the test reached the same state, the same browser is being compared, and the environment renders the same content. Percy’s support index points readers to guidance on adjusting diff sensitivity between builds, ignoring regions, and selecting a base build with Git.

  • Adjust diff sensitivity when small rendering differences obscure changes you need to review. Choose a sensitivity that still exposes meaningful visual regressions.
  • Ignore a region when that region is inherently variable and its changes are not part of the visual check. Avoid ignoring a large area that could hide a real regression.
  • Check the base build when the comparison looks unrelated to the change under review. With Git baseline management, base selection follows Git history and the base branch.

8. Common problems and fixes

Symptom Likely cause What to check
No Percy build or snapshots appear The run did not execute through Percy, or the token is unavailable. Confirm PERCY_TOKEN is set in the process environment and the test command is wrapped with percy exec.
The snapshot shows a loading or intermediate state The test captured before the UI reached its intended state. Wait for an application-specific selector or state before the Percy call. Use network idle only when it suits the page.
The test hangs while waiting for network idle The page may keep network activity open, so idle is never reached. Replace that generic wait with a wait for the specific content or state the snapshot needs.
There are unexpected diffs between browsers Fonts, native controls, scrollbars, or other browser and operating-system rendering differences. Review each browser result and decide whether it represents a supported environment difference or a product issue.
A build compares against an unexpected image The selected base build or baseline strategy may not match the intended branch workflow. Check the base branch and Git history, or confirm whether Visual Git is the intended snapshot-level workflow.
Reviewers see noisy changes in a variable area Dynamic content is changing between captures. Stabilize the test data or ignore only the specific region whose variation is irrelevant.
Usage grows after enabling more browsers Each browser rendering counts as a separate screenshot. Review enabled browser coverage and retain the browsers that provide useful coverage.

9. Performance, reliability, and usage considerations

  • Performance: Each additional browser rendering creates more screenshot work and more diffs to inspect. Keep snapshots focused on high-value pages and states.
  • Reliability: Make navigation and state setup repeatable, and wait for the exact content that matters. A generic wait cannot guarantee a stable capture for every application.
  • Review load: More snapshots and browsers can increase review effort. Use descriptive names and choose representative states.
  • Usage: Percy counts each enabled browser snapshot separately. Check the current Percy account and plan details for applicable usage limits; the dossier does not establish prices.
  • Baselines: A baseline is part of the test’s meaning. Keep branch and approval conventions clear so future diffs compare against the intended build.

10. Or skip the browser setup

If you need a clean screenshot without adding and maintaining a browser capture flow, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can capture a URL in one GET request as PNG, JPEG, WebP, or PDF. It is not a replacement for Percy’s baseline comparison and visual review workflow; use it when you need a screenshot or page capture directly.

The API accepts common screenshot parameter names used by other screenshot APIs, which can make switching easier. See the ScreenshotNeo API documentation for options including full-page capture, CSS selectors, device presets, custom CSS and JavaScript, wait conditions, request blocking, caching, async jobs, bulk capture, and more.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.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(fs => fs.writeFile('shot.webp', bytes));

ScreenshotNeo accepts cookie banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo’s free 1,000 screenshots per month, with no card required.

FAQ

Does Percy decide whether a visual change is correct?

No. Percy compares captures and presents visual differences; a reviewer decides whether the change is intended.

Does a Percy snapshot replace functional tests?

No. The functional test gets the page into the meaningful state; Percy checks how that state renders.

Should every test take a Percy snapshot?

Choose snapshots for pages and states where visual coverage is useful. A focused set is easier to review and maintain.

Can I approve one snapshot without advancing a whole build?

Visual Git supports individual snapshot approvals. Git baseline management handles approval at the complete-build level.