Claude-skill-registry chromatic
Automates visual regression testing for Storybook components using cloud-based snapshot comparison. Use when setting up visual testing, catching UI regressions, or reviewing component changes.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/chromatic" ~/.claude/skills/majiayu000-claude-skill-registry-chromatic && rm -rf "$T"
manifest:
skills/data/chromatic/SKILL.mdsource content
Chromatic Visual Testing
Cloud-based visual testing platform that captures screenshots of every Storybook story and detects visual changes.
Quick Start
# Install Chromatic npx storybook add chromatic # Or install manually npm install --save-dev chromatic # Run visual tests (first time creates baselines) npx chromatic --project-token=<token>
How It Works
- Cloud Rendering: Chromatic renders components in cloud browsers
- Snapshot Capture: Takes screenshot of each story
- Automated Diffing: Compares new snapshots to baselines
- Review & Verify: Approve or reject visual changes
Configuration
chromatic.config.json
{ "projectToken": "chpt_xxxxxxxxxxxx", "buildScriptName": "build-storybook", "storybookBuildDir": "storybook-static", "zip": true, "autoAcceptChanges": "main", "exitOnceUploaded": false, "exitZeroOnChanges": false, "onlyChanged": true, "externals": ["public/**"], "skip": "dependabot/**" }
Package.json Scripts
{ "scripts": { "chromatic": "chromatic --exit-zero-on-changes", "chromatic:ci": "chromatic --auto-accept-changes=main" } }
Story-Level Configuration
Disable Snapshots
// Skip specific story export const Loading: Story = { parameters: { chromatic: { disableSnapshot: true } } }; // Skip all stories in file export default { title: 'Components/Spinner', parameters: { chromatic: { disableSnapshot: true } } };
Viewport Testing
export const Responsive: Story = { parameters: { chromatic: { viewports: [320, 768, 1200] } } };
Delay for Animations
export const Animated: Story = { parameters: { chromatic: { delay: 300, // Wait 300ms before snapshot pauseAnimationAtEnd: true } } };
Diff Threshold
export const SubtleChanges: Story = { parameters: { chromatic: { diffThreshold: 0.2 // 0-1, higher = more tolerant } } };
Multi-Browser Testing
// Test in multiple browsers export default { title: 'Components/Button', parameters: { chromatic: { modes: { chrome: { viewport: 1200 }, firefox: { viewport: 1200 }, safari: { viewport: 1200 }, edge: { viewport: 1200 } } } } };
Modes for Theme/Locale Testing
// .storybook/modes.ts export const allModes = { light: { theme: 'light' }, dark: { theme: 'dark' }, mobile: { viewport: { width: 375, height: 667 } }, desktop: { viewport: { width: 1200, height: 800 } } }; // Component story export const Button: Story = { parameters: { chromatic: { modes: { 'light desktop': allModes['light'], 'dark desktop': { ...allModes['dark'], ...allModes['desktop'] }, 'light mobile': { ...allModes['light'], ...allModes['mobile'] } } } } };
CI Integration
GitHub Actions
name: Chromatic on: push jobs: chromatic: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Required for accurate baselines - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - uses: chromaui/action@latest with: projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} autoAcceptChanges: main onlyChanged: true
GitLab CI
chromatic: stage: test image: node:20 script: - npm ci - npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN only: - merge_requests - main
TurboSnap (Incremental Testing)
Only test stories affected by code changes:
npx chromatic --only-changed
Configure in CI:
- uses: chromaui/action@latest with: projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} onlyChanged: true traceChanged: expanded # Track changes across files
Handling Dynamic Content
Ignore DOM Elements
export const WithTimestamp: Story = { parameters: { chromatic: { diffIncludeAntiAliasing: false } }, decorators: [ (Story) => ( <> <Story /> <span data-chromatic="ignore"> {new Date().toISOString()} </span> </> ) ] };
Mock Data
export const UserProfile: Story = { parameters: { chromatic: { delay: 500 } }, loaders: [ async () => ({ user: { name: 'Test User', avatar: '/mock-avatar.png' } }) ] };
Review Workflow
Accept Changes
# Auto-accept on main branch npx chromatic --auto-accept-changes=main # Accept specific branches npx chromatic --auto-accept-changes="main|release/*"
Skip Builds
# Skip CI for specific patterns npx chromatic --skip="dependabot/**" # Skip with commit message git commit -m "docs: update readme [skip chromatic]"
Troubleshooting
Flaky Tests
// Increase delay for async content parameters: { chromatic: { delay: 1000, diffThreshold: 0.1 } }
Font Loading Issues
// Wait for fonts in preview.js export const decorators = [ (Story) => { const [fontsLoaded, setFontsLoaded] = useState(false); useEffect(() => { document.fonts.ready.then(() => setFontsLoaded(true)); }, []); return fontsLoaded ? <Story /> : null; } ];
External Resources
{ "externals": [ "public/fonts/**", "public/images/**" ] }
See references/configuration.md for complete CLI options and references/ci-integration.md for advanced CI setups.