@deepstorm/cli 0.10.1 → 0.11.0

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.
@@ -0,0 +1,61 @@
1
+ # E2E 测试流程:{模块名} — {业务流程}
2
+
3
+ **来源:** sweep-explore 源码分析
4
+ **创建时间:** {YYYY-MM-DD HH:mm}
5
+
6
+ ---
7
+
8
+ ## 模块信息
9
+
10
+ | 字段 | 内容 |
11
+ | :--- | :--- |
12
+ | 模块名 | {模块名,如 用户管理} |
13
+ | 源码路径 | {对应的前端源码目录} |
14
+ | 涉及页面 | {页面列表,以逗号分隔} |
15
+
16
+ ---
17
+
18
+ ## 场景清单
19
+
20
+ | ID | 场景 | 类型 | 优先级 |
21
+ | :--- | :--- | :--- | :--- |
22
+ | L01 | {场景标题} | 正常流程 | P0 |
23
+ | L02 | {场景标题} | 边界条件 | P1 |
24
+ | L03 | {场景标题} | 异常场景 | P1 |
25
+
26
+ ---
27
+
28
+ ## Flow: L01 - {场景标题}
29
+
30
+ ### 前置条件
31
+
32
+ {描述测试开始前必须满足的状态或数据}
33
+
34
+ ### 执行步骤
35
+
36
+ 1. {操作步骤 1}
37
+ ✅ 验证点:{预期结果 1}
38
+ 2. {操作步骤 2}
39
+ ✅ 验证点:{预期结果 2}
40
+
41
+ ### 环境要求
42
+
43
+ - 目标环境:{test / staging / prod}
44
+ - 所需账号:{账号类型或角色}
45
+
46
+ ---
47
+
48
+ ## Flow: L02 - {场景标题}
49
+
50
+ ### 前置条件
51
+
52
+ {描述测试开始前必须满足的状态或数据}
53
+
54
+ ### 执行步骤
55
+
56
+ 1. {操作步骤 1}
57
+ ✅ 验证点:{预期结果 1}
58
+
59
+ ### 环境要求
60
+
61
+ - 目标环境:{test / staging / prod}
@@ -0,0 +1,335 @@
1
+ ---
2
+ name: sweep-record
3
+ description: Use when you have a browser recording (.recording.json) from `deepstorm record` and need to generate E2E tests. AI analyzes the recording to produce .flow.md + .spec.ts compatible with sweep-run. Supports selecting from multiple recordings or specifying one directly.
4
+ allowed-tools: Read, Write, Agent, Bash
5
+ deepstorm:
6
+ tool: sweep
7
+ ---
8
+
9
+ # Sweep Record — 浏览器操作录制 → E2E 测试生成
10
+
11
+ 基于 `deepstorm record` CLI 录制的 `.recording.json`,AI 自动分析操作序列、推断断言、生成与 sweep-run 兼容的 `.flow.md` 和 `.spec.ts`。
12
+
13
+ ## 适用场景
14
+
15
+ **何时使用:**
16
+ - 已有录制好的 `.recording.json` 文件(通过 `deepstorm record start -u <url>` 录制)
17
+ - 想将真人操作转化为可重复执行的 E2E 测试
18
+ - 项目无前端源码或源码结构不标准,无法使用 `/sweep-explore`
19
+ - 测试工程师能手动操作界面但不熟悉代码编写
20
+
21
+ **何时不使用:**
22
+ - 没有进行浏览器操作录制
23
+ - 需要从源码分析生成测试 → 请使用 `/sweep-explore`
24
+ - 已有现成需求文档 → 请使用 `/sweep-plan`
25
+
26
+ ## 使用方式
27
+
28
+ | 方式 | 说明 |
29
+ |------|------|
30
+ | **交互选择** | `/sweep-record` → 列出所有未处理的 `.recording.json`,选择后进入分析 |
31
+ | **直接指定** | `/sweep-record <name>` → 匹配对应名称的录制文件,跳过选择直接分析 |
32
+
33
+ ---
34
+
35
+ ## 四步工作流
36
+
37
+ ```mermaid
38
+ flowchart LR
39
+ S1["Step 1: 选择录制<br>选择 .recording.json"] --> S2["Step 2: AI 分析<br>去重 + 分组 + 命名"]
40
+ S2 --> S3["Step 3: 生成产出物<br>.flow.md + .spec.ts"]
41
+ S3 --> S4["Step 4: 降级处理<br>异常情况处理"]
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 安全门闸
47
+
48
+ > **使用本 skill 前必须先阅读以下全部流程说明**,然后逐节执行。该 skill 不依赖其他外部 skill。
49
+
50
+ ---
51
+
52
+ ## §1 录制文件选择
53
+
54
+ ### 1.1 扫描录制目录
55
+
56
+ ```bash
57
+ ls -lt .deepstorm/recordings/*.recording.json 2>/dev/null
58
+ ```
59
+
60
+ ### 1.2 展示列表
61
+
62
+ 读取所有 `.recording.json` 文件的 `meta` 信息,向用户展示:
63
+
64
+ ```
65
+ 📁 录制文件列表:
66
+
67
+ [未处理]
68
+ 1. 2026-07-26 14:30:22 — 8 events — ?untitled
69
+ 2. 2026-07-26 15:10:05 — 24 events — ?untitled
70
+
71
+ [已处理 → test-flows/user-login.flow.md]
72
+ 3. 2026-07-25 10:00:00 — 15 events — user-login
73
+
74
+ ? 请输入编号或输入文件名称 >
75
+ ```
76
+
77
+ **判断规则:**
78
+ - 已处理:对应名称的 `.flow.md` 已存在于 `test-flows/` 中
79
+ - 未处理:无同名 `.flow.md`
80
+ - 标题展示:优先显示文件名;文件名无语义时显示 `?untitled`
81
+
82
+ ### 1.3 直接指定
83
+
84
+ `/sweep-record <name>` 时:
85
+ - 在 `.deepstorm/recordings/` 中匹配文件名包含 `<name>` 的 `.recording.json`
86
+ - 唯一匹配 → 直接进入分析
87
+ - 多匹配 → 展示匹配列表让用户选择
88
+ - 无匹配 → 回到列表模式
89
+
90
+ ### 1.4 异常处理
91
+
92
+ - 录制目录不存在 → 提示"尚未进行过录制,请先执行 `deepstorm record start -u <url>`"
93
+ - 无录制文件 → 提示同上
94
+ - 所有文件均已处理 → 提示用户是否要重新分析某文件
95
+
96
+ ---
97
+
98
+ ## §2 AI 事件分析
99
+
100
+ ### 2.1 读取录制数据
101
+
102
+ 加载选中的 `.recording.json`,解析 `meta` 和 `events` 数组。
103
+
104
+ ### 2.2 事件去重与语义分组
105
+
106
+ 使用 AI 对原始事件执行:
107
+
108
+ **去重规则:**
109
+ - 同一元素 <500ms 内的多次 click → 合并为一次
110
+ - focus + input + blur → 聚合为一个 input 步骤(保留最终值)
111
+ - 连续 mousemove/scroll 事件已在 CLI 阶段过滤,此处检查残留
112
+
113
+ **语义分组提示:**
114
+
115
+ 分析 `events[]` 数组,将零散事件聚合法操作步骤:
116
+
117
+ ```markdown
118
+ 将以下原始事件序列:
119
+
120
+ click on <input#username> → input value="admin" → click on <input#password> →
121
+ input value="****" → click on <button#login> → navigation to /dashboard
122
+
123
+ 分组为语义步骤:
124
+
125
+ 1. 填写用户名(admin)
126
+ 2. 填写密码
127
+ 3. 点击"登录"按钮
128
+ 4. 验证跳转到仪表盘页面
129
+ ```
130
+
131
+ **分组策略:**
132
+ - 连续输入在同一区域 → 合并为"填写 {表单名}"分组
133
+ - click + input + blur → 合并为"填写 {字段名} 为 {值}"
134
+ - 下拉选择 → "选择 {选项名}"
135
+ - click + navigation → "点击 {元素名} 并跳转"
136
+ - 相邻的 click → 保留为独立操作(除非同一元素 <500ms)
137
+
138
+ ### 2.3 断言推断
139
+
140
+ 基于以下数据源自动推断断言:
141
+
142
+ **网络响应断言(优先级高):**
143
+ - 从 `type: "network"` 事件中提取 URL 和 statusCode
144
+ - statusCode 200 → ✅ 验证点:接口 {path} 返回状态码 200
145
+ - statusCode 4xx/5xx → ✅ 验证点:接口 {path} 返回 {code}(错误提示:{摘要})
146
+ - 响应体摘要有错误信息 → 追加验证点
147
+
148
+ **页面导航断言:**
149
+ - 从 `type: "navigation"` 事件提取目标 URL
150
+ - 完整导航 → ✅ 验证点:页面 URL 跳转到 {url}
151
+ - SPA 路由变化 → ✅ 验证点:URL 变为 {path}
152
+
153
+ **页面标题/内容断言:**
154
+ - 导航后标题变化 → ✅ 验证点:页面标题变为 {新标题}
155
+ - 如有截图且 AI 可见差异 → ✅ 验证点:{元素名} 可见(视觉确认)
156
+
157
+ **截图辅助分析:**
158
+ - 每张截图附带在事件序列中的时间戳
159
+ - AI 比较操作前后的截图,发现页面变化
160
+ - 截图内容用于补充断言(如弹窗出现、状态文字变化)
161
+
162
+ ### 2.4 流程自动命名
163
+
164
+ **命名策略:**
165
+ 1. 综合页面标题序列、URL 路径、操作语义 → 推断业务名称
166
+ 2. 使用英文 kebab-case,3-5 个词
167
+ 3. 反映核心操作目的(如 `user-login`、`create-order`、`approve-workflow`)
168
+
169
+ **命名提示词示例:**
170
+
171
+ ```markdown
172
+ 基于以下操作序列推断该测试流程的名称(英文 kebab-case,3-5 词):
173
+
174
+ 页面标题序列:Dashboard → Login → User Management
175
+ URL 路径序列:/ → /login → /users
176
+ 操作摘要:输入用户名 → 输入密码 → 点击登录
177
+
178
+ 推荐:user-login
179
+ ```
180
+
181
+ **置信度:**
182
+ - 页面标题和 URL 包含业务关键词 → 高置信度
183
+ - 仅能从操作推断 → 中等置信度,名称加 `?` 前缀标记
184
+ - 完全无法推断 → 推荐 `?untitled-flow`,提示用户手动命名
185
+
186
+ ### 2.5 用户确认
187
+
188
+ ```
189
+ ✅ AI 分析完成
190
+
191
+ 📋 共识别 6 个语义操作步骤
192
+ 📸 含 3 张截图分析
193
+ 🔍 推断 5 个验证点
194
+
195
+ 📝 推荐流程名称:user-login
196
+ 是否接受此名称?(Y/n) >
197
+ ```
198
+
199
+ - 用户按 Enter → 接受推荐名称
200
+ - 用户输入新名称 → 使用自定义名称
201
+ - AI 推荐名称含 `?` 前缀时 → 强制要求用户命名
202
+
203
+ ---
204
+
205
+ ## §3 测试生成
206
+
207
+ ### 3.1 生成 .flow.md
208
+
209
+ 基于分析结果生成 `.flow.md`,格式与 sweep-explore 产出的 `.flow.md` 一致:
210
+
211
+ **文件结构:**
212
+
213
+ ```markdown
214
+ # E2E 测试流程:{flow-name}
215
+
216
+ **来源:** sweep-record 浏览器录制
217
+ **创建时间:** {YYYY-MM-DD HH:mm}
218
+
219
+ ---
220
+
221
+ ## 场景清单
222
+
223
+ | ID | 场景 | 来源 |
224
+ |----|------|------|
225
+ | L01 | {操作序列主流程} | 录制分析 |
226
+
227
+ ---
228
+
229
+ ## Flow: L01 - {主流程}
230
+
231
+ ### 前置条件
232
+ - 打开目标页面 {url}
233
+
234
+ ### 执行步骤
235
+ 1. {操作描述(中文)}
236
+ ✅ 验证点:{预期结果}
237
+
238
+ ### 环境要求
239
+ - 目标环境:{从录制 URL 推断,如 test/staging/prod}
240
+ ```
241
+
242
+ **注意事项:**
243
+ - 精确的 Playwright locator 信息不出现在 `.flow.md` 中(保持可读性)
244
+ - 每个语义分组对应一个 `Flow: L{N} - {标题}` 章节
245
+ - 文件头部标记来源为 `sweep-record`
246
+ - 步骤数量超过 15 时考虑拆分为多个 Flow
247
+
248
+ **多流程拆分:**
249
+ - 录制包含多个独立语义流程 → 拆分为多个 `Flow:` 章节,共用同一 `.flow.md`
250
+ - 录制包含完全无关的两组操作 → AI 建议生成多个 `.flow.md` 文件并请求用户确认
251
+
252
+ ### 3.2 生成 .spec.ts
253
+
254
+ 基于录制数据中的精确 locator 直接生成 Playwright 测试脚本:
255
+
256
+ **生成策略:**
257
+ - 使用录制数据中的精确 locator(`getByRole`、`getByText`、`getByPlaceholder`、`getByTestId`、CSS 选择器),优先级同设计文档 D2
258
+ - 每个步骤前添加中文注释说明操作意图
259
+ - 操作后添加对应的 `expect()` 断言(从 Step 2.3 推断)
260
+ - 录制中的输入值直接硬编码(供后续人工替换为测试数据变量)
261
+ - `.spec.ts` 的 `test.describe` 名称 = flow-name
262
+
263
+ **文件命名:**
264
+ - `.flow.md` → `test-flows/{flow-name}.flow.md`
265
+ - `.spec.ts` → `test-flows/{flow-name}.spec.ts`
266
+
267
+ ### 3.3 用户确认流程
268
+
269
+ ```
270
+ 📝 即将生成以下文件:
271
+
272
+ 1. test-flows/user-login.flow.md (6 steps, 5 assertions)
273
+ 2. test-flows/user-login.spec.ts (6 Playwright steps)
274
+
275
+ ? 确认生成?(Y/n) >
276
+ ```
277
+
278
+ - 用户确认 → 写入文件
279
+ - 用户拒绝 → 返回修改
280
+
281
+ ### 3.4 异常处理
282
+
283
+ **录制为空或无有效事件:**
284
+ - 有效事件数 = 0 → 提示"录制文件中无有效事件,无法生成测试",建议重新录制
285
+ - 有效事件数 < 2 → 提示"录制事件不足,可能无法生成有意义的测试脚本",但仍尝试生成,附带低质量警告
286
+
287
+ ---
288
+
289
+ ## §4 降级处理
290
+
291
+ ### 4.1 录制文件损坏
292
+
293
+ ```bash
294
+ # 验证 JSON 格式
295
+ cat .deepstorm/recordings/{file}.recording.json | python3 -m json.tool > /dev/null 2>&1
296
+ ```
297
+
298
+ 若 JSON 解析失败:
299
+ - 提示"录制文件可能已损坏"并显示解析错误位置
300
+ - 建议用户重新录制
301
+ - 如文件部分可读,尝试提取有效事件片段
302
+
303
+ ### 4.2 分析失败
304
+
305
+ 当 AI 无法合理分组或推断时:
306
+ - 输出原始事件序列的直观展示
307
+ - 提示"AI 无法有效分析该录制内容"
308
+ - 可能原因:录制内容过于复杂、浏览器崩溃导致数据不完整、页面涉及需要交互的 iframe
309
+ - 建议:重新录制,将流程拆分为更小的步骤
310
+
311
+ ### 4.3 无截图时的断言策略
312
+
313
+ 如果录制过程中截图失败或不存在:
314
+ - 降级为纯网络响应和导航状态推断断言
315
+ - 标记缺少截图的步骤为"无截图确认"(降低断言可信度)
316
+ - 提示用户"部分操作缺少截图,建议补录以获得更好的断言覆盖"
317
+
318
+ ---
319
+
320
+ ## 快速参考
321
+
322
+ ### 命令速查
323
+
324
+ | 命令 | 说明 |
325
+ |------|------|
326
+ | `/sweep-record` | 交互选择录制文件并进入分析 |
327
+ | `/sweep-record <name>` | 直接指定录制文件名称 |
328
+
329
+ ### 产出物
330
+
331
+ ```
332
+ test-flows/
333
+ ├── {flow-name}.flow.md ← 测试意图文档(sweep-run 兼容)
334
+ └── {flow-name}.spec.ts ← Playwright 测试脚本
335
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstorm/cli",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "DeepStorm CLI — 一键配置项目开发环境",
5
5
  "license": "MIT",
6
6
  "author": "billkang",
@@ -16,7 +16,8 @@
16
16
  "dotenv": "^17.4.2",
17
17
  "handlebars": "^4.7.8",
18
18
  "js-yaml": "^4.1.0",
19
- "@deepstorm/pilot": "^0.10.1"
19
+ "playwright": "^1.62.0",
20
+ "@deepstorm/pilot": "^0.11.0"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@types/node": "^22.0.0",