Testland
Browse all skills & agents

percy-visual-regression-testing

Authors Percy visual snapshot tests via the @percy/cli + framework SDK (Playwright, Cypress, Selenium, Storybook), runs them with `percy exec -- {test command}`, configures viewports / masking / ignored regions, and reviews diffs in the Percy build UI. Use when the project ships visual regression coverage to BrowserStack Percy.

Install with skills.sh (any agent)

npx skills add testland/qa --skill percy-visual-regression-testing
View source

percy-visual-regression-testing

Overview

Percy is BrowserStack's visual testing platform. The integration shape is two-layered: the CLI (@percy/cli) plus a framework SDK (@percy/playwright, @percy/cypress, @percy/selenium, @percy/storybook, etc. - the Percy CLI README (opens in new window) lists the available SDKs as Playwright, Cypress, Selenium, Storybook, Puppeteer, Appium, plus framework-specific wrappers like Ember, Gatsby, Jekyll, and a custom SDK option).

The CLI starts a local snapshot server, the SDK calls percySnapshot(page, name) from inside your tests, and the build appears in the Percy UI for baseline review.

When to use

  • The repo already uses Percy (presence of @percy/* packages, .percy.yml, or PERCY_TOKEN in CI secrets).
  • The project wants visual diffs reviewed in a hosted UI (vs. self-hosted Playwright snapshots) and uses BrowserStack for cross-browser coverage.
  • A team needs the AI-summary / noise-filtering review flow that Percy provides on top of raw pixel diffs.

If the project does not already use BrowserStack, evaluate chromatic-visual-regression-testing (Storybook-first) or playwright-snapshots (self-hosted) before adopting Percy.

Authoring snapshots

Install (Playwright example)

npm install --save-dev @percy/cli @percy/playwright

Both packages are required: @percy/cli runs the local snapshot server, @percy/playwright exposes the percySnapshot function (percy-playwright (opens in new window)).

Snapshot in a Playwright test

const { chromium } = require('playwright');
const percySnapshot = require('@percy/playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('http://example.com/', { waitUntil: 'networkidle2' });
  await percySnapshot(page, 'Example Site');
  await browser.close();
})();

(Adapted from percy-playwright (opens in new window).)

Options to percySnapshot(page, name, options)

Per the percy-playwright README (opens in new window):

OptionEffect
percyCSSCSS injected immediately before the screenshot. Use this to neutralize timestamps, ad slots, or animations.
fullPageCapture the entire scrollable page rather than the viewport.
freezeAnimatedImageFreeze animated images (GIF / APNG) so the diff is deterministic.
ignoreRegionSelectorsCSS selectors whose bounding boxes are excluded from the diff.
customIgnoreRegionsCoordinate-based exclusion zones for ad-hoc cases.

Other SDKs (@percy/cypress, @percy/selenium, @percy/storybook) expose the same shape with framework-specific calling conventions - check the matching SDK README on github.com/percy.

Configuration file

The Percy CLI looks for config in this order (percy-config (opens in new window)):

  1. "percy" block in package.json
  2. .percyrc (YAML or JSON)
  3. .percy.json
  4. .percy.yaml / .percy.yml
  5. .percy.js / percy.config.js

The first found wins, searched from CWD up to the home directory. Use this file to set project-wide defaults (viewports, percyCSS, network idle timeout). For the current schema of the snapshot block (widths array, minimum height, etc.), check the latest percy-cli (opens in new window) release - the schema evolves with major versions and reproducing it from memory risks drift.

Running

The canonical invocation is percy exec -- <test command> (percy-exec (opens in new window)):

export PERCY_TOKEN=<your project token>
percy exec -- npx playwright test
percy exec -- yarn cypress run
percy exec -- npx jest

percy exec starts a local snapshot server on port 5338 (configurable), proxies snapshot requests from the SDK during the test run, and finalizes the build when the wrapped command exits (percy-exec (opens in new window)).

Useful percy exec flags

Per percy-exec (opens in new window):

FlagPurpose
--parallelMark the build as part of a parallel CI matrix.
--partialAllow the build to be marked partial (e.g. early exit).
-P, --port <n>Override the local server port (default 5338).
-d, --dry-runCapture snapshots locally without uploading.
-h, --allowed-hostnameRestrict asset discovery to specific hostnames.
--disallowed-hostnameInverse of allowed; useful for blocking analytics URLs.
-t, --network-idle-timeout <ms>Tune asset-discovery timing for slow apps.
--debugVerbose logging for troubleshooting.

PERCY_TOKEN is the only required env var (percy-cli (opens in new window)); the SDK no-ops when the token is absent (so tests stay green locally without a token).

Reviewing diffs

A successful Percy build appears in the Percy UI grouped by snapshot name; visual changes between commits appear as side-by-side diffs that require explicit approval before the build is marked passed. Percy also integrates with PR statuses so a build with unapproved changes shows as pending on the PR until a reviewer approves (percy-overview (opens in new window)).

The newer "AI Agents" mode generates natural-language summaries of visual changes and reduces noise on cosmetically-irrelevant diffs (percy-overview (opens in new window)); this is opt-in per project.

CI integration

The minimal pattern: install @percy/cli + the SDK, expose PERCY_TOKEN as a CI secret, wrap the test command in percy exec.

# .github/workflows/visual.yml
name: visual

on:
  pull_request:
  push:
    branches: [main]

jobs:
  percy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Run Percy + Playwright
        env:
          PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
        run: npx percy exec -- npx playwright test

For a parallel CI matrix (e.g. sharded Playwright tests), add --parallel to percy exec and use Percy's parallel-build coordinator (percy-exec (opens in new window)).

References

Related skills

chromatic-visual-regression-testing

Authors and runs Chromatic visual tests on Storybook, Playwright, or Cypress projects via the `chromatic` CLI; configures baselines, TurboSnap, UI Review, and CI gating; reads exit codes for change-vs-error classification. Use when the project ships visual regression coverage to Chromatic Cloud.

playwright-snapshots

Authors Playwright `expect(page).toHaveScreenshot()` assertions, configures masks / clips / threshold / maxDiffPixels per test, manages the per-OS / per-browser snapshot directory, and runs the update flow with `--update-snapshots`. Use when the project ships self-hosted visual regression coverage in Playwright (no external snapshot service).

responsive-breakpoint-runner

Produces a single breakpoint-matrix report (rows = pages/stories, columns = viewports) across Percy, Chromatic, Playwright snapshots, or Storybook test-runner. Routes per-engine viewport syntax, runs each, and aggregates the results into one cross-breakpoint view. Use when the team needs one unified pass/fail view across three or more viewport widths instead of separate per-engine or per-breakpoint reports. The matrix-view output is the distinguishing trait: it dispatches to playwright-snapshots (and the other engines) rather than replacing any single-engine skill.

storybook-visual-regression-testing

Sets up visual regression coverage for a Storybook project - either via the official @chromatic-com/storybook addon (hosted) or via @storybook/test-runner with a postVisit hook that calls Playwright's toHaveScreenshot (self-hosted). Covers test-runner install, lifecycle hooks (setup / preVisit / postVisit), and CI integration. Use when a repo already has a working `.storybook/` config and the team wants per-story visual coverage rather than page-level snapshots.

visual-baseline-conventions

Reference catalog for visual regression coverage decisions - which Storybook stories or pages get baselines, how to choose breakpoints, when to mask vs adjust threshold, when to add or remove a baseline, and a decision matrix for picking among Percy / Chromatic / Playwright / Storybook test-runner. Use when designing visual coverage for a new project or auditing an existing baseline set.

visual-baseline-gate

Consumes pre-classified visual-diff JSON and a reviewer-signed acceptance log to produce a single go/no-go CI verdict for visual regression. Blocks when intentional baseline changes lack a non-author reviewer sign-off or when regressions are present, and emits a markdown + JSON artifact for the CI step. Use this skill when the gate's input is pre-classified diff data and the enforcement concern is reviewer approval, not when the goal is fanning out to multiple engines (use a multi-engine CI orchestrator for that).

visual-diff-summarizer

Triages a PR's visual regression diffs when there are too many changed screenshots to review one by one. Clusters snapshots (from Percy, Chromatic, Playwright `toHaveScreenshot`, Storybook, Loki) by component / route, separates changes that match PR intent from cascade / regression suspects, recommends which baselines to update, and emits one PR comment pointing the reviewer at the screenshots that need actual eyes. Use when a PR has 20+ visual diffs / changed screenshots and the reviewer needs help deciding which to open.