Testland
Browse all skills & agents

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.

Install with skills.sh (any agent)

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

chromatic-visual-regression-testing

Overview

Chromatic is a visual testing platform built by the team behind Storybook (chromatic-overview (opens in new window)). It works in three modes:

  • Storybook (default): every story becomes a snapshot.
  • Playwright: snapshots are captured during Playwright test runs via the --playwright flag.
  • Cypress: snapshots are captured during Cypress runs via --cypress.

The CLI shape: chromatic is one binary; everything (auth, framework choice, TurboSnap) is a flag or env var.

When to use

  • The project uses Storybook and wants a hosted UI for visual review with team sign-off on baseline changes.
  • The team needs TurboSnap - a per-PR speedup that snapshots only stories whose dependency graph changed (turbosnap (opens in new window)).
  • The repo already has chromatic in devDependencies or a chromatic.config.json at the root.
  • Visual coverage is story-driven, not full-page-driven (in contrast to Percy or Playwright snapshots, which are page-driven by default).

Authoring

Install

npm install --save-dev chromatic

(Per the Chromatic quickstart (opens in new window).)

Connect to a project

The first run uploads the Storybook build, captures a snapshot of each story, and establishes those snapshots as the project baseline (quickstart (opens in new window)):

npx chromatic --project-token <your-project-token>

Subsequent runs compare new snapshots to the baseline; visual changes must be explicitly accepted in the Chromatic UI before the build passes.

Authoring stories (Storybook mode)

Chromatic snapshots whatever your Storybook indexes, so authoring is "add a story." Per-story knobs that affect snapshots are passed in the story's parameters.chromatic block (e.g. viewports, delay, pauseAnimationAtEnd).

Authoring tests (Playwright / Cypress mode)

When invoked with --playwright or --cypress, the CLI captures snapshots from your existing Playwright / Cypress test runs (cli (opens in new window)); no per-test code changes are required beyond running the matching framework's archive output through Chromatic.

Running

CLI invocation

The canonical invocation in CI, with the token sourced from an env var (cli (opens in new window)):

export CHROMATIC_PROJECT_TOKEN=<token>
npx chromatic

Useful flags (cli (opens in new window)):

FlagEffect
--project-token <t>Override the token (env var preferred).
--playwrightCapture from Playwright runs instead of Storybook.
--cypressCapture from Cypress runs instead of Storybook.
--only-changedEnable TurboSnap (snapshot only stories affected by changed files).
--only-story-namesRun a build limited to specific story names.
--auto-accept-changesAuto-accept changes on the named branch (typically used on main for the first run after a planned UI overhaul).
--exit-zero-on-changesExit 0 on visual changes (still uploads, but the CI step doesn't fail).
--exit-once-uploadedReturn as soon as the upload completes; do not wait for the snapshot pass.
--dry-runSkip publishing; useful for local debugging.
--no-interactiveCI-style logging when running locally.
--trace-changedShow the TurboSnap dependency tree (debug).
--listPrint the indexed stories without running them.
--debugVerbose logging.
--diagnostics-file <p>Write a JSON diagnostics dump for support.

Configuration file

chromatic.config.json at the project root - config keys mirror the CLI flags converted to kebab-case (cli (opens in new window)):

{
  "$schema": "https://www.chromatic.com/config-file.schema.json",
  "onlyChanged": true,
  "exitZeroOnChanges": false,
  "autoAcceptChanges": "main",
  "externals": ["public/**", "tokens/**"]
}

externals lists glob patterns of non-bundled files that should still trigger a TurboSnap rebuild when changed (e.g. design tokens, static assets) (turbosnap (opens in new window)).

Reading exit codes

Per the Chromatic CLI docs (opens in new window), exit codes carry semantic meaning - the gate logic should treat visual changes (1) differently from system errors (3, 21 - 23, 101 - 105, 201 - 220):

CodeMeaning
0Success.
1Build has visual changes (review required).
2Build has component (Storybook) errors.
3Build failed (system error).
4No stories found.
5 - 6Build limited / canceled.
11 - 12Account quota / payment issues.
21 - 23Storybook build / load failures.
101 - 105Git or dependency issues.
201 - 220Network / API errors.
254 - 255Invalid options / unknown error.

Use --exit-zero-on-changes only when changes are reviewed in the Chromatic UI (not in CI) and you want CI to remain green pending review.

TurboSnap

TurboSnap analyzes git history and the bundler dependency graph to identify stories affected by a PR's changes; only those stories are snapshotted, and the rest copy their baseline forward (turbosnap (opens in new window)).

Enable via --only-changed (CLI) or onlyChanged: true (chromatic.config.json).

Bundler requirements

  • Webpack: Chromatic reads the stats file emitted by Webpack.
  • Vite: Vite also supplies a compatible dependency graph.

(Per turbosnap (opens in new window).)

Full-rebuild triggers

TurboSnap conservatively snapshots everything when any of these change (turbosnap (opens in new window)):

  • package.json changes without a valid lockfile.
  • Storybook config (main.js, manager.js).
  • preview.js imports.
  • Static folders.
  • Infrastructure upgrades (Storybook major version, etc.).

Merge commits also trigger conservative re-testing because TurboSnap cannot know ahead of time which baseline side to compare against (turbosnap (opens in new window)).

CI integration

The minimal pattern is: install chromatic, expose CHROMATIC_PROJECT_TOKEN as a CI secret, run the CLI, fail the job on exit != 0 (or != 0,1 if review happens in the Chromatic UI).

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

on:
  pull_request:
  push:
    branches: [main]

jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0   # required by TurboSnap

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

      - run: npm ci

      - name: Build Storybook + run Chromatic
        env:
          CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
        run: npx chromatic --only-changed

fetch-depth: 0 is required so TurboSnap can resolve the PR-vs-baseline commit ancestry (turbosnap (opens in new window)).

References

Related skills

chart-render-tests

Chart-render regression testing across the three chart-library families - Canvas (Chart.js: locator screenshot snapshot + `canvas.toDataURL()` diff with animations disabled), SVG (D3: `outerHTML` structural snapshot with generated-ID normalization + per-element data-binding tests), and declarative specs (Vega / Vega-Lite: JSON Schema validation + Vega-Lite → Vega compile test). Detects the family from package.json imports (chart.js / d3 / vega-lite), then applies the matching recipe; full per-library depth with citations in references/chartjs.md, references/d3.md, references/vega.md. Use when a dashboard or data product renders charts and their output needs regression coverage - before a chart-library major upgrade, after a theming change, or when runtime-generated Vega specs must be proven valid before render.

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.

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`; references/ carry the responsive-breakpoint viewport matrix (one project per breakpoint, cross-breakpoint matrix report, plus Chromatic / Percy / Storybook test-runner viewport syntax). Use when the project ships self-hosted visual regression coverage in Playwright (no external snapshot service), or needs a unified multi-viewport breakpoint matrix.

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 the binding gate artifacts - visual-gate.json + visual-gate.md - with fail-closed handling of a missing classifier run and author-cannot-self-approve enforcement, so the pipeline can exit non-zero on BLOCK. Use when the gate's input is pre-classified diff data and the enforcement concern is reviewer approval and a binding CI verdict.