pin · git:20260914.f923583 · 2026-09-14 · sha256 69be5fb230fb36ed
pin git:20260914.f923583A
Immutable. This exact content is served forever at /api/v1/blob/69be5fb230fb36ed.
--- name: pin description: 用 Playwright 脚本把肉眼难确认的界面 bug(时序、偶发、多步交互)钉住:先复现、按复现率反复验证,再修应用代码,spec 留作回归 disable-model-invocation: true argument-hint: "<现象:哪个页面、做了什么、期望什么、实际怎样>" --- 把一个界面 bug 钉住再修。一眼能看出对错的问题(文案、样式)不用这个,直接改。 ## 前提 - 被测项目的 e2e 容器已按 `../e2e/references/runner.md` 搭好,`<exec>` 是 `e2e/profile.md` 里的执行前缀。没有 profile.md 时只填本次要用的执行前缀、入口、账号三项,其余写「待确认」。 - 宿主机不装任何 Playwright 组件,命令一律走 `<exec>`。 - 定位失败的顺序见 `../e2e/references/diagnose.md`,时序手段见 `../e2e/references/timing.md`。 ## 次数规则 复现率 p = 失败次数 ÷ 运行次数。依据:零失败 N 次只能说明失败率低于约 3/N(95% 置信,统计学三法则)。 | 阶段 | 跑几次 | |---|---| | 确认复现 | 先 1 次。失败就再跑 2 次,3 次都失败按「必现」处理(p = 1)。第 1 次通过就继续跑到出现失败,最多 30 次,据此估 p | | 调试中 | 必现 1 次;偶发 ⌈3/p⌉ 次 | | 确认修好 | 连续 max(3, ⌈3/p⌉) 次全部通过 | ⌈3/p⌉ 超过 30 时不硬跑,先用 `timing.md` 的手段把时序固定住、提高复现率。多次运行用 `--repeat-each=<N>`;含写操作时每次运行建的数据在 `afterEach` 里删。 ## 步骤 1. **写复现**:`e2e/tests/repro/<kebab-case 名>.spec.ts`,文件头 `// pin: <现象> <日期>`。断言写正确行为,不写现状。会建数据的,第一次运行前就写好 `afterEach` 删除。先 grep `e2e/tests/` 有没有同流程的 spec,有就在上面加用例。 2. **确认复现**:按次数规则跑。失败点必须就是这个现象,按 `diagnose.md` 确认;选择器写错、账号登不上导致的失败不算,改测试直到失败原因对上。**复现出红之前不读应用代码猜原因。** 30 次都没失败、固定时序后仍复现不出:停下,列出试过的写法,向我要能复现的环境、录屏或 HAR。 3. **缩到最少**:先把当前 spec 另存为同目录 `<名>.original.spec.ts`。再从 spec 里一次删一个步骤或一项前置数据,按次数规则重跑,删掉后不再失败的留下,直到剩下的每一步都不可少。 4. **列假设**:读应用代码前,先在回复里写出 3–5 个按可能性排序的原因假设,不等回复,按顺序往下验证;我插话就按我的调整。原因看起来再明显也要列,收尾时逐条写明证实还是排除。 5. **定位**:按 `diagnose.md` 查证假设,一次只改一个变量。往应用代码或 spec 里加的调试日志一律带同一个前缀 `[DEBUG-<4 位随机字符>]`。 6. **修应用代码**:修真正的原因。复现 spec 的断言和剩下的步骤是验收标准,要改断言、删步骤、加 `skip` / `fixme` 都先问我。role / 文本定位不了时可以给元素加 `data-testid`,收尾时列出来。同一个 bug 连续 3 次修复都没通过:停下,不再试第 4 个修法,把 3 次的假设、改动、结果列给我,一起重新看设计。 7. **确认修好**: - 复现 spec 按次数规则全部通过。 - `<名>.original.spec.ts` 跑 1 轮(次数同上)全部通过后删掉,只留缩减版。 - 相关回归:看应用代码的 `git diff`,用改动涉及的路由、页面、组件名、选择器 grep `e2e/tests/`,只跑命中的 spec 文件各 1 次;有失败紧接着用 `--last-failed` 复跑(记录每次运行都会覆盖,中间不要插别的运行)。 - 不跑全量。diff 改到公共组件、布局、路由、状态管理时,收尾提醒我考虑跑 `/flow:e2e run`。 8. **清理**:grep 前缀 `[DEBUG-` 把调试日志全部删掉,重跑一次复现 spec 确认仍通过。spec 留在 `e2e/tests/repro/`,以后 `/flow:e2e run` 会一起跑。 ## 不用 - `--only-changed`:`e2e/` 被 gitignore、应用代码也不在 spec 的 import 里,一个测试都选不中且不报错。 - `test.only`:容易漏在 spec 里。 - `page.waitForTimeout()`、`networkidle`、`sleep`。 ## 护栏 - 副作用分级同 `/flow:e2e`:1 只读 / 2 库内可逆 / 3 库内不可逆 / 4 出库外部。复现步骤含 2 级写操作先按画像备份,画像里没有备份命令就先问我;3 / 4 级先问我。 - 不 mock 外部网关。只用 Playwright 自带 chromium。 - 密码放 `e2e/.env`,spec 里用 `process.env.E2E_*`。 - 数据被弄乱需要还原时,先问我再跑恢复命令。 ## 收尾 只说三件事:复现情况(复现率、缩减后的步骤、各假设证实或排除)、改了哪些应用代码(含新加的 `data-testid`)、验证结果(复现 spec 跑了几次、相关回归跑了哪些文件、结果)。需要我拍板的放最后。