claude-coder 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -177
- package/bin/cli.js +172 -159
- package/package.json +52 -52
- package/src/commands/auth.js +240 -294
- package/src/commands/setup-modules/helpers.js +99 -105
- package/src/commands/setup-modules/index.js +25 -25
- package/src/commands/setup-modules/mcp.js +94 -94
- package/src/commands/setup-modules/provider.js +260 -260
- package/src/commands/setup-modules/safety.js +61 -61
- package/src/commands/setup-modules/simplify.js +52 -52
- package/src/commands/setup.js +172 -172
- package/src/common/assets.js +236 -192
- package/src/common/config.js +125 -138
- package/src/common/constants.js +55 -56
- package/src/common/indicator.js +222 -222
- package/src/common/interaction.js +170 -170
- package/src/common/logging.js +77 -76
- package/src/common/sdk.js +50 -50
- package/src/common/tasks.js +88 -157
- package/src/common/utils.js +161 -146
- package/src/core/coding.js +55 -55
- package/src/core/context.js +117 -132
- package/src/core/go.js +310 -0
- package/src/core/harness.js +484 -0
- package/src/core/hooks.js +533 -528
- package/src/core/init.js +171 -163
- package/src/core/plan.js +325 -318
- package/src/core/prompts.js +227 -253
- package/src/core/query.js +49 -47
- package/src/core/repair.js +46 -58
- package/src/core/runner.js +195 -352
- package/src/core/scan.js +89 -89
- package/src/core/{base.js → session.js} +56 -53
- package/src/core/simplify.js +52 -59
- package/templates/bash-process.md +12 -5
- package/templates/codingSystem.md +65 -0
- package/templates/codingUser.md +17 -31
- package/templates/coreProtocol.md +29 -0
- package/templates/goSystem.md +130 -0
- package/templates/guidance.json +52 -34
- package/templates/planSystem.md +78 -0
- package/templates/planUser.md +9 -0
- package/templates/playwright.md +16 -16
- package/templates/requirements.example.md +57 -56
- package/templates/scanSystem.md +120 -0
- package/templates/scanUser.md +10 -17
- package/templates/test_rule.md +194 -194
- package/src/core/validator.js +0 -138
- package/templates/addGuide.md +0 -98
- package/templates/addUser.md +0 -26
- package/templates/agentProtocol.md +0 -195
- package/templates/scanProtocol.md +0 -118
package/templates/test_rule.md
CHANGED
|
@@ -1,195 +1,195 @@
|
|
|
1
|
-
# Playwright 自动化测试通用规则 v0.0.1
|
|
2
|
-
|
|
3
|
-
## 一、四条铁律
|
|
4
|
-
|
|
5
|
-
1. **真实操作** — 必须通过 Playwright MCP 产生浏览器交互,代码审查不等于测试
|
|
6
|
-
2. **测试业务** — 断言基于用户可见结果(页面文本、按钮状态),非内部变量
|
|
7
|
-
3. **独立可重复** — 每个场景不依赖其他测试结果
|
|
8
|
-
4. **先调查再修复** — 失败先分析根因,不要修改测试让它通过
|
|
9
|
-
|
|
10
|
-
## 二、三步测试方法论
|
|
11
|
-
|
|
12
|
-
任何 Web 项目的端到端测试遵循三步走:
|
|
13
|
-
|
|
14
|
-
### Step 1: 功能验证(Happy Path)
|
|
15
|
-
|
|
16
|
-
核心用户流程能走通,每个步骤对应一个 Playwright MCP 工具调用:
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
1. browser_navigate → [页面URL]
|
|
20
|
-
2. browser_snapshot → 确认页面加载,定位关键元素 ref
|
|
21
|
-
3. browser_fill_form / browser_type → 输入测试数据
|
|
22
|
-
4. browser_click → 提交操作
|
|
23
|
-
5. browser_wait_for → 等待结果出现
|
|
24
|
-
6. browser_snapshot → 验证预期结果
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Step 2: 错误场景(Unhappy Path)
|
|
28
|
-
|
|
29
|
-
| 类别 | 典型场景 |
|
|
30
|
-
|------|---------|
|
|
31
|
-
| 输入验证 | 空提交、超长输入、特殊字符、非法格式 |
|
|
32
|
-
| 认证权限 | 未登录访问、过期凭证、无效 API Key |
|
|
33
|
-
| 网络服务 | 后端宕机、慢响应、API 500 |
|
|
34
|
-
| 状态边界 | 空数据、大数据量、重复提交、浏览器后退 |
|
|
35
|
-
|
|
36
|
-
### Step 3: 探索性测试
|
|
37
|
-
|
|
38
|
-
以目标用户角色自由使用系统,关注可发现性、可理解性、响应速度、错误恢复、视觉一致性。
|
|
39
|
-
|
|
40
|
-
## 三、Playwright MCP 工具速查
|
|
41
|
-
|
|
42
|
-
### 导航与观察
|
|
43
|
-
|
|
44
|
-
| 工具 | 用途 | 关键参数 |
|
|
45
|
-
|------|------|---------|
|
|
46
|
-
| `browser_navigate` | 打开页面 | `url` |
|
|
47
|
-
| `browser_snapshot` | 获取页面可访问性快照 | 无 |
|
|
48
|
-
| `browser_console_messages` | 检查控制台 | `level` |
|
|
49
|
-
| `browser_network_requests` | 网络请求日志 | 无 |
|
|
50
|
-
|
|
51
|
-
### 交互操作
|
|
52
|
-
|
|
53
|
-
| 工具 | 用途 | 关键参数 |
|
|
54
|
-
|------|------|---------|
|
|
55
|
-
| `browser_click` | 点击元素 | `ref`, `element` |
|
|
56
|
-
| `browser_type` | 逐字符输入 | `ref`, `text`, `submit` |
|
|
57
|
-
| `browser_fill_form` | 批量填写表单 | `fields[]` |
|
|
58
|
-
| `browser_select_option` | 选择下拉项 | `ref`, `values[]` |
|
|
59
|
-
| `browser_press_key` | 按键 | `key` |
|
|
60
|
-
| `browser_file_upload` | 上传文件 | `paths[]` |
|
|
61
|
-
| `browser_handle_dialog` | 处理弹窗 | `accept` |
|
|
62
|
-
|
|
63
|
-
### 等待与控制
|
|
64
|
-
|
|
65
|
-
| 工具 | 用途 | 关键参数 |
|
|
66
|
-
|------|------|---------|
|
|
67
|
-
| `browser_wait_for` | 等待元素/文本出现 | `text`, `ref`, `timeout` |
|
|
68
|
-
| `browser_evaluate` | 执行 JS | `function` |
|
|
69
|
-
| `browser_close` | 关闭页面 | 无 |
|
|
70
|
-
|
|
71
|
-
## 四、Smart Snapshot 策略(节省 40-60% Token)
|
|
72
|
-
|
|
73
|
-
每次 `browser_snapshot` 消耗 3,000-8,000 tokens。分级控制:
|
|
74
|
-
|
|
75
|
-
| 级别 | 何时 snapshot | 示例 |
|
|
76
|
-
|------|-------------|------|
|
|
77
|
-
| **必须** | 首次加载页面 | navigate 后确认页面正确 |
|
|
78
|
-
| **必须** | 关键断言点 | 验证操作结果出现 |
|
|
79
|
-
| **必须** | 操作失败时 | 调查页面状态 |
|
|
80
|
-
| **可选** | 中间操作后 | fill 后确认文字填入 |
|
|
81
|
-
| **跳过** | 连续同类操作间 | 连续选择多个下拉框 |
|
|
82
|
-
| **跳过** | 等待循环中 | 改用 `browser_wait_for` |
|
|
83
|
-
|
|
84
|
-
**高效模式**:navigate → snapshot → fill → select → click → wait_for → snapshot(**2 次**)
|
|
85
|
-
**低效模式**:navigate → snapshot → fill → snapshot → select → snapshot → click → snapshot(**4 次**)
|
|
86
|
-
|
|
87
|
-
## 五、等待策略
|
|
88
|
-
|
|
89
|
-
### 按操作类型选择
|
|
90
|
-
|
|
91
|
-
| 操作类型 | 策略 | Token 消耗 |
|
|
92
|
-
|---------|------|-----------|
|
|
93
|
-
| 瞬时(导航、点击) | 直接操作,不等待 | 极低 |
|
|
94
|
-
| 短等(表单提交) | `browser_wait_for text="成功" timeout=10000` | ~5K |
|
|
95
|
-
| 长等(AI 生成、文件处理) | `browser_wait_for` + 合理 timeout | ~5K |
|
|
96
|
-
| 超长等(批量处理) | Shell 端 API 检查 + 最终 1 次 snapshot | ~5.5K |
|
|
97
|
-
|
|
98
|
-
### SSE / 流式生成任务的等待策略
|
|
99
|
-
|
|
100
|
-
当操作涉及 AI 生成、文件转换、SSE 流式处理等需要较长时间的场景时,优先使用 `browser_wait_for` 而非轮询 snapshot:
|
|
101
|
-
|
|
102
|
-
| 步骤 | 工具 | 说明 |
|
|
103
|
-
|------|------|------|
|
|
104
|
-
| 触发操作 | `browser_click` | 点击"生成"/"提交"按钮 |
|
|
105
|
-
| 等待完成 | `browser_wait_for` | 等待完成标志文本出现,设置合理 timeout |
|
|
106
|
-
| 验证结果 | `browser_snapshot` | 确认结果/下载链接出现 |
|
|
107
|
-
|
|
108
|
-
**`browser_wait_for` 参数**:
|
|
109
|
-
- `text`:完成标志文本(如"下载"、"完成"、"预览")
|
|
110
|
-
- `timeout`:根据操作实际预估耗时设置(如表单提交 10s、AI 生成 60-180s、批量处理更长)
|
|
111
|
-
- 相比轮询 snapshot,Token 消耗从 ~60K+ 降至 ~5K
|
|
112
|
-
|
|
113
|
-
### 常见反模式
|
|
114
|
-
|
|
115
|
-
- 每步 snapshot → 合并 2-3 操作后再 snapshot
|
|
116
|
-
- 轮询 snapshot 等待长操作 → 改用 `browser_wait_for`
|
|
117
|
-
- MCP 做 20+ 步 → 长流程用 Playwright CLI
|
|
118
|
-
- 反复 navigate 同一页面 → 在同一页面完成
|
|
119
|
-
- 失败后盲目重试 → 先 `browser_console_messages` 分析
|
|
120
|
-
|
|
121
|
-
### 优先级映射
|
|
122
|
-
|
|
123
|
-
P0(核心流程)必测 → P1(错误处理)必测 → P2(次要功能)按需 → P3 低优先
|
|
124
|
-
|
|
125
|
-
预算 >200K: P0+P1+P2 | 100-200K: P0+P1 | <100K: 仅 P0
|
|
126
|
-
|
|
127
|
-
## 六、凭证管理
|
|
128
|
-
|
|
129
|
-
`.mcp.json` 由 `claude-coder auth` 自动生成,根据配置模式使用不同参数:
|
|
130
|
-
- persistent(默认):`--user-data-dir=<path>`,登录态自动保持
|
|
131
|
-
- isolated:`--isolated --storage-state=<path>`,每次从快照加载
|
|
132
|
-
- extension:`--extension`,连接真实浏览器
|
|
133
|
-
|
|
134
|
-
凭证失效时:不修改 auth 文件,报告中标注,提示用户运行 `claude-coder auth [URL]`。
|
|
135
|
-
|
|
136
|
-
## 七、失败处理
|
|
137
|
-
|
|
138
|
-
**阻断性**(立即停止): 服务未启动、500 错误、凭证缺失、页面空白
|
|
139
|
-
|
|
140
|
-
**非阻断性**(记录继续): 样式异常、console warning、慢响应
|
|
141
|
-
|
|
142
|
-
失败时: snapshot(记录状态)→ console_messages(错误日志)→ 停止该场景 → 继续下一个
|
|
143
|
-
|
|
144
|
-
## 八、tasks.json 测试步骤模板
|
|
145
|
-
|
|
146
|
-
推荐使用结构化标签前缀(`【规则】【环境】【P0】` 等)组织步骤。研究表明,结构化标记可提升 LLM 的指令遵循度和步骤完成率,帮助 Agent 理解每步的目的和优先级。
|
|
147
|
-
|
|
148
|
-
### 基础模板
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
{
|
|
152
|
-
"steps": [
|
|
153
|
-
"【规则】阅读 .claude-coder/test_rule.md",
|
|
154
|
-
"【环境】curl [后端]/health && curl [前端](失败则停止)",
|
|
155
|
-
"【P0】Playwright MCP 执行核心 Happy Path(Smart Snapshot)",
|
|
156
|
-
"【P1】错误场景:空输入、无效凭证",
|
|
157
|
-
"【记录】结果写入 record/",
|
|
158
|
-
"【预算】消耗 >80% 时跳过低优先级,记录 session_result.json"
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 含长等待操作的模板(SSE / AI 生成 / 文件转换)
|
|
164
|
-
|
|
165
|
-
```json
|
|
166
|
-
{
|
|
167
|
-
"steps": [
|
|
168
|
-
"【规则】阅读 .claude-coder/test_rule.md",
|
|
169
|
-
"【环境】curl http://localhost:8000/health 确认后端服务正常",
|
|
170
|
-
"【P0】Playwright MCP 访问目标页面,snapshot 确认页面加载",
|
|
171
|
-
"【P0】填写表单数据,snapshot 确认输入成功",
|
|
172
|
-
"【P0】点击提交,使用 browser_wait_for 等待结果出现(根据操作耗时设置合理 timeout)",
|
|
173
|
-
"【P0】验证结果正确(下载链接有效 / 预览内容匹配)",
|
|
174
|
-
"【记录】测试结果写入 record/(使用 test_rule.md 报告模板)",
|
|
175
|
-
"【预算】Smart Snapshot 策略:导航→填写→点击→等待→验证,共 3-4 次 snapshot"
|
|
176
|
-
]
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## 九、测试报告格式
|
|
181
|
-
|
|
182
|
-
```markdown
|
|
183
|
-
# E2E 测试报告
|
|
184
|
-
**日期**: YYYY-MM-DD | **环境**: 前端 [URL] / 后端 [URL]
|
|
185
|
-
|
|
186
|
-
| 场景 | 结果 | 备注 |
|
|
187
|
-
|------|------|------|
|
|
188
|
-
| [名称] | PASS/FAIL | [简要] |
|
|
189
|
-
|
|
190
|
-
## 发现的问题
|
|
191
|
-
### [P0/P1/P2] 标题
|
|
192
|
-
- **复现**: [Playwright 动作序列]
|
|
193
|
-
- **预期/实际**: ...
|
|
194
|
-
- **根因**: [代码分析]
|
|
1
|
+
# Playwright 自动化测试通用规则 v0.0.1
|
|
2
|
+
|
|
3
|
+
## 一、四条铁律
|
|
4
|
+
|
|
5
|
+
1. **真实操作** — 必须通过 Playwright MCP 产生浏览器交互,代码审查不等于测试
|
|
6
|
+
2. **测试业务** — 断言基于用户可见结果(页面文本、按钮状态),非内部变量
|
|
7
|
+
3. **独立可重复** — 每个场景不依赖其他测试结果
|
|
8
|
+
4. **先调查再修复** — 失败先分析根因,不要修改测试让它通过
|
|
9
|
+
|
|
10
|
+
## 二、三步测试方法论
|
|
11
|
+
|
|
12
|
+
任何 Web 项目的端到端测试遵循三步走:
|
|
13
|
+
|
|
14
|
+
### Step 1: 功能验证(Happy Path)
|
|
15
|
+
|
|
16
|
+
核心用户流程能走通,每个步骤对应一个 Playwright MCP 工具调用:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
1. browser_navigate → [页面URL]
|
|
20
|
+
2. browser_snapshot → 确认页面加载,定位关键元素 ref
|
|
21
|
+
3. browser_fill_form / browser_type → 输入测试数据
|
|
22
|
+
4. browser_click → 提交操作
|
|
23
|
+
5. browser_wait_for → 等待结果出现
|
|
24
|
+
6. browser_snapshot → 验证预期结果
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Step 2: 错误场景(Unhappy Path)
|
|
28
|
+
|
|
29
|
+
| 类别 | 典型场景 |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| 输入验证 | 空提交、超长输入、特殊字符、非法格式 |
|
|
32
|
+
| 认证权限 | 未登录访问、过期凭证、无效 API Key |
|
|
33
|
+
| 网络服务 | 后端宕机、慢响应、API 500 |
|
|
34
|
+
| 状态边界 | 空数据、大数据量、重复提交、浏览器后退 |
|
|
35
|
+
|
|
36
|
+
### Step 3: 探索性测试
|
|
37
|
+
|
|
38
|
+
以目标用户角色自由使用系统,关注可发现性、可理解性、响应速度、错误恢复、视觉一致性。
|
|
39
|
+
|
|
40
|
+
## 三、Playwright MCP 工具速查
|
|
41
|
+
|
|
42
|
+
### 导航与观察
|
|
43
|
+
|
|
44
|
+
| 工具 | 用途 | 关键参数 |
|
|
45
|
+
|------|------|---------|
|
|
46
|
+
| `browser_navigate` | 打开页面 | `url` |
|
|
47
|
+
| `browser_snapshot` | 获取页面可访问性快照 | 无 |
|
|
48
|
+
| `browser_console_messages` | 检查控制台 | `level` |
|
|
49
|
+
| `browser_network_requests` | 网络请求日志 | 无 |
|
|
50
|
+
|
|
51
|
+
### 交互操作
|
|
52
|
+
|
|
53
|
+
| 工具 | 用途 | 关键参数 |
|
|
54
|
+
|------|------|---------|
|
|
55
|
+
| `browser_click` | 点击元素 | `ref`, `element` |
|
|
56
|
+
| `browser_type` | 逐字符输入 | `ref`, `text`, `submit` |
|
|
57
|
+
| `browser_fill_form` | 批量填写表单 | `fields[]` |
|
|
58
|
+
| `browser_select_option` | 选择下拉项 | `ref`, `values[]` |
|
|
59
|
+
| `browser_press_key` | 按键 | `key` |
|
|
60
|
+
| `browser_file_upload` | 上传文件 | `paths[]` |
|
|
61
|
+
| `browser_handle_dialog` | 处理弹窗 | `accept` |
|
|
62
|
+
|
|
63
|
+
### 等待与控制
|
|
64
|
+
|
|
65
|
+
| 工具 | 用途 | 关键参数 |
|
|
66
|
+
|------|------|---------|
|
|
67
|
+
| `browser_wait_for` | 等待元素/文本出现 | `text`, `ref`, `timeout` |
|
|
68
|
+
| `browser_evaluate` | 执行 JS | `function` |
|
|
69
|
+
| `browser_close` | 关闭页面 | 无 |
|
|
70
|
+
|
|
71
|
+
## 四、Smart Snapshot 策略(节省 40-60% Token)
|
|
72
|
+
|
|
73
|
+
每次 `browser_snapshot` 消耗 3,000-8,000 tokens。分级控制:
|
|
74
|
+
|
|
75
|
+
| 级别 | 何时 snapshot | 示例 |
|
|
76
|
+
|------|-------------|------|
|
|
77
|
+
| **必须** | 首次加载页面 | navigate 后确认页面正确 |
|
|
78
|
+
| **必须** | 关键断言点 | 验证操作结果出现 |
|
|
79
|
+
| **必须** | 操作失败时 | 调查页面状态 |
|
|
80
|
+
| **可选** | 中间操作后 | fill 后确认文字填入 |
|
|
81
|
+
| **跳过** | 连续同类操作间 | 连续选择多个下拉框 |
|
|
82
|
+
| **跳过** | 等待循环中 | 改用 `browser_wait_for` |
|
|
83
|
+
|
|
84
|
+
**高效模式**:navigate → snapshot → fill → select → click → wait_for → snapshot(**2 次**)
|
|
85
|
+
**低效模式**:navigate → snapshot → fill → snapshot → select → snapshot → click → snapshot(**4 次**)
|
|
86
|
+
|
|
87
|
+
## 五、等待策略
|
|
88
|
+
|
|
89
|
+
### 按操作类型选择
|
|
90
|
+
|
|
91
|
+
| 操作类型 | 策略 | Token 消耗 |
|
|
92
|
+
|---------|------|-----------|
|
|
93
|
+
| 瞬时(导航、点击) | 直接操作,不等待 | 极低 |
|
|
94
|
+
| 短等(表单提交) | `browser_wait_for text="成功" timeout=10000` | ~5K |
|
|
95
|
+
| 长等(AI 生成、文件处理) | `browser_wait_for` + 合理 timeout | ~5K |
|
|
96
|
+
| 超长等(批量处理) | Shell 端 API 检查 + 最终 1 次 snapshot | ~5.5K |
|
|
97
|
+
|
|
98
|
+
### SSE / 流式生成任务的等待策略
|
|
99
|
+
|
|
100
|
+
当操作涉及 AI 生成、文件转换、SSE 流式处理等需要较长时间的场景时,优先使用 `browser_wait_for` 而非轮询 snapshot:
|
|
101
|
+
|
|
102
|
+
| 步骤 | 工具 | 说明 |
|
|
103
|
+
|------|------|------|
|
|
104
|
+
| 触发操作 | `browser_click` | 点击"生成"/"提交"按钮 |
|
|
105
|
+
| 等待完成 | `browser_wait_for` | 等待完成标志文本出现,设置合理 timeout |
|
|
106
|
+
| 验证结果 | `browser_snapshot` | 确认结果/下载链接出现 |
|
|
107
|
+
|
|
108
|
+
**`browser_wait_for` 参数**:
|
|
109
|
+
- `text`:完成标志文本(如"下载"、"完成"、"预览")
|
|
110
|
+
- `timeout`:根据操作实际预估耗时设置(如表单提交 10s、AI 生成 60-180s、批量处理更长)
|
|
111
|
+
- 相比轮询 snapshot,Token 消耗从 ~60K+ 降至 ~5K
|
|
112
|
+
|
|
113
|
+
### 常见反模式
|
|
114
|
+
|
|
115
|
+
- 每步 snapshot → 合并 2-3 操作后再 snapshot
|
|
116
|
+
- 轮询 snapshot 等待长操作 → 改用 `browser_wait_for`
|
|
117
|
+
- MCP 做 20+ 步 → 长流程用 Playwright CLI
|
|
118
|
+
- 反复 navigate 同一页面 → 在同一页面完成
|
|
119
|
+
- 失败后盲目重试 → 先 `browser_console_messages` 分析
|
|
120
|
+
|
|
121
|
+
### 优先级映射
|
|
122
|
+
|
|
123
|
+
P0(核心流程)必测 → P1(错误处理)必测 → P2(次要功能)按需 → P3 低优先
|
|
124
|
+
|
|
125
|
+
预算 >200K: P0+P1+P2 | 100-200K: P0+P1 | <100K: 仅 P0
|
|
126
|
+
|
|
127
|
+
## 六、凭证管理
|
|
128
|
+
|
|
129
|
+
`.mcp.json` 由 `claude-coder auth` 自动生成,根据配置模式使用不同参数:
|
|
130
|
+
- persistent(默认):`--user-data-dir=<path>`,登录态自动保持
|
|
131
|
+
- isolated:`--isolated --storage-state=<path>`,每次从快照加载
|
|
132
|
+
- extension:`--extension`,连接真实浏览器
|
|
133
|
+
|
|
134
|
+
凭证失效时:不修改 auth 文件,报告中标注,提示用户运行 `claude-coder auth [URL]`。
|
|
135
|
+
|
|
136
|
+
## 七、失败处理
|
|
137
|
+
|
|
138
|
+
**阻断性**(立即停止): 服务未启动、500 错误、凭证缺失、页面空白
|
|
139
|
+
|
|
140
|
+
**非阻断性**(记录继续): 样式异常、console warning、慢响应
|
|
141
|
+
|
|
142
|
+
失败时: snapshot(记录状态)→ console_messages(错误日志)→ 停止该场景 → 继续下一个
|
|
143
|
+
|
|
144
|
+
## 八、tasks.json 测试步骤模板
|
|
145
|
+
|
|
146
|
+
推荐使用结构化标签前缀(`【规则】【环境】【P0】` 等)组织步骤。研究表明,结构化标记可提升 LLM 的指令遵循度和步骤完成率,帮助 Agent 理解每步的目的和优先级。
|
|
147
|
+
|
|
148
|
+
### 基础模板
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"steps": [
|
|
153
|
+
"【规则】阅读 .claude-coder/test_rule.md",
|
|
154
|
+
"【环境】curl [后端]/health && curl [前端](失败则停止)",
|
|
155
|
+
"【P0】Playwright MCP 执行核心 Happy Path(Smart Snapshot)",
|
|
156
|
+
"【P1】错误场景:空输入、无效凭证",
|
|
157
|
+
"【记录】结果写入 record/",
|
|
158
|
+
"【预算】消耗 >80% 时跳过低优先级,记录 session_result.json"
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 含长等待操作的模板(SSE / AI 生成 / 文件转换)
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"steps": [
|
|
168
|
+
"【规则】阅读 .claude-coder/test_rule.md",
|
|
169
|
+
"【环境】curl http://localhost:8000/health 确认后端服务正常",
|
|
170
|
+
"【P0】Playwright MCP 访问目标页面,snapshot 确认页面加载",
|
|
171
|
+
"【P0】填写表单数据,snapshot 确认输入成功",
|
|
172
|
+
"【P0】点击提交,使用 browser_wait_for 等待结果出现(根据操作耗时设置合理 timeout)",
|
|
173
|
+
"【P0】验证结果正确(下载链接有效 / 预览内容匹配)",
|
|
174
|
+
"【记录】测试结果写入 record/(使用 test_rule.md 报告模板)",
|
|
175
|
+
"【预算】Smart Snapshot 策略:导航→填写→点击→等待→验证,共 3-4 次 snapshot"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 九、测试报告格式
|
|
181
|
+
|
|
182
|
+
```markdown
|
|
183
|
+
# E2E 测试报告
|
|
184
|
+
**日期**: YYYY-MM-DD | **环境**: 前端 [URL] / 后端 [URL]
|
|
185
|
+
|
|
186
|
+
| 场景 | 结果 | 备注 |
|
|
187
|
+
|------|------|------|
|
|
188
|
+
| [名称] | PASS/FAIL | [简要] |
|
|
189
|
+
|
|
190
|
+
## 发现的问题
|
|
191
|
+
### [P0/P1/P2] 标题
|
|
192
|
+
- **复现**: [Playwright 动作序列]
|
|
193
|
+
- **预期/实际**: ...
|
|
194
|
+
- **根因**: [代码分析]
|
|
195
195
|
```
|
package/src/core/validator.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
const { log } = require('../common/config');
|
|
5
|
-
const { getGitHead } = require('../common/utils');
|
|
6
|
-
const { assets } = require('../common/assets');
|
|
7
|
-
const { TASK_STATUSES } = require('../common/constants');
|
|
8
|
-
const { loadTasks, getFeatures } = require('../common/tasks');
|
|
9
|
-
|
|
10
|
-
function inferFromTasks(taskId) {
|
|
11
|
-
if (!taskId) return null;
|
|
12
|
-
const data = loadTasks();
|
|
13
|
-
if (!data) return null;
|
|
14
|
-
const task = getFeatures(data).find(f => f.id === taskId);
|
|
15
|
-
return task ? task.status : null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function validateSessionResult() {
|
|
19
|
-
if (!assets.exists('sessionResult')) {
|
|
20
|
-
log('error', 'Agent 未生成 session_result.json');
|
|
21
|
-
return { valid: false, fatal: true, recoverable: false, reason: 'session_result.json 不存在' };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const data = assets.readJson('sessionResult', null);
|
|
25
|
-
if (data === null) {
|
|
26
|
-
log('warn', 'session_result.json 解析失败');
|
|
27
|
-
return { valid: false, fatal: false, recoverable: true, reason: 'JSON 解析失败' };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const sessionData = data.current && typeof data.current === 'object' ? data.current : data;
|
|
31
|
-
|
|
32
|
-
const required = ['session_result', 'status_after'];
|
|
33
|
-
const missing = required.filter(k => !(k in sessionData));
|
|
34
|
-
if (missing.length > 0) {
|
|
35
|
-
log('warn', `session_result.json 缺少字段: ${missing.join(', ')}`);
|
|
36
|
-
return { valid: false, fatal: false, recoverable: true, reason: `缺少字段: ${missing.join(', ')}` };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!['success', 'failed'].includes(sessionData.session_result)) {
|
|
40
|
-
log('warn', `session_result 必须是 success 或 failed,实际是: ${sessionData.session_result}`);
|
|
41
|
-
return { valid: false, fatal: false, recoverable: true, reason: `无效 session_result: ${sessionData.session_result}`, data: sessionData };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!TASK_STATUSES.includes(sessionData.status_after)) {
|
|
45
|
-
log('warn', `status_after 不合法: ${sessionData.status_after}`);
|
|
46
|
-
return { valid: false, fatal: false, recoverable: true, reason: `无效 status_after: ${sessionData.status_after}`, data: sessionData };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (sessionData.session_result === 'success') {
|
|
50
|
-
log('ok', 'session_result.json 合法 (success)');
|
|
51
|
-
} else {
|
|
52
|
-
log('warn', 'session_result.json 合法,但 Agent 报告失败 (failed)');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return { valid: true, fatal: false, recoverable: false, data: sessionData };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function checkGitProgress(headBefore) {
|
|
59
|
-
if (!headBefore) {
|
|
60
|
-
log('info', '未提供 head_before,跳过 git 检查');
|
|
61
|
-
return { hasCommit: false, warning: false };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const projectRoot = assets.projectRoot;
|
|
65
|
-
const headAfter = getGitHead(projectRoot);
|
|
66
|
-
|
|
67
|
-
if (headBefore === headAfter) {
|
|
68
|
-
log('warn', '本次会话没有新的 git 提交');
|
|
69
|
-
return { hasCommit: false, warning: true };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
const msg = execSync('git log --oneline -1', { cwd: projectRoot, encoding: 'utf8' }).trim();
|
|
74
|
-
log('ok', `检测到新提交: ${msg}`);
|
|
75
|
-
} catch { /* ignore */ }
|
|
76
|
-
|
|
77
|
-
return { hasCommit: true, warning: false };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function checkTestCoverage(taskId, statusAfter) {
|
|
81
|
-
if (statusAfter !== 'done' || !taskId) return;
|
|
82
|
-
if (!assets.exists('tests')) return;
|
|
83
|
-
|
|
84
|
-
const tests = assets.readJson('tests', null);
|
|
85
|
-
if (!tests) return;
|
|
86
|
-
const testCases = tests.test_cases || [];
|
|
87
|
-
const taskTests = testCases.filter(t => t.feature_id === taskId);
|
|
88
|
-
if (taskTests.length > 0) {
|
|
89
|
-
const failed = taskTests.filter(t => t.last_result === 'fail');
|
|
90
|
-
if (failed.length > 0) {
|
|
91
|
-
log('warn', `tests.json 中有失败的验证记录: ${failed.map(t => t.id).join(', ')}`);
|
|
92
|
-
} else {
|
|
93
|
-
log('ok', `${taskTests.length} 条验证记录覆盖任务 ${taskId}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function validate(headBefore, taskId) {
|
|
99
|
-
log('info', '========== 开始校验 ==========');
|
|
100
|
-
|
|
101
|
-
const srResult = validateSessionResult();
|
|
102
|
-
const gitResult = checkGitProgress(headBefore);
|
|
103
|
-
|
|
104
|
-
let fatal = false;
|
|
105
|
-
let hasWarnings = false;
|
|
106
|
-
|
|
107
|
-
if (srResult.valid) {
|
|
108
|
-
hasWarnings = gitResult.warning;
|
|
109
|
-
} else {
|
|
110
|
-
if (gitResult.hasCommit) {
|
|
111
|
-
const taskStatus = inferFromTasks(taskId);
|
|
112
|
-
if (taskStatus === 'done' || taskStatus === 'testing') {
|
|
113
|
-
log('warn', `session_result.json 异常,但 tasks.json 显示 ${taskId} 已 ${taskStatus},且有新提交,降级为警告`);
|
|
114
|
-
} else {
|
|
115
|
-
log('warn', 'session_result.json 异常,但有新提交,降级为警告(不回滚代码)');
|
|
116
|
-
}
|
|
117
|
-
hasWarnings = true;
|
|
118
|
-
} else {
|
|
119
|
-
log('error', '无新提交且 session_result.json 异常,视为致命');
|
|
120
|
-
fatal = true;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const statusAfter = srResult.data?.status_after || inferFromTasks(taskId) || null;
|
|
125
|
-
checkTestCoverage(taskId, statusAfter);
|
|
126
|
-
|
|
127
|
-
if (fatal) {
|
|
128
|
-
log('error', '========== 校验失败 (致命) ==========');
|
|
129
|
-
} else if (hasWarnings) {
|
|
130
|
-
log('warn', '========== 校验通过 (有警告) ==========');
|
|
131
|
-
} else {
|
|
132
|
-
log('ok', '========== 校验全部通过 ==========');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return { fatal, hasWarnings, sessionData: srResult.data };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
module.exports = { validate, validateSessionResult, checkGitProgress };
|
package/templates/addGuide.md
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# 任务分解指南
|
|
2
|
-
|
|
3
|
-
> 本文档是 `claude-coder add` 指令的参考文档。
|
|
4
|
-
> ADD Agent 的唯一职责:分解需求为结构化任务,追加到 tasks.json。不实现任何代码。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## tasks.json 格式
|
|
9
|
-
|
|
10
|
-
```json
|
|
11
|
-
{
|
|
12
|
-
"project": "项目名称",
|
|
13
|
-
"created_at": "2026-02-13",
|
|
14
|
-
"features": [
|
|
15
|
-
{
|
|
16
|
-
"id": "feat-001",
|
|
17
|
-
"category": "backend | frontend | fullstack | infra",
|
|
18
|
-
"priority": 1,
|
|
19
|
-
"description": "功能的简要描述(40字内)",
|
|
20
|
-
"steps": [
|
|
21
|
-
"具体步骤 1",
|
|
22
|
-
"具体步骤 2",
|
|
23
|
-
"端到端测试:验证方法"
|
|
24
|
-
],
|
|
25
|
-
"status": "pending",
|
|
26
|
-
"depends_on": []
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### 字段规范
|
|
33
|
-
|
|
34
|
-
| 字段 | 规则 |
|
|
35
|
-
|------|------|
|
|
36
|
-
| `id` | 格式 `feat-NNN`,从已有最大值递增 |
|
|
37
|
-
| `category` | `backend` / `frontend` / `fullstack` / `infra`,准确归类 |
|
|
38
|
-
| `priority` | 数字越小越优先,从已有最大值递增 |
|
|
39
|
-
| `description` | 简明扼要,40 字内,说明"做什么"而非"怎么做" |
|
|
40
|
-
| `steps` | 具体可操作步骤,最后一步必须是可验证的测试命令,单任务不超过 5 步 |
|
|
41
|
-
| `status` | 新增任务一律 `"pending"` |
|
|
42
|
-
| `depends_on` | 引用前置任务的 `id`,形成 DAG(有向无环图),不得循环依赖 |
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 任务分解规则
|
|
47
|
-
|
|
48
|
-
### 粒度控制
|
|
49
|
-
|
|
50
|
-
- 每个任务是独立可测试的功能单元,1-3 session 可完成,新增不超 500 行
|
|
51
|
-
- 单任务 steps 不超过 5 步,超过则拆分为多个任务
|
|
52
|
-
- 第一个任务从第一个有业务逻辑的功能开始,不重复脚手架内容
|
|
53
|
-
- 新项目:infra 任务合并为尽量少的条目,不拆碎
|
|
54
|
-
|
|
55
|
-
### 验证命令模板
|
|
56
|
-
|
|
57
|
-
steps 的最后一步必须包含可执行的验证命令:
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
API: curl -s -o /dev/null -w "%{http_code}" http://localhost:PORT/path → 200
|
|
61
|
-
文件: grep -q "关键内容" path/to/file && echo "pass"
|
|
62
|
-
构建: npm run build 2>&1 | tail -1 → 无 error
|
|
63
|
-
页面: Playwright MCP snapshot 验证关键元素存在
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 反面案例(禁止出现)
|
|
67
|
-
|
|
68
|
-
- `"实现用户功能"` → 太模糊,应拆为具体接口
|
|
69
|
-
- `"编写测试"` → 测试应内嵌在 steps 末尾,不是独立任务
|
|
70
|
-
- steps 只有 `"实现xxx"` 没有验证步骤
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## requirements.md 处理原则
|
|
75
|
-
|
|
76
|
-
`requirements.md` 是用户的需求输入,**绝对不能修改它**。但"不能改"不等于"必须盲从"。遇到以下情况时,在 `session_result.json` 的 `notes` 中记录问题,按最合理的方式继续分解:
|
|
77
|
-
|
|
78
|
-
| 场景 | 处理方式 |
|
|
79
|
-
|------|----------|
|
|
80
|
-
| 需求自相矛盾 | 记录矛盾,按技术可行的方案分解,说明选择理由 |
|
|
81
|
-
| 需求与已有代码冲突 | 记录冲突,说明重构成本,按现有架构分解,建议用户确认 |
|
|
82
|
-
| 需求太模糊无法执行 | 自行做出合理决策,在 notes 中记录选择,供用户确认 |
|
|
83
|
-
| 需求中途变更 | 记录变更影响,基于最新需求分解 |
|
|
84
|
-
| 需求引用了不可访问的资源 | 记录问题,根据文字描述尽力分解 |
|
|
85
|
-
| 需求指定了不存在的依赖 | 记录问题,使用最接近的可用版本 |
|
|
86
|
-
|
|
87
|
-
**核心原则:不停工、不擅改、留记录。**
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Playwright MCP 测试任务
|
|
92
|
-
|
|
93
|
-
当任务涉及前端或全栈端到端测试,且项目已配置 Playwright MCP 时,测试步骤的详细规范(结构化标签、Smart Snapshot 策略、SSE 等待模式、步骤模板等)统一参见 `.claude-coder/test_rule.md` 第五节(等待策略)和第八节(步骤模板)。
|
|
94
|
-
|
|
95
|
-
此处只列关键原则:
|
|
96
|
-
- steps 首步加入 `【规则】阅读 .claude-coder/test_rule.md`
|
|
97
|
-
- 使用 `【P0】【P1】【P2】` 标记优先级,预算不足时可按优先级裁剪
|
|
98
|
-
- 长等待操作使用 `browser_wait_for` 而非轮询 snapshot
|
package/templates/addUser.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
你是资深需求分析师,擅长将模糊需求分解为可执行的原子任务。
|
|
2
|
-
这是任务追加 session,不是编码 session。你只分解任务,不实现代码。
|
|
3
|
-
|
|
4
|
-
{{profileContext}}
|
|
5
|
-
{{taskContext}}
|
|
6
|
-
{{recentExamples}}
|
|
7
|
-
项目绝对路径: {{projectRoot}}
|
|
8
|
-
|
|
9
|
-
【方案文件】
|
|
10
|
-
{{planPath}}
|
|
11
|
-
|
|
12
|
-
执行步骤(按顺序,不可跳过):
|
|
13
|
-
1. 读取方案文件({{planPath}}),理解技术方案和任务规划
|
|
14
|
-
2. 读取 .claude-coder/tasks.json 和 .claude-coder/project_profile.json,了解项目现状
|
|
15
|
-
3. 分析方案中的任务列表:识别核心功能点,判断是单任务还是需要拆分为多任务
|
|
16
|
-
4. 检查重复:对比已有任务,避免功能重叠
|
|
17
|
-
5. 确定依赖:新任务的 depends_on 引用已有或新增任务的 id,形成 DAG
|
|
18
|
-
6. 分解任务:按下方任务分解指南的规则,每个任务独立可测试
|
|
19
|
-
7. 追加到 tasks.json,id 和 priority 从已有最大值递增,status: pending
|
|
20
|
-
8. git add -A && git commit -m "chore: add new tasks"
|
|
21
|
-
9. 写入 session_result.json(格式:{ "session_result": "success", "status_before": "N/A", "status_after": "N/A", "notes": "追加了 N 个任务:简述" })
|
|
22
|
-
|
|
23
|
-
{{addGuide}}
|
|
24
|
-
|
|
25
|
-
{{testRuleHint}}
|
|
26
|
-
不修改已有任务,不实现代码。
|