diff --git a/.claude/skills/d8d-dev/journey-mode.md b/.claude/skills/d8d-dev/journey-mode.md index 4f1b714..fa328d3 100644 --- a/.claude/skills/d8d-dev/journey-mode.md +++ b/.claude/skills/d8d-dev/journey-mode.md @@ -378,7 +378,111 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这 - 修复后重测:重新 browser_take_screenshot + analyze_image 确认问题已修复 - 修复失败 → 标记 journey-step-fail → 继续下一步骤 - 步骤 4(修复阶段)仅处理功能断言 FAIL,不处理视觉验证 FAIL - f. 如涉及数据变化 → browser_evaluate 或 curl 验证数据(✅ 允许 curl 补充) + + 6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态) + 目的: 捕获并验证操作时才会出现的视觉状态(hover、选中、弹窗、展开、加载中、错误提示等),这些状态在静态原型对比中无法覆盖 + + 触发条件(满足任一即执行): + - 当前步骤操作后出现了弹窗/Modal/对话框 + - 下拉菜单/Select/日期选择器展开 + - 按钮/卡片/列表项处于 Hover/Active 状态 + - 表单字段获得 Focus/有验证错误提示 + - 页面显示 Loading/Skeleton/进度条 + - 列表项被选中/高亮/勾选 + - 页面切换/跳转后的首屏渲染完成 + - 出现了错误提示/Toast/Notification + - 折叠面板展开/收起状态变化 + + 执行流程: + a. 等待状态稳定(动画/过渡完成): + - browser_wait_for → time=1-2s(等待动画完成) + + b. 捕获实际状态截图: + - browser_take_screenshot → 保存为 journey-epic{N}-{M}-step{S}-state.png + + c. 搜索匹配的设计帧(双模式支持): + **Pencil MCP 模式(优先)**: + - 读取 pipeline-context.md 获取设计文件路径(如 VividSpark1.2.pen) + - mcp__pencil__batch_get → 搜索与当前状态匹配的帧 + - 搜索关键词: "{Page}-{State}" 如 "Dashboard-Modal", "Login-Error", "Upload-Loading" + - 或按 frame 类型和名称模式匹配 + - 如找到匹配帧 → mcp__pencil__export_nodes 导出设计截图 + + **HTML 原型模式(回退)**: + - 检查 prototype/pages/{group}/{page}-{state}.html 是否存在 + - 如存在 → 启动原型服务 → Playwright 截图 + + 设计帧未找到处理: + - 标记 prototype_found: false + - 记录 actual_screenshot 路径 + - 不阻断旅程,但记录到 pipeline-report.md 建议补充设计帧 + + d. 执行视觉对比(如找到设计帧): + - ui_diff_check: + - expected_image_source: 设计帧截图(或原型截图) + - actual_image_source: 当前状态截图 (journey-epic{N}-{M}-step{S}-state.png) + - prompt: "对比设计原型和实际实现。这是用户操作后出现的动态交互状态(如弹窗、hover、选中、加载中、错误提示等)。 + + 重点关注: + 1) 组件布局和结构是否一致(弹窗位置、按钮排列等) + 2) 颜色/样式是否匹配(背景色、边框、阴影等) + 3) 文字内容是否正确(标题、提示信息、按钮文字等) + 4) 交互状态是否准确(hover 效果、选中状态、focus 样式等) + 5) 图标和装饰元素是否一致 + + 注意:忽略动态数据(如用户名、时间戳等),只关注 UI 结构和样式。 + + 按严重程度列出所有视觉差异:" + + e. 差异分级与处理: + 记录到 pipeline-state.yaml: + ```yaml + journey_state_visual_diff: + epic_6: + journey_1: + step_3: + state_type: "modal_open" # 状态类型: modal_open/hover/select_focus/loading/error/etc + prototype_found: true # 是否找到对应设计帧 + prototype_source: "VividSpark1.2.pen:frame-456" # 设计来源 + prototype_frame_id: "frame-456" + diff_check_executed: true + severity: "moderate" # critical/moderate/minor/none + differences: + - type: "color" + severity: "minor" + description: "弹窗背景色不一致:设计 #1A1A1A,实际 #222222" + location: "弹窗背景" + - type: "spacing" + severity: "moderate" + description: "按钮间距偏差 8px,设计 16px,实际 24px" + location: "底部按钮组" + - type: "text" + severity: "critical" + description: "按钮文字错误:设计'确认',实际'提交'" + location: "主按钮" + screenshot_expected: "tests/e2e/screenshots/journey-epic6-1-step3-design.png" # 设计帧截图 + screenshot_actual: "tests/e2e/screenshots/journey-epic6-1-step3-state.png" # 实际状态截图 + auto_fix_triggered: true # 是否触发自动修复 + auto_fix_type: "AUTO-FIX" # 修复类型 + auto_fix_result: "PASS" # 修复结果 + ``` + + 差异处理规则: + - 🔴 严重差异(布局错误、关键组件缺失、文字错误)→ 立即触发 AUTO-FIX + - 🟡 中等差异(颜色、间距偏差)→ 记录到 pipeline-report.md,建议修复 + - 🟢 轻微差异(微小像素偏移)→ 记录但不阻断旅程 + - ✅ 无差异 → 标记状态正常 + + f. 自动修复与重测(如触发): + - AUTO-FIX 触发后: + 1. 定位相关源码文件(根据差异类型确定) + 2. 执行修复(如调整 CSS、修改组件样式等) + 3. 重新截图: browser_take_screenshot + 4. 重新对比: ui_diff_check + 5. 修复成功 → 标记 auto_fix_result: "PASS" + 6. 修复失败 → 标记 auto_fix_result: "FAIL",记录原因 + + 6. ⛔ **源码 SVG data URI 扫描**(视觉验证关卡内 — 每次 snapshot 后强制执行): g. ⛔ **约束一致性检查**(每个用户步骤首次执行时 — R7 执行时强制检测): 触发条件(操作被拦截 + 声明方说"可选"): - 操作后 Toast 出现且含"请上传/请填写/请选择/不能为空/不能为空" diff --git a/.claude/skills/d8d-dev/visual-diff-mode-pencil.md b/.claude/skills/d8d-dev/visual-diff-mode-pencil.md new file mode 100644 index 0000000..72d82d6 --- /dev/null +++ b/.claude/skills/d8d-dev/visual-diff-mode-pencil.md @@ -0,0 +1,234 @@ +# 原型对比验证模式 - Pencil MCP 直接对比版 + +> **定位**:使用 Pencil MCP 工具直接从 `.pen` 设计文件提取截图,与实际页面实现做逐页视觉对比。 +> +> **与 HTML 原型版对比**: +> | 维度 | Pencil MCP 直接版 | HTML 原型版 | +> |------|------------------|-------------| +> | 来源 | `.pen` 设计源文件 | `prototype/pages/*.html` | +> | 保真度 | 100% 设计稿像素级 | 可能有 HTML/CSS 转换损耗 | +> | 依赖 | Pencil MCP Server | Node.js + Express | +> | 启动 | 无需额外服务 | 需启动 `prototype/server.js` | + +--- + +## 前置条件 + +``` +检查清单(任一不满足 → 报错并终止): +├── .pen 设计文件存在(如 VividSpark1.2.pen) +├── Pencil MCP Server 可用(`pencil` 工具集) +├── pipeline-context.md 存在(含实际应用 URL 和凭据) +├── pm2 服务运行中(实际应用可访问) +└── 至少有一个 Epic 的 Story 已 verified +``` + +--- + +## 核心流程 + +``` +Phase PVD-0: 准备 + ├── 读取 .pen 文件 → 使用 Pencil MCP 发现设计页面 + ├── 读取 pipeline-context.md → 获取实际应用 URL + ├── 构建页面映射表(设计帧 ↔ 实际路由) + └── 创建截图输出目录 + +Phase PVD-1: 逐页对比循环 + 对每个映射页面: + ├── A. Pencil MCP 导出设计帧截图 + ├── B. Playwright 截取实际页面 + ├── C. UI 差异对比(ui_diff_check) + └── D. 差异分级 + 记录 + +Phase PVD-2: 汇总报告 + ├── 生成 visual-diff-pencil-report.md + └── 输出差异统计和修复建议 +``` + +--- + +## Phase PVD-0: 准备 + +### 0.1 使用 Pencil MCP 发现设计页面 + +``` +工具: mcp__pencil__batch_get +参数: + - filePath: "VividSpark1.2.pen" + - patterns: [{"type": "frame"}] # 查找所有帧/页面 + - searchDepth: 2 +``` + +从返回结果中提取所有设计帧: +- 帧名称(如 "Login", "Dashboard") +- 帧 ID(如 "node-123", "frame-456") +- 帧尺寸(width, height) + +分类为 frontend 和 admin 组: +- 帧名称含 "admin"、"Admin" → admin 组 +- 其他 → frontend 组 + +### 0.2 读取实际应用信息 + +同 HTML 原型版,读取 `_bmad-output/implementation-artifacts/pipeline-context.md` 获取: +- 实际应用 URL(API_URL, ADMIN_URL) +- 认证凭据 +- 已实现的路由 + +### 0.3 构建页面映射表 + +**自动映射规则**: + +``` +对每个设计帧(从 Pencil MCP 获取): + 1. 提取帧名称(如 "Login", "Dashboard") + 2. 在实际路由中查找匹配: + - 帧名=Login → /login 或 /admin/login + - 帧名=Dashboard → / 或 /dashboard + - 帧名=Register → /register + - 其他 → /{帧名小写} 或 /admin/{帧名小写} + 3. 验证实际路由可访问(curl 检查非 404) + 4. 不可访问的页面标记为 skipped +``` + +**映射输出格式**(记录到 pipeline-state.yaml): + +```yaml +visual_diff_pencil_mapping: + - design_frame: "Login" + design_frame_id: "node-123" + actual_route: "/login" + group: "frontend" + status: "active" # active / skipped / error + + - design_frame: "Dashboard" + design_frame_id: "node-456" + actual_route: "/" + group: "frontend" + status: "active" +``` + +### 0.4 创建截图输出目录 + +```bash +mkdir -p tests/e2e/screenshots/visual-diff-pencil +``` + +--- + +## Phase PVD-1: 逐页对比循环 + +对映射表中每个 `status: active` 的页面执行以下流程。 + +### 1.A Pencil MCP 导出设计帧截图 + +``` +工具: mcp__pencil__export_nodes +参数: + - filePath: "VividSpark1.2.pen" + - nodeIds: ["{design_frame_id}"] # 从映射表获取 + - outputDir: "tests/e2e/screenshots/visual-diff-pencil" + - format: "png" + - scale: 2 # 2x 高清 +``` + +导出后的文件路径: +- `tests/e2e/screenshots/visual-diff-pencil/{design_frame_id}.png` + +重命名为可读名称: +- `tests/e2e/screenshots/visual-diff-pencil/{name}-design.png` + +### 1.B 截取实际页面截图 + +同 HTML 原型版,使用 Playwright: + +``` +1. browser_navigate → {实际 URL}{route} +2. browser_resize → 1440x900(与设计帧尺寸匹配) +3. 处理认证(如需要) +4. browser_wait_for → time=3 +5. browser_take_screenshot(fullPage=false) + → tests/e2e/screenshots/visual-diff-pencil/{name}-actual.png +``` + +### 1.C UI 差异对比 + +``` +工具: ui_diff_check +参数: + - expected_image_source: "tests/e2e/screenshots/visual-diff-pencil/{name}-design.png" + - actual_image_source: "tests/e2e/screenshots/visual-diff-pencil/{name}-actual.png" + - prompt: "对比这两张截图:第一张是 Pencil 设计稿,第二张是实际实现。列出所有视觉差异,包括布局结构、组件排列、颜色、间距、字体、图标等。按严重程度排序。" +``` + +### 1.D 差异分级 + +同 HTML 原型版: + +| 级别 | 标准 | 示例 | +|------|------|------| +| 🔴 严重 | 布局结构不同、关键组件缺失 | 原型有两列布局实际一列 | +| 🟡 中等 | 颜色/间距偏差、图标不一致 | 卡片圆角不一致 | +| 🟢 轻微 | 微小像素差异 | 1-2px 偏移 | + +--- + +## Phase PVD-2: 汇总报告 + +### 2.1 生成报告 + +生成 `tests/e2e/screenshots/visual-diff-pencil/visual-diff-pencil-report.md`: + +```markdown +# Visual Diff Report (Pencil MCP Direct) + +生成时间: {timestamp} +对比页面数: {total_pages} +数据来源: VividSpark1.2.pen (Pencil MCP 直接导出) + +## Summary + +| 级别 | 数量 | +|------|------| +| 🔴 严重 | {critical_count} | +| 🟡 中等 | {moderate_count} | +| 🟢 轻微 | {minor_count} | +| ✅ 匹配 | {match_count} | + +## 详细对比结果 + +### 🔴 {page_name} +- 设计截图: `visual-diff-pencil/{name}-design.png` +- 实际截图: `visual-diff-pencil/{name}-actual.png` +- 差异描述... + +... +``` + +### 2.2 更新 pipeline-state.yaml + +```yaml +visual_diff_pencil: + status: completed + total_pages: 11 + compared_pages: 11 + critical_count: 0 + moderate_count: 3 + minor_count: 5 + match_count: 3 + report_path: "tests/e2e/screenshots/visual-diff-pencil/visual-diff-pencil-report.md" + timestamp: "2026-04-08T12:00:00Z" +``` + +--- + +## 附录:与 HTML 原型版对比速查 + +| 步骤 | Pencil MCP 直接版 | HTML 原型版 | +|------|------------------|-------------| +| 原型来源 | `.pen` 文件 | `prototype/pages/*.html` | +| 截图工具 | `mcp__pencil__export_nodes` | Playwright 访问 `localhost:8080` | +| 保真度 | 100% 设计稿 | 可能有转换损耗 | +| 启动依赖 | 无 | 需启动 `prototype/server.js` | +| 推荐场景 | 有 `.pen` 文件时首选 | 无 `.pen` 或需 HTML 交互时 | diff --git a/.claude/skills/d8d-dev/visual-diff-mode.md b/.claude/skills/d8d-dev/visual-diff-mode.md index f46f45b..76efcea 100644 --- a/.claude/skills/d8d-dev/visual-diff-mode.md +++ b/.claude/skills/d8d-dev/visual-diff-mode.md @@ -1,6 +1,14 @@ # 原型对比验证模式(Visual Diff Mode) -> **定位**:在回归验证和旅程验证之后,将实际页面实现与原型 HTML 页面做逐页视觉对比,发现布局偏差、组件遗漏、交互方式差异等视觉问题。 +> **定位**:在回归验证和旅程验证之后,将实际页面实现与原型做逐页视觉对比,发现布局偏差、组件遗漏、交互方式差异等视觉问题。 +> +> **两种对比方式**(任选其一): +> | 方式 | 来源 | 适用场景 | +> |------|------|---------| +> | **Pencil MCP 直接版**(推荐) | `.pen` 设计源文件 | 有 `.pen` 文件时首选,100% 设计稿保真度 | +> | **HTML 原型版** | `prototype/pages/*.html` | 无 `.pen` 文件或需要 HTML 交互时 | +> +> Pencil MCP 直接版文档:**[visual-diff-mode-pencil.md](./visual-diff-mode-pencil.md)** > > **与其他模式的关系**: > - 回归验证模式 → 检查功能点存在且正确(类比单元测试) diff --git a/.claude/skills/d8d-dev/workflow.md b/.claude/skills/d8d-dev/workflow.md index 3299c91..0b258af 100644 --- a/.claude/skills/d8d-dev/workflow.md +++ b/.claude/skills/d8d-dev/workflow.md @@ -87,7 +87,14 @@ | **单 Epic 模式** | 执行指定 Epic 的所有 Story | 按模块开发 | | **回归验证模式** | 不做实现,逐 Story 验证功能点存在且正确 | 代码已实现需回归验证(类比:单元测试) | | **旅程验证模式** | 专用用户旅程定义+验证(跨页面完整流程) | 跨 Story/Epic 的用户体验验证(类比:E2E 测试) | -| **原型对比验证模式** | 截取原型和实际页面截图,使用 ui_diff_check + analyze_image 对比差异 | Epic 完成后的视觉还原度检查(类比:视觉回归测试) | +| **原型对比验证模式** | 截取原型和实际页面截图,使用 ui_diff_check 对比差异 | Epic 完成后的视觉还原度检查(类比:视觉回归测试) | + +### 原型对比验证子模式 + +| 子模式 | 原型来源 | 推荐场景 | +|--------|---------|---------| +| **Pencil MCP 直接版**(优先) | `.pen` 设计文件(如 VividSpark1.2.pen) | 有 .pen 文件时首选,100% 设计稿保真度 | +| **HTML 原型版** | `prototype/pages/*.html` | 无 .pen 文件或需要 HTML 交互时 | ## 模式选择与流转 @@ -183,9 +190,18 @@ Read fully and follow: ./journey-mode.md ### 原型对比验证模式 ``` -Read fully and follow: ./visual-diff-mode.md +自动检测并选择: +├── 存在 .pen 设计文件(如 VividSpark1.2.pen) +│ └── Read fully and follow: ./visual-diff-mode-pencil.md # Pencil MCP 直接版 +│ +└── 不存在 .pen 文件,但存在 prototype/pages/*.html + └── Read fully and follow: ./visual-diff-mode.md # HTML 原型版 ``` +**手动指定子模式**: +- `/d8d-dev visual-diff --pencil` → 强制使用 Pencil MCP 直接版 +- `/d8d-dev visual-diff --html` → 强制使用 HTML 原型版 + ### 仅测试模式 / 仅审查模式 直接读取对应 Story 的 phase-04-test.md 或 phase-05-review.md 中的相关部分。