level 16 / percy-and-chromatic

Percy & Chromatic

Integrate Percy and Chromatic for cross-browser visual reviews with cloud rendering, diffing, and team approval workflows.

Why Cloud Visual Testing Services?

Local toHaveScreenshot solves single-browser regression. Cloud services add:

  • Cross-browser rendering — compare Chrome, Firefox, Safari, Edge in one run
  • Responsive snapshots — capture multiple viewports automatically
  • Review workflow — visual diffs in a web UI, team approval before merge
  • Baseline management — no baseline files in git, managed in the cloud
  • Consistent rendering — cloud renders snapshots in a controlled environment

Percy Setup

npm install -D @percy/cli @percy/playwright
// e2e/visual.spec.ts
import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';

test('home page visual', async ({ page }) => {
  await page.goto('/');
  await percySnapshot(page, 'Home Page');
});

test('product card visual', async ({ page }) => {
  await page.goto('/products');
  await percySnapshot(page, 'Product Listing', {
    widths: [375, 768, 1280],  // capture at mobile, tablet, desktop
  });
});
# .github/workflows/visual.yml
- name: Run Percy
  run: npx percy exec -- npx playwright test e2e/visual.spec.ts
  env:
    PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

How Percy works:

  1. SDK captures DOM + assets (not a screenshot)
  2. Uploads to Percy cloud
  3. Percy renders pixel-perfect snapshots in browsers
  4. Compares against approved baseline
  5. Reports diff to PR

Chromatic Setup

Chromatic is primarily for Storybook component visual testing but also supports Playwright.

npm install -D chromatic
// With Storybook (most common use)
// Run: npx chromatic --project-token=<token>
// Chromatic captures every story at every breakpoint

// With Playwright (E2E visual)
import { test } from '@playwright/test';
import { takeSnapshot } from '@chromatic-com/playwright';

test('checkout flow visual', async ({ page }) => {
  await page.goto('/checkout');
  await takeSnapshot(page, 'Checkout Step 1');

  await page.getByRole('button', { name: 'Continue to payment' }).click();
  await takeSnapshot(page, 'Checkout Step 2');
});

Percy vs Chromatic vs Local

FeaturetoHaveScreenshotPercyChromatic
SetupZero (built-in)PERCY_TOKENProject token
BaselinesGit (png files)CloudCloud
Cross-browserOne browserMultipleMultiple
Review UINone (just fail)Web UIWeb UI
StorybookNoNoYes (primary)
E2E pagesYesYesYes
Free tierN/A5k snapshots/mo5k snapshots/mo
Best forCI regression gateFull-page E2EComponent library

Review Workflow

Percy/Chromatic flow on PR:

1. CI runs visual tests → uploads snapshots
2. Service renders + diffs against baseline
3. If diffs found:
   - PR check shows "X visual changes"
   - Link to review UI with side-by-side diffs
4. Team reviews in browser:
   - "Approve" → diff becomes new baseline
   - "Reject" → PR blocked, dev must fix
5. Baseline updates are permanent in cloud
   (not a file commit)

When to Use Each Approach

Local toHaveScreenshot:
✅ No external service dependency
✅ Works offline, instant feedback
✅ Full Playwright options (mask, clip, threshold)
❌ Cross-browser requires multiple baseline sets
❌ No review UI
Best for: regression gates on a single browser in CI

Percy/Chromatic:
✅ Cross-browser in one run
✅ Review workflow with team approval
✅ Consistent cloud rendering
❌ External service dependency
❌ Cost at scale
Best for: design system validation, cross-browser visual QA