ScreenshotNeo

BlogHow-to

How to Configure Visual Testing in Chromatic for Web Pages

Set up Chromatic visual tests for Storybook states or Playwright page journeys, run them in CI, and review changes without losing control of baselines.

By the ScreenshotNeo team4 October 20269 min read

To configure visual testing in Chromatic, first choose where your test states come from: use Storybook for repeatable component states, or use the Playwright integration when your existing browser tests already drive complete web-page journeys. Create a Chromatic project, install the matching integration, run a local build and review its baseline, then add the project token to CI secrets and run Chromatic on your pull requests.

For page-level testing with Playwright, Chromatic captures an archive during the test run and renders snapshots in its cloud environment. The documented integration requires Playwright 1.38.0 or newer and Chrome in the Playwright configuration. Check the live docs against your locked versions before implementing because framework requirements can change. Chromatic Playwright setup

1. Choose the source of your visual test states

Chromatic can use Storybook, Playwright, Vitest, or Cypress as the source of UI states. Storybook stories are a good fit for isolated component variations, including mocked loading, empty, and error states. Playwright is a good fit when the visual state depends on navigating pages and completing interactions in a browser. Chromatic describes its approach as using the existing setup, configuration, mocking, and tests. Chromatic visual tests overview

Decision Storybook Playwright
Test source Stories that describe component and page states Browser tests that exercise user journeys
Local workflow Run and review from Storybook’s Visual Tests panel Run the existing Playwright suite through Chromatic’s integration
Best suited to Broad, isolated state coverage and edge cases Whole-page and integrated flows
Setup checks Storybook 7.6 or newer for the addon Supported Playwright version, Chrome, and archive location

You can use both approaches. Chromatic documents a two-project arrangement: create one project for Storybook and another for Playwright or Cypress, then run the CLI twice with each project’s token. This keeps each test source and its baselines distinct. Combining Storybook and end-to-end tests

2. Create a project and protect its token

  1. Create a project in Chromatic and connect it to the repository if you want pull-request status checks.
  2. Copy the project token. It authenticates CLI and CI builds; treat it as a secret.
  3. For CI, store it in the provider’s secret store as CHROMATIC_PROJECT_TOKEN. The CLI recognizes this environment variable automatically. Do not commit the token to source control. Chromatic CLI authentication and exit codes

The project identifier used by the Storybook addon is not the same as the secret project token. Keep the token in CI secrets and commit only the project configuration intended for the repository.

3. Configure Storybook visual tests

The Storybook route uses Chromatic’s Visual Tests addon. The current addon guide requires Storybook 7.6 or higher. From the project root, run the command for your package manager:

# npm / npx
npx storybook@latest add @chromatic-com/storybook

# Yarn

yarn dlx storybook@latest add @chromatic-com/storybook

# pnpm
pnpm dlx storybook@latest add @chromatic-com/storybook

Authenticate when prompted, select or create the Chromatic project, and let the addon add its project configuration. Start Storybook, run tests from the Visual Tests sidebar panel, and inspect highlighted changes. Accept a change only when the new appearance is intentional; otherwise fix the component or story and rerun.

The addon’s chromatic.config.json can specify the project ID, a custom Storybook build script, debug output, or zip upload. Use the actual project ID and script name for your repository:

{
  "$schema": "https://www.chromatic.com/config-file.schema.json",
  "projectId": "Project:YOUR_PROJECT_ID",
  "buildScriptName": "build-storybook",
  "debug": false,
  "zip": true
}

buildScriptName is useful when your build script has a different name. debug enables verbose logging when diagnosing setup problems. zip configures zip upload and is recommended in the addon guide for large projects. If you use a separate configuration file for an environment, point the addon to it with its configFile option. For monorepos, give each subproject its own Chromatic configuration and set its Storybook base, build, and config paths correctly. Visual Tests addon configuration

4. Configure Playwright page visual tests

Use this path when Playwright already drives the web-page states you want to compare. Install the Chromatic CLI and Playwright integration as development dependencies:

npm install --save-dev chromatic @chromatic-com/playwright

In a Playwright test, use the Chromatic integration’s test and expect helpers, then invoke the CLI with --playwright. A minimal TypeScript example for an existing page journey is:

import { test, expect } from "@chromatic-com/playwright";

test("pricing page visual state", async ({ page }) => {
  await page.goto("http://127.0.0.1:3000/pricing");
  await expect(page.getByRole("heading", { name: "Pricing" })).toBeVisible();
});

Run the app and Playwright tests first, then run Chromatic against the produced archive:

npx playwright test
npx chromatic --playwright

Chromatic’s CLI can be added as an npm script. This example lets the job finish successfully when visual changes are present while still surfacing them for review:

{
  "scripts": {
    "test:e2e": "playwright test",
    "chromatic": "chromatic --playwright --exit-zero-on-changes"
  }
}

Ensure the Playwright configuration includes Chrome because Chromatic relies on Chrome for snapshotting. If your Playwright outputDir is not the default, set CHROMATIC_ARCHIVE_LOCATION to the same archive location. In a monorepo, also align the archive scripts and config paths with the subproject layout. Playwright configuration and archive location

5. Run Chromatic in CI

A CI job generally installs dependencies, starts or builds the application as required, runs the browser tests when applicable, and invokes the Chromatic CLI. Add CHROMATIC_PROJECT_TOKEN in the CI provider’s secret settings before running the workflow.

# Example CI shell steps for a Playwright project
npm ci
npm run build
npm run start:test &
npx playwright test
npm run chromatic

Adapt the start command and readiness handling to your app and CI provider. For a Storybook project, use its build script and invoke chromatic without --playwright. For a Vitest or Cypress integration, use the documented --vitest or --cypress mode. The CI guide documents those modes and linked-repository pull-request checks. Automate visual tests with CI

