Setup visual regression testing with Storybook stories, configuration, and CI/CD workflows. Supports Chromatic, Percy, BackstopJS. Auto-invoke when user says "set up visual regression", "add Chromatic tests", "add screenshot testing", or "set up Percy".
Generates complete visual regression testing setup for Storybook components. Automatically invoked when you request "set up visual regression," "add Chromatic tests," or "add screenshot testing." Creates stories, config files, and CI workflows for Chromatic, Percy, or BackstopJS.
/plugin marketplace add alekspetrov/navigator/plugin install navigator@navigator-marketplaceThis skill is limited to using the following tools:
examples/design-system-vr.mdexamples/existing-storybook-vr.mdexamples/simple-component-vr.mdfunctions/chromatic_config_generator.pyfunctions/ci_workflow_generator.pyfunctions/story_generator.pyfunctions/vr_setup_validator.pytemplates/chromatic-config.json.j2templates/github-workflow.yml.j2templates/gitlab-ci.yml.j2templates/story-template.tsx.j2templates/storybook-main.js.j2Generate complete visual regression testing setup with Storybook stories, configuration files, and CI/CD workflows.
Supports: Chromatic, Percy, BackstopJS Frameworks: React, Vue, Svelte (TypeScript/JavaScript) CI/CD: GitHub Actions, GitLab CI, CircleCI
.stories.tsx with all variantsExecute: vr_setup_validator.py
Check:
Output:
{
"framework": "react",
"storybook_version": "7.6.0",
"vr_tool": "chromatic",
"ci_platform": "github",
"component": {
"path": "src/components/ProfileCard.tsx",
"name": "ProfileCard",
"props": [...],
"valid": true
},
"dependencies": {
"installed": ["@storybook/react", "@storybook/addon-essentials"],
"missing": ["chromatic", "@chromatic-com/storybook"]
}
}
If Storybook not found: Ask user if they want to install Storybook first, provide setup instructions.
If multiple VR tools found: Ask user which to use (Chromatic recommended).
Execute: story_generator.py
Process:
Template: templates/story-template.tsx.j2
Example output (ProfileCard.stories.tsx):
import type { Meta, StoryObj } from '@storybook/react';
import { ProfileCard } from './ProfileCard';
const meta = {
title: 'Components/ProfileCard',
component: ProfileCard,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
size: { control: 'select', options: ['sm', 'md', 'lg'] },
variant: { control: 'select', options: ['default', 'compact'] },
},
} satisfies Meta<typeof ProfileCard>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
name: 'John Doe',
avatar: 'https://example.com/avatar.jpg',
bio: 'Software Engineer',
size: 'md',
variant: 'default',
},
};
export const Small: Story = {
args: {
...Default.args,
size: 'sm',
},
};
export const Large: Story = {
args: {
...Default.args,
size: 'lg',
},
};
export const Compact: Story = {
args: {
...Default.args,
variant: 'compact',
},
};
// Accessibility test
Default.parameters = {
a11y: {
config: {
rules: [
{ id: 'color-contrast', enabled: true },
{ id: 'label', enabled: true },
],
},
},
};
Write to: {component_directory}/{ComponentName}.stories.tsx
Execute: chromatic_config_generator.py (or percy/backstop equivalent)
Generate 3 files:
{
"projectId": "<PROJECT_ID_PLACEHOLDER>",
"buildScriptName": "build-storybook",
"exitZeroOnChanges": true,
"exitOnceUploaded": true,
"onlyChanged": true,
"externals": ["public/**"],
"skip": "dependabot/**",
"ignoreLastBuildOnBranch": "main"
}
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@chromatic-com/storybook', // ← Added
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
};
{
"scripts": {
"chromatic": "npx chromatic",
"chromatic:ci": "npx chromatic --exit-zero-on-changes"
}
}
For Percy: Generate .percy.yml instead
For BackstopJS: Generate backstop.config.js instead
Execute: ci_workflow_generator.py
Detect CI platform from existing files:
.github/workflows/ → GitHub Actions.gitlab-ci.yml → GitLab CI.circleci/config.yml → CircleCIGenerate: .github/workflows/chromatic.yml
name: Visual Regression Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
chromatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for Chromatic
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
exitZeroOnChanges: true
onlyChanged: true
For GitLab CI: Add job to .gitlab-ci.yml
For CircleCI: Add job to .circleci/config.yml
Output to user:
✅ Visual regression testing setup complete!
## Files Created/Modified
✅ {ComponentName}.stories.tsx (Storybook story with variants)
✅ chromatic.config.json (Chromatic configuration)
✅ .storybook/main.js (Added @chromatic-com/storybook addon)
✅ package.json (Added chromatic scripts)
✅ .github/workflows/chromatic.yml (CI workflow)
## Next Steps
### 1. Install Dependencies
```bash
npm install --save-dev chromatic @chromatic-com/storybook
```
### 2. Create Chromatic Project
1. Go to https://www.chromatic.com/start
2. Sign in with GitHub
3. Create new project
4. Copy project token
### 3. Add Secret to GitHub
1. Go to repository Settings → Secrets and variables → Actions
2. Create secret: `CHROMATIC_PROJECT_TOKEN`
3. Paste your project token
### 4. Update chromatic.config.json
Replace `<PROJECT_ID_PLACEHOLDER>` with your actual project ID from Chromatic dashboard.
### 5. Create Baseline
```bash
npm run chromatic
```
This captures the initial screenshots as your baseline.
### 6. Test Visual Regression
1. Make a visual change to ProfileCard
2. Commit and push
3. CI will run Chromatic automatically
4. Review changes in Chromatic dashboard
## Documentation
See `.agent/sops/testing/visual-regression-setup.md` for detailed workflow.
## Troubleshooting
**Storybook build fails**: Ensure all component dependencies are installed
**Chromatic upload fails**: Check project token in secrets
**No changes detected**: Chromatic only runs on changed stories (use `--force-rebuild` to test)
def detect_storybook_config(project_root: str) -> dict
def detect_vr_tool(project_root: str) -> str
def validate_component_path(component_path: str) -> dict
def check_dependencies(project_root: str) -> dict
Returns: Validation report with detected setup and missing dependencies
def analyze_component(component_path: str, framework: str) -> dict
def generate_story(component_info: dict, template_path: str) -> str
def create_accessibility_tests(component_info: dict) -> str
def create_interaction_tests(component_info: dict) -> str
Returns: Generated story file content
def generate_chromatic_config(project_info: dict) -> str
def generate_storybook_config(existing_config: dict) -> str
def generate_package_scripts(existing_scripts: dict) -> dict
def generate_percy_config(project_info: dict) -> str # Percy alternative
def generate_backstop_config(project_info: dict) -> str # BackstopJS alternative
Returns: Configuration file contents as strings
def detect_ci_platform(project_root: str) -> str
def generate_github_workflow(project_info: dict) -> str
def generate_gitlab_ci(project_info: dict) -> str
def generate_circleci_config(project_info: dict) -> str
Returns: CI workflow file contents
User: "Set up visual regression for ProfileCard component"
→ Detects: React, existing Storybook, no VR tool
→ Generates: ProfileCard.stories.tsx with 4 variants
→ Creates: Chromatic config, GitHub workflow
→ Outputs: Setup instructions
See: examples/simple-component-vr.md
User: "Set up visual regression for entire design system"
→ Detects: React, Storybook, components in src/components/
→ Generates: Stories for all components (Button, Input, Card, etc.)
→ Creates: Chromatic config with design token validation
→ Outputs: Bulk setup instructions
See: examples/design-system-vr.md
User: "Add Chromatic to existing Storybook"
→ Detects: Storybook v7, existing stories
→ Adds: @chromatic-com/storybook addon
→ Creates: Chromatic config, CI workflow
→ Preserves: Existing stories and configuration
See: examples/existing-storybook-vr.md
After product-design generates implementation plan, suggest visual regression:
"Implementation plan created! Consider setting up visual regression testing:
'Set up visual regression for {ComponentName}'
This ensures pixel-perfect implementation and prevents visual drift."
Default: Chromatic (best Storybook integration)
Error: Component file not found at {path}
Please provide correct path:
"Set up visual regression for src/components/ProfileCard.tsx"
Storybook not detected. Install first:
npm install --save-dev @storybook/react @storybook/addon-essentials
npx storybook init
Then retry: "Set up visual regression for ProfileCard"
Multiple VR tools found: chromatic, percy
Which should I use?
- "Use Chromatic for visual regression"
- "Use Percy for visual regression"
Traditional approach (50k tokens):
With visual-regression skill (3k tokens):
Savings: 94% (47k tokens)
Last Updated: 2025-10-21 Skill Type: Project-specific Generator: nav-skill-creator (self-improving)
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.