How to Test a Web App’s Component Library with Storybook Screenshot Tests
Turn Storybook stories into visual regression tests with reviewed baselines, CI checks, and a clear workflow for diagnosing screenshot differences.
Storybook screenshot tests check whether a component’s rendered appearance has changed by comparing screenshots of its stories against approved image baselines. Create stories for important component states, choose a visual-testing workflow compatible with your Storybook version, review the first baseline, then run comparisons in development and CI. Treat visual tests as a complement to behavior and accessibility tests, not a replacement.
1. What Storybook screenshot tests check
Storybook calls these visual tests: rendered pixels from stories are compared with known baselines. A story captures a component in a particular state and configuration, so a useful story set becomes a set of repeatable visual regression cases. A difference can reveal a layout, color, size, or other appearance change; it does not, by itself, tell you whether the change is correct.
Choose the test type to match the failure you want to catch:
| Test type | Good for | Does not establish |
|---|---|---|
| Visual tests | Changes in rendered appearance compared with image baselines | That interactions, application logic, or accessibility are correct |
| DOM or HTML snapshots | Changes in markup or structure | That users see the intended visual result |
| Component and interaction tests | Component behavior and user actions | That every rendered state matches its approved appearance |
| Accessibility checks | Accessibility issues covered by the checks you run | Visual consistency across snapshots |
| End-to-end tests | Behavior that depends on a full workflow or running application stack | A complete baseline review for every component state |
Storybook stories can also be reused in Playwright or Cypress end-to-end tests. Use those when the question involves a larger workflow or application stack. Keep separate checks for behavior and accessibility: screenshots alone cannot prove either.
2. Build a representative set of stories
Before adding screenshot comparisons, decide which parts of the component library should be protected. A test can only represent the states you have described in stories.
- List the important components and visual variants: for example, button sizes and styles, form-field states, navigation variants, and content cards with short and long content.
- Add stories for meaningful states, including empty, loading, error, disabled, and populated states where they apply. Include edge content that has caused layout problems, such as long labels, missing images, or wrapped text.
- Keep each story deterministic. Supply fixed data and avoid relying on current time, random values, remote content, or state that changes between runs.
- Give stories clear names so reviewers can identify which component and state changed.
- Decide which stories need a visual check and which are better covered by behavior, accessibility, or end-to-end tests. You do not need to snapshot every theoretical combination to get a useful suite.
Stories are reusable testing cases, but a large, redundant story set can slow review and make intentional changes harder to find. Start with the states that matter to your users and expand when a defect or new component behavior reveals a gap.
3. Choose a visual-testing workflow for your Storybook version
Storybook’s documented managed visual-testing route uses Chromatic. The setup depends on Storybook version, so check the version installed in your project before following a command.
Storybook 7.6 and later: documented addon setup
The Storybook version 8 visual-testing guide says the official @chromatic-com/storybook addon requires Storybook 7.6 or higher and documents this setup command:
npx storybook@latest add @chromatic-com/storybook
Follow the setup prompts to connect a Chromatic account and project; setup configures the project identifiers. Confirm that the current addon and command are compatible with your installed Storybook version before applying them, especially if your project is on an older release.
Storybook 9
Storybook’s version 9 guide documents an integrated testing-widget workflow. Use the documentation for your installed major version to configure and run it. Do not assume setup instructions for version 8 and version 9 are interchangeable.
Vite and the legacy test runner
For Vite-based Storybook projects, Storybook’s current testing guide points to its Vitest addon. Storybook’s integration listing warns that official support for @storybook/test-runner has ended and suggests Vite users consider the Vitest integration. The legacy runner is based on Jest and Playwright; check Storybook’s compatibility table for the version range before adopting it. Avoid starting a new setup around a legacy runner without checking its current support status.
When a custom screenshot matcher fits
A custom setup can suit a team that needs to own screenshot capture and assertions. Storybook’s test-runner documentation shows a postVisit hook that waits for page readiness, captures a Playwright page screenshot, then compares it with jest-image-snapshot. That approach means your team owns the browser setup, snapshot storage, comparison plumbing, and compatibility maintenance. Prefer a managed workflow when its review and CI behavior meets your needs.
4. Establish and review the baseline
- Run the visual workflow against your stories to create the initial snapshots.
- Review the initial images as a deliberate reference point. Check that the stories represent the intended component states and that captures are stable and complete.
- When a later run reports differences, inspect the affected stories and highlighted pixel differences.
- If a difference is intended, accept it and update the baseline. If it is unexpected, fix the component or story and rerun the check.
- Keep the change and baseline update together in the same review so the reviewer can understand why the visual reference changed.
In the Storybook 9 guide, baselines accepted in the addon sync to the cloud so branch collaborators share them. Baseline behavior depends on the workflow you choose; check its documentation for how branches, approvals, and snapshot updates work.
5. Run screenshot tests in CI
Run visual checks during development so a component author can inspect differences while making a change. Also run them in CI on pull or merge requests so visual changes are visible before merge. Storybook recommends requiring the check in your Git provider to prevent unreviewed UI changes from merging.
- Use the workflow’s documented CI setup for your Storybook version and build system.
- Trigger the visual check on the branches and pull or merge requests that need review.
- Make the check visible and required according to your team’s merge policy.
- Have a reviewer inspect changed stories and approve intended baseline updates.
- When CI fails, distinguish a real appearance change from a rendering or environment problem before changing the baseline.
Exact CI configuration and commands vary by integration and Storybook version. Use the official setup instructions for the chosen workflow rather than copying a configuration from a different release.
6. Reduce noisy differences and keep runs reliable
- Stabilize story inputs. Fix dates, data, and state. Avoid randomness and mutable external content.
- Wait for the intended render. If content appears asynchronously, ensure the visual runner captures only after the story reaches the state you intend to compare.
- Check what changed before approving. A difference may come from a component edit, a story change, or the capture environment. Confirm which one explains it.
- Keep baselines reviewed. Accepting every difference without inspection weakens the baseline as a useful reference.
- Limit redundant cases. Cover meaningful variants and edge states, then add cases where they catch a distinct visual risk.
- Use compatible tooling. Verify the Storybook version, build setup, addon or runner support, and browser requirements together.
Hosted visual testing can provide a managed review workflow, while custom Playwright assertions give you more control over capture and comparison plumbing but require your team to maintain it. Choose based on version compatibility, browser ownership, baseline review, and CI needs. The research sources do not establish a comparable price or performance benchmark, so assess those from the current provider terms and your own workload rather than assuming one approach is faster or cheaper.
7. Troubleshooting common problems
| Symptom | Likely cause | What to do |
|---|---|---|
| Addon setup rejects the project or command | The installed Storybook version is outside the documented compatibility range, or setup differs for that major version. | Check the installed version. The version 8 guide says the official addon requires 7.6 or higher; follow the matching version’s instructions. |
| Tests do not run as expected in a Vite project | The chosen runner or integration does not match the project’s build setup. | Review Storybook’s current testing guide and consider the Vitest addon for Vite-based projects. |
| A legacy test-runner setup is unsupported or incompatible | The legacy runner’s official support has ended, or its compatibility range does not include your Storybook version. | Check the current integration listing and compatibility table; evaluate the recommended current integration for your setup. |
| Many differences appear after a small change | Shared styling, story inputs, or capture conditions may have changed across many stories. | Inspect representative affected stories first, identify the shared cause, and review all affected baselines before accepting them. |
| A screenshot captures incomplete content | The capture ran before the story finished rendering or reached its intended state. | Make the story deterministic and configure the chosen workflow to wait for the relevant readiness condition. For custom Playwright capture, Storybook’s example uses a page-readiness wait in postVisit. |
| A visual difference is difficult to judge | The story name or state does not make the captured case clear, or the baseline is stale. | Improve the story’s name and inputs, inspect the rendered image and pixel differences, then update the baseline only if the UI change is intentional. |
| CI allows an unreviewed visual change through | The visual check is not required by the repository’s merge rules. | Configure the Git provider to require the check, as Storybook recommends, and agree on who reviews baseline changes. |
8. DIY browser capture with ScreenshotNeo
Storybook visual-test integrations compare story renders with baselines. A screenshot API is useful for capturing a publicly reachable page or a deployed Storybook view; it does not by itself provide the same story-by-story baseline review workflow. For a private or local Storybook, use your visual-testing integration or run a browser in an environment that can reach it.
ScreenshotNeo is a website screenshot API and MCP server by Yorker Media. For a manual DIY capture, you can use a browser automation tool such as Playwright to open a deployed Storybook story and save a screenshot. The following illustrates the browser step; the URL must point to a publicly reachable story in your own deployment:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('https://your-storybook.example/?path=/story/button--primary', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'button-primary.png', fullPage: true });
await browser.close();
This captures an image, but you still need to store and compare it with a reviewed baseline. Prefer the Storybook visual-testing workflow when you need story-aware baseline review in CI.
Or skip the browser setup
For a reachable deployed page, ScreenshotNeo can return a screenshot in one GET request. See the ScreenshotNeo API documentation. Use your own deployed Storybook story URL in place of the example target.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-storybook.example/?path=/story/button--primary -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://your-storybook.example/?path=/story/button--primary"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://your-storybook.example/?path=/story/button--primary' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. These captures do not replace Storybook’s baseline comparison and review workflow. Sign up free for 1,000 screenshots a month, with no card required.
9. Performance, reliability, and cost
Run the smallest representative story set that protects the states your team cares about, and avoid duplicating cases without a distinct purpose. The practical cost of a suite includes capture execution, reviewer time, maintaining stories and baselines, and debugging unstable runs. Hosted and self-managed workflows distribute that work differently; compare current provider pricing and your own CI requirements before choosing. No benchmark or provider cost comparison is established by the cited Storybook material.
For reliability, pin down story inputs and use a workflow supported by your Storybook version and build system. A green visual check is meaningful only when the captured story is the intended state and the baseline was reviewed. Require the CI check if unreviewed appearance changes must not merge.
10. Frequently asked questions
Do screenshot tests replace component tests?
No. Screenshot comparisons check appearance. Use component or interaction tests for behavior and accessibility checks for accessibility concerns.
Can Storybook stories be used in end-to-end tests?
Yes. Storybook documents importing stories into Playwright or Cypress end-to-end tests. That can help when you need to exercise a workflow beyond a rendered component state.
Should every story have a screenshot baseline?
Only when a visual comparison provides useful coverage. Prioritize important variants and states, and avoid redundant cases that add review work without protecting a distinct visual outcome.
Can ScreenshotNeo approve visual changes for Storybook?
ScreenshotNeo captures pages. The Storybook workflows described here provide story-oriented visual comparison and baseline review; use one of those for that review process.