When UI Test or UI Review is enabled, a visual change can produce a non-zero exit code. Choose the outcome intentionally:

  • Keep the review gate: run the normal command and let changes fail the job until reviewed.
  • Allow the job to pass while retaining review: use --exit-zero-on-changes. The build still reports changes; this flag does not accept them.
  • Auto-accept changes: configure autoAcceptChanges deliberately. This accepts detected changes and removes the normal human review of those baselines.

These settings are not interchangeable. Exiting successfully without accepting a change preserves the review decision; auto-accepting updates the baseline. Avoid commands such as || true as a default because they can hide build errors as well as visual changes. Chromatic configuration reference

6. Tune coverage, speed, and repository layout

Keep states deterministic

  • Control data and API responses so a story or page journey produces the same state on each run.
  • Wait for a meaningful readiness signal before capture, such as a visible page heading, rather than relying only on a fixed delay.
  • Keep timestamps, randomized content, rotating promotions, and other variable regions stable or exclude them from the visual state when appropriate.
  • Cover important variants explicitly: loading, error, empty, authenticated, and responsive states where they matter.

Use selective rebuilds carefully

onlyChanged enables TurboSnap behavior that skips unaffected stories. It can reduce work on large Storybook projects when dependency tracking is reliable. forceRebuild asks Chromatic to test everything rather than skip a rebuild. Treat these as coverage and performance controls: use selective runs for routine changes when appropriate, and force a complete rebuild when validating broad or uncertain changes. Options including onlyChanged and forceRebuild

Handle monorepos and multiple test sources

  • For separate Storybook subprojects, configure each project with its own correct Storybook base, build, and config paths.
  • For Playwright with a custom output directory, make CHROMATIC_ARCHIVE_LOCATION match the generated archive location.
  • For Storybook plus end-to-end page coverage, create separate Chromatic projects and use the corresponding token for each CLI run.

7. Troubleshooting common failures

Symptom Likely cause Fix
CI reports missing authentication The project token is absent, misspelled, or unavailable to the job. Store it as CHROMATIC_PROJECT_TOKEN in CI secrets and confirm the job can read that secret. Do not print its value in logs.
Playwright integration cannot find an archive A custom outputDir does not match Chromatic’s archive location. Set CHROMATIC_ARCHIVE_LOCATION to the actual archive directory and align monorepo scripts/config paths.
Playwright snapshots fail or differ from expected rendering Chrome is missing from the Playwright setup, or the browser/test environment differs from the expected one. Include Chrome in the Playwright configuration and review the test environment and dependencies.
Chromatic exits non-zero when snapshots change The build has visual changes and the selected CI behavior treats them as a failing check. Review the diff. Accept intentional changes; fix unintended ones. Use --exit-zero-on-changes only if CI should pass while leaving the changes unaccepted for review.
Storybook addon reports a login or project-list error The project ID/config may be missing or invalid, account access may be insufficient, or network controls may block Chromatic requests. Check the committed chromatic.config.json, confirm account and repository access, and check proxy/firewall restrictions. The addon documentation lists Chromatic endpoints to verify.
Addon fails with ERR_REQUIRE_ESM involving string-width The addon guide identifies this as an issue that can occur with older Yarn 1.x dependency resolution. Upgrade Yarn where possible. If that is not possible, follow the documented package resolution workaround and reinstall dependencies.
Build says no stories were found The selected Storybook build or project paths do not point to the intended stories. Check the build script, Storybook config location, and subproject paths; run the same build locally first.
Visual diffs appear on every run Page state may include unstable data, timing, fonts, or assets. Stabilize data and readiness conditions, ensure assets load, and remove unnecessary time-dependent state from the captured scenario.

8. Performance, reliability, and cost considerations

Visual test reliability depends on repeatable inputs and rendering conditions. A useful suite covers meaningful states without multiplying near-duplicate cases. Storybook makes isolated variants easier to maintain; browser journeys provide integrated coverage but can inherit instability from network data, application state, and test setup. Keep the CI token secure, pin project dependencies through the lockfile, and review framework requirements when upgrading.

For performance, use selective testing where its dependency assumptions fit the repository, avoid unnecessary duplicate states, and consider the addon’s zip configuration for large projects. CI time also includes installing dependencies, starting the application, and executing browser tests, so measure those stages in your own pipeline rather than assuming Chromatic is the only source of delay.

Chromatic usage and plan costs are specific to its current plan and snapshot terms; consult its current product and billing pages before estimating a project budget. No adoption, time-saving, or defect-reduction statistics are needed to configure the workflow.

Or skip the browser setup

If you need a screenshot of a live web page rather than a baseline-based visual regression workflow, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF. See the ScreenshotNeo API documentation for the supported parameters.

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}`);
  • Cookie banners are accepted like a visitor and removed, along with supported newsletter popups and chat widgets, before the shot.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status.
  • An MCP server lets AI agents, including Claude and Cursor, take screenshots.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.

Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.

FAQ

Does the Storybook addon replace CI?

No. The addon provides on-demand local runs; CI remains the automated pull-request workflow for the team.

Can I use the same Chromatic project token for Storybook and Playwright?

For the documented combined workflow, create separate projects for the two test sources and run each with its own project token.

Does accepting a visual change happen automatically when I use --exit-zero-on-changes?

No. That flag changes the process exit behavior; it does not accept the detected changes.

Can Playwright component testing serve as the Storybook replacement here?

Chromatic’s combined-workflow guide says Playwright and Cypress component testing are not supported as Chromatic’s component workbench integration. Use the documented integration matching your test source.