视觉回归测试设置技能
技能目的
生成完整的视觉回归测试设置,包括Storybook故事、配置文件和CI/CD工作流。
支持: Chromatic, Percy, BackstopJS 框架: React, Vue, Svelte (TypeScript/JavaScript) CI/CD: GitHub Actions, GitLab CI, CircleCI
这个技能做什么
- 检测现有设置: Storybook版本,VR工具,CI平台
- 验证组件: 提取props,变体,状态
- 生成故事: 完整的
.stories.tsx带有所有变体 - 创建配置文件: Chromatic, Percy或BackstopJS配置
- 设置CI/CD: 自动生成工作流文件
- 提供指导: API令牌,首次基线的下一步操作
工作流程
第1步: 验证项目设置
执行: vr_setup_validator.py
检查:
- 从package.json中检测框架(React/Vue/Svelte)
- 检测现有的Storybook配置(.storybook/目录)
- 检测现有的VR工具(依赖中的chromatic, percy, backstopjs)
- 检测CI平台(.github/, .gitlab-ci.yml, .circleci/)
- 组件文件存在且有效
输出:
{
"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"]
}
}
如果未发现Storybook: 询问用户是否需要先安装Storybook,提供安装指导。
如果发现多个VR工具: 询问用户使用哪一个(推荐Chromatic)。
第2步: 生成Storybook故事
执行: story_generator.py
流程:
- 解析组件文件(TypeScript/JSX/Vue SFC)
- 提取props,prop类型,默认值
- 识别变体(大小,变体,禁用等)
- 从模板生成故事文件
- 添加可访问性测试(@storybook/addon-a11y)
- 添加交互测试(如果@storybook/test可用)
模板: templates/story-template.tsx.j2
示例输出(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',
},
};
// 可访问性测试
Default.parameters = {
a11y: {
config: {
rules: [
{ id: 'color-contrast', enabled: true },
{ id: 'label', enabled: true },
],
},
},
};
写入: {component_directory}/{ComponentName}.stories.tsx
第3步: 生成配置文件
执行: chromatic_config_generator.py(或percy/backstop等效)
对于Chromatic:
生成3个文件:
- chromatic.config.json:
{
"projectId": "<PROJECT_ID_PLACEHOLDER>",
"buildScriptName": "build-storybook",
"exitZeroOnChanges": true,
"exitOnceUploaded": true,
"onlyChanged": true,
"externals": ["public/**"],
"skip": "dependabot/**",
"ignoreLastBuildOnBranch": "main"
}
- 更新.storybook/main.js(添加插件):
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@chromatic-com/storybook', // ← 添加的
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
};
- 更新package.json(添加脚本):
{
"scripts": {
"chromatic": "npx chromatic",
"chromatic:ci": "npx chromatic --exit-zero-on-changes"
}
}
对于Percy: 生成.percy.yml代替
对于BackstopJS: 生成backstop.config.js代替
第4步: 生成CI/CD工作流
执行: ci_workflow_generator.py
从现有文件中检测CI平台:
.github/workflows/→ GitHub Actions.gitlab-ci.yml→ GitLab CI.circleci/config.yml→ CircleCI- 无 → 询问用户,默认GitHub Actions
GitHub Actions示例:
生成: .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 # 为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
对于GitLab CI: 在.gitlab-ci.yml中添加作业
对于CircleCI: 在.circleci/config.yml中添加作业
第5步: 提供设置指导
输出给用户:
✅ 视觉回归测试设置完成!
## 文件创建/修改
✅ {ComponentName}.stories.tsx(带有变体的Storybook故事)
✅ chromatic.config.json(Chromatic配置)
✅ .storybook/main.js(添加@chromatic-com/storybook插件)
✅ package.json(添加chromatic脚本)
✅ .github/workflows/chromatic.yml(CI工作流)
## 后续步骤
### 1. 安装依赖
```bash
npm install --save-dev chromatic @chromatic-com/storybook
2. 创建Chromatic项目
- 访问 https://www.chromatic.com/start
- 使用GitHub登录
- 创建新项目
- 复制项目令牌
3. 添加GitHub密钥
- 访问仓库设置 → 密钥和变量 → Actions
- 创建密钥:
CHROMATIC_PROJECT_TOKEN - 粘贴你的项目令牌
4. 更新chromatic.config.json
将<PROJECT_ID_PLACEHOLDER>替换为Chromatic仪表板中的实际项目ID。
5. 创建基线
npm run chromatic
这将捕获初始截图作为你的基线。
6. 测试视觉回归
- 对ProfileCard进行视觉更改
- 提交并推送
- CI将自动运行Chromatic
- 在Chromatic仪表板中查看更改
文档
查看.agent/sops/testing/visual-regression-setup.md了解详细工作流程。
故障排除
Storybook构建失败: 确保所有组件依赖都已安装
Chromatic上传失败: 检查密钥中的项目令牌
未检测到更改: Chromatic仅在更改的故事上运行(使用--force-rebuild测试)
---
## 预定义函数参考
### vr_setup_validator.py
```python
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
返回: 验证报告,包含检测到的设置和缺失依赖
story_generator.py
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
返回: 生成的故事文件内容
chromatic_config_generator.py
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替代方案
def generate_backstop_config(project_info: dict) -> str # BackstopJS替代方案
返回: 配置文件内容字符串
ci_workflow_generator.py
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
返回: CI工作流文件内容
模板参考
- story-template.tsx.j2: React/TypeScript故事模板
- story-template.vue.j2: Vue SFC故事模板
- chromatic-config.json.j2: Chromatic配置
- percy-config.yml.j2: Percy配置
- github-workflow.yml.j2: GitHub Actions工作流
- gitlab-ci.yml.j2: GitLab CI作业
- storybook-main.js.j2: Storybook插件配置
示例
示例1: 简单组件
用户:“为ProfileCard组件设置视觉回归”
→ 检测到:React,现有的Storybook,没有VR工具
→ 生成:带有4个变体的ProfileCard.stories.tsx
→ 创建:Chromatic配置,GitHub工作流
→ 输出:设置指导
查看:examples/simple-component-vr.md
示例2: 完整设计系统
用户:“为整个设计系统设置视觉回归”
→ 检测到:React,Storybook,组件在src/components/
→ 生成:所有组件的故事(按钮,输入,卡片等)
→ 创建:带有设计令牌验证的Chromatic配置
→ 输出:批量设置指导
查看:examples/design-system-vr.md
示例3: 现有的Storybook
用户:“为现有的Storybook添加Chromatic”
→ 检测到:Storybook v7,现有故事
→ 添加:@chromatic-com/storybook插件
→ 创建:Chromatic配置,CI工作流
→ 保留:现有故事和配置
查看:examples/existing-storybook-vr.md
与product-design技能集成
在product-design生成实施计划后,建议设置视觉回归:
“实施计划已创建!考虑设置视觉回归测试:
'为{ComponentName}设置视觉回归'
这确保了像素完美的实现,并防止视觉漂移。”
工具比较
Chromatic(推荐)
- ✅ 专为Storybook设计
- ✅ 组件聚焦测试
- ✅ UI审核工作流
- ✅ 免费层:每月5,000个快照
- ❌ 需要云服务
Percy
- ✅ 多框架支持
- ✅ 响应测试
- ✅ 视觉审核
- ❌ 更贵
- ❌ 较少Storybook特定
BackstopJS
- ✅ 开源,自托管
- ✅ 无云依赖
- ✅ 免费
- ❌ 更多手动设置
- ❌ 较少自动化
默认: Chromatic(最佳Storybook集成)
错误处理
组件未找到
错误:在{path}未找到组件文件
请提供正确的路径:
“为src/components/ProfileCard.tsx设置视觉回归”
Storybook未安装
未检测到Storybook。先安装:
npm install --save-dev @storybook/react @storybook/addon-essentials
npx storybook init
然后重试:“为ProfileCard设置视觉回归”
检测到多个VR工具
发现多个VR工具:chromatic, percy
我应该使用哪一个?
- “使用Chromatic进行视觉回归”
- “使用Percy进行视觉回归”
最佳实践
- 从关键组件开始:不要测试所有内容,专注于设计系统原语
- 使用交互测试:结合视觉+功能测试
- 在main上设置基线:始终将基线合并到main分支
- 审核更改:不要自动接受视觉更改
- 测试状态:捕获悬停,焦点,错误状态
- 可访问性:在所有故事中包括a11y测试
令牌效率
传统方法(50k令牌):
- 阅读Storybook文档(20k)
- 阅读Chromatic文档(15k)
- 手动编写故事(10k)
- 配置CI(5k)
使用视觉回归技能(3k令牌):
- 技能自动调用(0令牌)
- 指导加载(3k令牌)
- 函数执行(0令牌)
节省:94%(47k令牌)
版本历史
- v3.3.0: 初始发布,支持Chromatic
- 未来: Percy, BackstopJS, Vue, Svelte支持
最后更新: 2025-10-21 技能类型: 项目特定 生成器: nav-skill-creator(自我改进)