// 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".
| name | visual-regression |
| description | 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". |
| allowed-tools | Read, Write, Bash, Glob |
| version | 1.0.0 |
| triggers | ["set up visual regression","add chromatic tests","create visual tests","configure visual regression","add screenshot testing","set up percy","add backstopjs"] |
Generate 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)