From 9ff878eae23df2c110e7cda64e8e1cdb3b9c2d7f Mon Sep 17 00:00:00 2001 From: zyh Date: Sun, 19 Apr 2026 12:26:55 +0000 Subject: [PATCH] =?UTF-8?q?sync:=20=E6=96=B0=E5=A2=9E=20uni-app=20?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E8=AF=86=E5=88=AB=E3=80=81Playwright=20?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E9=87=8D=E8=AF=95=E3=80=81=E5=B7=B2=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=A0=87=E8=AE=B0=E4=B8=8D=E5=8F=AF=E4=BF=A1=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更内容: - journey-definition.md: 新增 @tap/@click/bindtap 交互识别 + uni-app 跳转识别 - journey-execution.md: 新增 Playwright 崩溃检测与恢复流程(auto-retry max 3x) - auto-fix-engine.md: 新增 FAIL#22 Playwright崩溃 + "已修复标记不可信"规则 + AUTO-RETRY 流程 - iron-laws.md: 新增 3 条检测即阻断规则(崩溃跳过/标记盲信/uni-app漏识别) - journey-authenticity-rules.md: 新增 uni-app 页面路由提取和事件绑定统计指引 --- .../modes/journey/journey-definition.md | 4 +- .../modes/journey/journey-execution.md | 9 ++++ .../skills/d8d-dev/rules/auto-fix-engine.md | 50 +++++++++++++++++++ .claude/skills/d8d-dev/rules/iron-laws.md | 3 ++ .../rules/journey-authenticity-rules.md | 10 +++- 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/.claude/skills/d8d-dev/modes/journey/journey-definition.md b/.claude/skills/d8d-dev/modes/journey/journey-definition.md index 80e9508..133d786 100644 --- a/.claude/skills/d8d-dev/modes/journey/journey-definition.md +++ b/.claude/skills/d8d-dev/modes/journey/journey-definition.md @@ -41,13 +41,15 @@ - 从 src/app/ 目录结构提取独立页面路由 b. 对每个主要视图,读取对应组件源码,提取所有用户交互元素: - - 按钮: onClick / handleClick / button 元素 + - 按钮: onClick / handleClick / button / @tap / @click 元素 + ⚠️ uni-app: @tap / @click / bindtap(注意 uni-app 编译后 @tap 和 @click 都生效) - 输入框: input / textarea / type="text" - 下拉选择: select / dropdown / combobox / Select 组件 - 筛选器/过滤器: filter / 筛选 - 分页控件: page / pagination / nextPage / setPage - 导出/下载: export / download / csv / excel - 对话框/弹窗: dialog / modal / open / close + - ⚠️ uni-app 特有:navigateTo / redirectTo / switchTab(页面跳转类交互) c. 比对交互元素 vs 所有旅程的技术验证步骤: - 每个交互元素必须被至少 1 条旅程的某个步骤覆盖 diff --git a/.claude/skills/d8d-dev/modes/journey/journey-execution.md b/.claude/skills/d8d-dev/modes/journey/journey-execution.md index 9691fe7..32666fe 100644 --- a/.claude/skills/d8d-dev/modes/journey/journey-execution.md +++ b/.claude/skills/d8d-dev/modes/journey/journey-execution.md @@ -258,6 +258,15 @@ curl 只用于补充数据验证(如确认数据库状态),**永远不能 - 修复失败 → 标记 journey-step-fail → 继续下一步骤 - 步骤 4(修复阶段)仅处理功能断言 FAIL,不处理视觉验证 FAIL f. 如涉及数据变化 → browser_evaluate 或 curl 验证数据(✅ 允许 curl 补充) + g. ⛔ **Playwright 崩溃检测与恢复**(每个 browser_* 操作步骤后检查) + - 如果 browser_* 操作返回超时/错误/无响应: + 1. ⛔ 禁止标记 PARTIAL PASS 跳过 + 2. 等待 10 秒(browser_wait_for → time=10) + 3. 重新 browser_navigate 到当前页面 URL + 4. 从当前步骤重新执行(不从头开始) + 5. 重试计数 +1(最大 3 次) + 6. 3 次仍崩溃 → 标记 journey-step-crash → 记录详细错误 → 继续下一步骤 + - ⚠️ 注意: 业务逻辑错误(Toast/400/500)不属于崩溃,走正常 FAIL 分类 6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态) 目的: 捕获并验证操作时才会出现的视觉状态(hover、选中、弹窗、展开、加载中、错误提示等),这些状态在静态原型对比中无法覆盖 diff --git a/.claude/skills/d8d-dev/rules/auto-fix-engine.md b/.claude/skills/d8d-dev/rules/auto-fix-engine.md index c1a7e3f..3dd5dca 100644 --- a/.claude/skills/d8d-dev/rules/auto-fix-engine.md +++ b/.claude/skills/d8d-dev/rules/auto-fix-engine.md @@ -50,6 +50,7 @@ | 19 | Tab 页面下拉刷新方式不一致(scroll-view refresher / onPullDownRefresh / 无 混用),或使用列表级 scroll-view refresher | Bug(UX 不一致) | AUTO-FIX | 首页用 scroll-view refresher,其他 Tab 无刷新,参见 ../reference/platform-uni-app.md §7 | | 20 | API route handler 无 try-catch 包裹,导致未处理异常直接返回原始 500 且无日志 | Bug(健壮性) | AUTO-FIX | Admin 提现审批 PUT 返回 500 但状态仍更新(异常被吞) | | 21 | uni-app 页面使用 `onMounted` 获取数据,但该页面是 `uni.navigateBack()` 的返回目标,导致回退时数据不刷新 | Bug(数据陈旧) | AUTO-FIX | 提现后返回收益页余额未刷新(onMounted 不再触发) | +| 22 | Playwright MCP 浏览器崩溃/超时(browser_snapshot/browser_click 等操作返回错误或无响应)| 环境问题 | AUTO-RETRY | 浏览器进程崩溃、MCP 连接超时、页面 unresponsive | | **99** | **以上都不匹配的任何 FAIL** | **默认: Bug** | **AUTO-FIX** | **兜底规则,确保无遗漏** | | **V1** | 页面主题/配色与原型不一致(深色→浅色、主色调偏差) | 视觉差异 | VISUAL-FIX | 原型深色主题但实际浅色;按钮颜色不一致 | | **V2** | 页面布局结构与原型不同(顶部导航↔侧边栏、网格↔列表、卡片↔表格) | 视觉差异 | VISUAL-FIX | 原型顶部水平导航但实际左侧边栏;原型卡片网格但实际列表 | @@ -68,6 +69,26 @@ **核心原则**: "已知" ≠ "已修复"。任何在之前的验证轮次中被发现但未实际修复的问题,在后续轮次再次检测到时,**必须**立即触发修复,不得以任何理由跳过。 +### ⛔ "已修复标记不可信"规则(⛔ 强制 — 交互缺陷审计表专用) + +**核心原则**: 旅程文件中交互缺陷审计表的"✅ 已修复"标记**不等同于实际验证通过**。 + +1. 验证执行时遇到"✅ 已修复"的缺陷,**必须重新验证该修复是否正确**: + - 读取标记对应的源码文件,确认修复代码存在 + - 如果涉及跳转:验证跳转目标是否正确(不只是"有 handler") + - 如果涉及数据:验证数据流是否正确(不只是"不报错") + +2. **禁止行为**: + - ❌ 看到"✅ 已修复"就跳过该交互元素的验证 + - ❌ 以"上次已修复"为由跳过实际 UI 交互测试 + - ❌ 仅检查 handler 是否存在而不验证 handler 的行为是否正确 + +3. **典型案例(V19 漏检教训)**: + - 审计标记:"报名派对按钮 | 无 handler | ✅ 已修复" + - 实际修复:添加了 handleSignUp 函数 + - 但修复错误:用了 `event-detail` 而非 `venue-detail`(venue.id ≠ event.id) + - 验证 agent 信任"已修复"标记 → 漏检错误修复 + **判定流程**: ``` 检测到 FAIL → 查分类表确定修复类型 @@ -246,6 +267,35 @@ - 后端路由缺失 → `Write` 新 `route.ts` + `handler` - 图标方案未实施 → 按方案安装 Tailwind + Iconify +### AUTO-RETRY(Playwright 崩溃专用,max 3 次) + +**适用**: Playwright MCP 浏览器崩溃、超时、无响应(FAIL #22) + +**流程**: +``` +Playwright 操作返回错误/超时: + ↓ +1. 诊断: 确认是 MCP 超时/浏览器崩溃(而非业务逻辑错误) + - 特征: browser_snapshot/browser_click 返回 "timeout" / "disconnected" / 无响应 + - 非特征: 页面显示业务错误(404/500/Toast)→ 走正常 FAIL 分类 + ↓ +2. 恢复: 等待 10 秒 → 重新 browser_navigate 到当前页面 + ↓ +3. 重试: 从崩溃的步骤重新执行(不从头开始) + - 读取 verification-checklist.yaml 找到当前步骤 + - 重试当前步骤(max 3x) + ↓ +4. 重试耗尽: 仍崩溃 → 标记 journey-step-crash + 记录 crash_log + - ⛔ 禁止标记 PARTIAL PASS 跳过 + - 必须记录崩溃的具体错误信息 +``` + +**⛔ 禁止行为**: +- ❌ Playwright 崩溃后标记 PARTIAL PASS 跳过 UI 验证 +- ❌ 以"浏览器环境不稳定"为由跳过交互验证 +- ❌ 不重试直接标记 crash 并继续 +- ❌ 将业务逻辑错误(Toast/400/500)误分类为 Playwright 崩溃 + **Emoji → Iconify 替换方案(检测到 emoji 充当功能图标时使用 ⛔ 强制)**: ⛔ **完整安装配置、使用方式、禁止方案列表见 ../reference/platform-uni-app.md 第 1 节。禁止自行发明替代方案。** diff --git a/.claude/skills/d8d-dev/rules/iron-laws.md b/.claude/skills/d8d-dev/rules/iron-laws.md index 9ef9600..39df46e 100644 --- a/.claude/skills/d8d-dev/rules/iron-laws.md +++ b/.claude/skills/d8d-dev/rules/iron-laws.md @@ -243,6 +243,9 @@ Epic N+1 完成 | 交互元素状态未变化 | browser_click 点击 checkbox/radio/toggle 后 browser_snapshot 确认 checked/selected 状态未改变 | Bug(#22) | AUTO-FIX: 修复事件绑定或状态更新逻辑 | | 按钮永久 disabled | 旅程定义中要求点击的按钮(如 Next/Submit/Publish)处于 disabled 状态且无法通过前置操作解除 | Bug(#23) | AUTO-FIX: 修复 disabled 条件或连接正确的状态源 | | API 成功但 UI 未更新 | curl/API 返回成功但 browser_snapshot + browser_take_screenshot 确认界面无变化(如封面预览未刷新、列表未新增) | Bug(#24) | AUTO-FIX: 添加 refetch/状态同步/乐观更新 | +| Playwright 崩溃直接跳过 | browser_* 操作返回错误/超时后,标记 PARTIAL PASS 而不重试 | 环境问题(#22) | AUTO-RETRY: 等待10秒+重启浏览器+重试当前步骤(max 3x) | +| 已修复标记盲信 | 旅程文件交互缺陷审计表标记"✅ 已修复",验证时不重新测试实际行为 | 漏检风险 | ⛔ 必须重新验证修复是否正确(不只是检查 handler 是否存在) | +| 漏识别 uni-app 交互 | 交互元素识别只覆盖 React(onClick)不覆盖 uni-app(@tap) | 覆盖漏洞 | 交互元素识别必须同时支持 onClick + @tap/@click/bindtap | > 完整的 FAIL 分类标准(含兜底规则 #99)和修复流程见 ./auto-fix-engine.md 第 2-4 节 diff --git a/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md b/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md index 213dbfc..e1bc680 100644 --- a/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md +++ b/.claude/skills/d8d-dev/rules/journey-authenticity-rules.md @@ -382,16 +382,24 @@ A 和 B 均不满足 → 普通 FAIL #12 (ENV-ADAPT) → 按提示补填继续 1. 从 app-client.tsx 或路由配置提取所有独立视图: grep -n "currentView\|view ===\|render.*View\|component" src/components/features/app-client.tsx + ⚠️ uni-app 小程序项目:从 pages.json 提取所有页面路由 + grep -n '"path"' app/mini-program/src/pages.json + 2. 对每个视图组件,统计用户交互元素: grep -c "onClick\|handleClick\|onChange\|handleSelect\|onSubmit" src/components/features/{view-component}.tsx + ⚠️ uni-app 小程序页面:统计 @tap / @click 事件绑定 + grep -c "@tap\|@click\|@tap.stop\|@click.stop\|bindtap\|bind:tap" app/mini-program/src/pages/{page}/index.vue + 3. 具体分类: - - 按钮: onClick / handleClick / button + - 按钮: onClick / handleClick / button / @click / @tap + ⚠️ uni-app: @tap / @click / bindtap(注意 uni-app 编译后 @tap 和 @click 都生效) - 输入框: input / textarea / type="text" - 选择器: select / dropdown / combobox / Select - 分页: page / pagination / nextPage / setPage - 导出: export / download / csv / excel - 弹窗: dialog / modal / open / close + - ⚠️ uni-app 特有:navigateTo / redirectTo / switchTab(页面跳转类交互) ``` ### 检测方法