.agents/skills/sanity-visual-regression/SKILL.md
Visual regression runs on Chromatic, wired via .github/workflows/chromatic.yml. Three snapshot sources, one Chromatic project each:
| Source | Chromatic project | Repo secret | Status |
|---|---|---|---|
dev/storybook stories | sanity | CHROMATIC_PROJECT_TOKEN_STORYBOOK | Active |
| Vitest browser tests (in place) | vitest project | CHROMATIC_PROJECT_TOKEN_VITEST | Dormant (early access) — see activation below |
Playwright e2e takeSnapshot() | sanity_e2e | CHROMATIC_PROJECT_TOKEN_E2E | Active, curated opt-in |
All checks are non-gating during burn-in (exitZeroOnChanges); merges to main auto-accept
baselines. Review diffs on the Chromatic build linked from the PR check.
*.stories.tsx file to the owning package's src tree, usually in the same
__tests__ directory as the component or harness. Storybook discovers story files in workspace
package src trees. Two patterns:
TestWrapper (+ TestForm for form inputs) — see
Dialog.stories.tsx
and the Portable Text stories. If a vitest browser test already has a *Story.tsx harness,
put the story beside it and reuse it (never fork it): the harness stays shared between the
test and the story.pnpm dev:storybook (port 6006), then pnpm --filter sanity-storybook test
(every story runs as a vitest browser-mode test via @storybook/addon-vitest).Chromatic / Storybook visual tests check snapshots only affected stories
(TurboSnap) and links the build for review.Migration priority: card and tone-related components first (tones cascade through everything),
box primitives later. Snapshot the wrapper components in packages/sanity/src/ui-components
and vanilla-extract-migrated components (change indicators, DocumentLayout) as sentinels.
parameters.chromatic per story/meta: delay (ms before capture — Portable Text
stories use 300 for editor boot), diffThreshold, disableSnapshot: true (story stays in
Storybook + addon-vitest but is never snapshotted), modes (viewport/theme matrix — the global
1280×900 desktop mode in preview.tsx matches
the vitest browser viewport).@chromatic-com/vitest is pre-wired but dormant. To activate:
CHROMATIC_PROJECT_TOKEN_VITEST repo secret.Chromatic / Vitest browser visual tests job self-activates on the next run. No
code changes. Every browser test's end state becomes a snapshot; the first build is the full
baseline.Afterwards, consider slimming co-located harness-reuse stories that overlap with end-of-test
snapshots (keep them if the browsable workbench view is worth the snapshot spend). See
REFERENCE.md for local capture runs, takeSnapshot()/configure() usage inside
tests (only valid once the plugin is active — takeSnapshot() THROWS in normal runs, so never
commit calls to it while the integration is dormant), and cost controls.
e2e/studio-test.ts wraps @chromatic-com/playwright with auto-snapshots disabled globally —
the suite runs against per-PR staging datasets (live timestamps, presence, parallel mutations),
so blanket end-of-test snapshots would be pure diff noise. Opt in per spec with takeSnapshot()
at deterministic moments only. See REFERENCE.md before
adding e2e snapshots.
REFERENCE.md: architecture and rationale, local Chromatic runs, CLI flags,
snapshot cost management, Vercel deployment (studio-storybook.sanity.dev), troubleshooting.