@epoint-testtech/ep-stage-skill 0.0.14 → 0.0.16

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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: code-list-generate
3
3
  description: 使用时机:当用户(上游研发/出码方)要「生成 / 编写 / 产出 code_list.json5(出码总结、测试输入物料清单)」、交付需求给下游胶水测试流程、或显式触发 `/code-list-generate <源码根路径>` 时使用。即使用户只说「帮我把这个需求的源码整理成下游测试要的输入文件」「code_list 怎么写」,也应主动使用本 skill。本 skill 引导从 epoint 系源码(perpage/*.html + *Action.java + Entity.java)和 PRD 中提取事实,产出符合下游契约的 code_list.json5。
4
- version: 2026-08-17+delete-scope-fix
4
+ version: 2026-08-20+6cf6d2e
5
5
  argument-hint: "<源码根路径>(可选;不给则打印输入引导逐项询问)"
6
6
  ---
7
7
 
@@ -121,6 +121,8 @@ node <skill目录>/scripts/validate-code-list.mjs <需求目录>/_docs/code_list
121
121
 
122
122
  **`scope: ['delete']` 的纪律**:只有「记录状态/条件阻断删除」的规则(如"在用数据不可删除")才配 `scope: ['delete']` + `assertionHint`。「未勾选拦截」(如"请选择要删除的数据!")、「二次确认文案」这类**操作前置提示不标 delete scope**(可标 `scope: ['ui']` 或并入其他规则的 description)——下游把 scope 含 delete 的规则当作删除断言策略来源(装配器虽有"优先阻断语义文案"的自愈,但只是兜底,不应依赖)。若确有多条 delete scope 规则,记录级阻断规则必须排最前。
123
123
 
124
+ **条件性删除必须标 `deletableCondition`**:阻断不是无条件成立、而是按记录状态/条件分流的(如"草稿可删、在用不可删"),这是业务常态。这类规则除了 `scope: ['delete']` + `assertionHint`(阻断文案),还必须补 `deletableCondition`(可删条件的文字描述,如 `'记录为草稿(DRAFT)状态'`)——下游删除用例保持单条,断言据此写**双预期**(满足可删条件→删除成功查无记录;命中阻断规则→提示且记录仍存在),骨架运行时分流断言;缺了这个字段,下游按无条件阻断处理(断言只写阻断单预期),可删路径在断言层面丢失。无条件阻断的规则(如"已归档数据一律不可删")不写该字段。
125
+
124
126
  ## 查询字段与数据主键
125
127
 
126
128
  - `pages[role=list].queryFields[]`:`component: 'mini-textbox'` → 输入框;`'mini-combobox'` → 下拉。带 `bind: 'dataBean.xxx'` 时下游能推出字段名。
@@ -293,6 +293,9 @@
293
293
  scope: ['delete'],
294
294
  sourceKind: 'static_scan',
295
295
  assertionHint: '<阻断提示原文,如 在用数据不可删除!>',
296
+ // 条件性删除(草稿可删/在用不可删这类按状态分流的规则)必须补:
297
+ // deletableCondition: '记录为草稿(DRAFT)状态',
298
+ // 无条件阻断规则不写。缺字段下游按无条件阻断处理(断言只写阻断单预期)。
296
299
  evidence: ['src/main/java/com/epoint/<module>/action/<XxxListAction>.java#<deleteSelect>'],
297
300
  },
298
301
  ],
@@ -113,6 +113,7 @@
113
113
  | `scope` | **关键**。作用域数组:`create`/`update`/`delete`/`ui`/子表 id 等。**含 `delete` 的规则会把下游删除用例断言改为「阻断」,下游取阻断语义最明确的一条作为策略来源(装配器优先选 assertionHint 含"不可删除"类文案的规则,兜底取第一条)**——因此只有「记录状态/条件阻断删除」的规则才标 `delete`;「未勾选拦截」「二次确认」等操作前置提示标 `ui`,不要混入 delete scope |
114
114
  | `sourceKind` | 通常 `static_scan` |
115
115
  | `assertionHint` | 阻断/校验提示**主文案**(如"在用数据不可删除!"),下游直接用作预期断言值。**一条规则只放一个主文案**(下游只消费单值);同规则的其余文案写进 `description`,不要塞数组 |
116
+ | `deletableCondition` | **可选,仅 delete scope 规则用**。条件性删除(如"草稿可删、在用不可删")时填可删条件的文字描述(如 `'记录为草稿(DRAFT)状态'`);下游删除用例保持单条、断言写双预期(条件满足→删除成功查无记录 + 条件不满足→阻断提示且记录仍存在),骨架运行时分流断言。无条件阻断规则不写;缺字段时下游按无条件阻断处理(断言只写阻断单预期) |
116
117
  | `evidence[]` | 源码相对路径#方法锚点 |
117
118
 
118
119
  ## 留空与省略约定
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: glue-create-project
3
3
  description: 使用时机:当用户表达「创建胶水项目 / 测试脚手架 / 新建 glue 项目」或显式触发 `/glue-create-project [名称或路径]` 时使用。本 skill 只创建胶水模式(glue)Playwright 测试脚手架,不收集登录信息,不写 .env / stage-context.md。
4
- version: 2026-08-17+chromium-install
4
+ version: 2026-08-20+6cf6d2e
5
5
  argument-hint: "<脚手架项目名或脚手架项目路径>"
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: glue-run-test
3
3
  description: 使用时机:当用户对某需求要「跑测试 / 验证 / 端到端执行 / 跑胶水测试 / 看报告」或显式触发 `/glue-run-test <testcase.json5路径>` 时使用。
4
- version: 2026-08-12+c23cb62
4
+ version: 2026-08-20+6cf6d2e
5
5
  argument-hint: "<testcase.json5绝对/相对路径>"
6
6
  compatibility: 需要由 stage-create 生成的 glue 模式 Playwright 项目 + 已审过的 `testcase.json5` + 同目录 `credentials.json5`。
7
7
  metadata:
@@ -215,7 +215,7 @@ CLI 非 0 退出 → 复述 stderr,不进 Step 7。
215
215
  | `<projectDir>/src/tests/<需求名>/.ep-stage/ai-runtime-trace.json5` | prepare-tasks 先写 tasks;run 回写 results / repairRounds |
216
216
  | `<projectDir>/src/tests/<需求名>/.ep-stage/elementmap.json` | Agent O-D-A-V 落的页面控件定位清单(含 grid columns);run 不触碰 |
217
217
  | `<projectDir>/src/tests/<需求名>/.ep-stage/repair-runs/<round>/repair-report.md` | 失败时才产;含失败分类与摘要,待人审确认 |
218
- | `<projectDir>/e2e/glue-code-mvp/glue-report/<run-timestamp>/` | run 子命令产;执行账本(`index.html` glue 风格综合报告(全部用例)+ `playwright-results.json` + `run-output.log` 完整执行输出 + `run-info.json`) |
218
+ | `<projectDir>/glue-report/<run-timestamp>/` | run 子命令产;执行账本(`index.html` glue 风格综合报告(全部用例)+ `playwright-results.json` + `run-output.log` 完整执行输出 + `run-info.json`) |
219
219
  | `<projectDir>/playwright-report/index.html` | run 子命令随执行产;Playwright 综合报告(用例状态/错误/截图/trace 回放),`npx playwright show-report` 打开 |
220
220
  | `<projectDir>/stage-report/` | run 子命令随执行产;stage-core 流程视角报告(index.html + report.pdf) |
221
221
 
@@ -240,10 +240,9 @@ Step 7 全部通过后,按以下中文格式呈现:
240
240
  > 需求:`<需求名>`/项目:`<projectDir>`
241
241
  > Spec:`<projectDir>/src/tests/<需求名>/crud.spec.ts`(glue 骨架 + Agent snippet 合并)
242
242
  > AI Runtime Trace:`<projectDir>/src/tests/<需求名>/.ep-stage/ai-runtime-trace.json5`
243
- > 报告目录:`<projectDir>/e2e/glue-code-mvp/glue-report/<run-timestamp>/`(run-output.log + run-info.json)
244
- > 综合报告:`<projectDir>/e2e/glue-code-mvp/glue-report/<run-timestamp>/index.html`(glue 风格,覆盖全部用例)
243
+ > 报告目录:`<projectDir>/glue-report/<run-timestamp>/`(run-output.log + run-info.json)
244
+ > 综合报告:`<projectDir>/glue-report/<run-timestamp>/index.html`(glue 风格,覆盖全部用例)
245
245
  > 技术细节:`<projectDir>/playwright-report/index.html`(trace/截图/视频)+ `<projectDir>/stage-report/`(流程 PDF)
246
- > 运行版本:`version = v1`
247
246
  >
248
247
  > 下一步:① 调整 `testcase.json5` / `contract.json5` 后重跑 `/glue-run-test <testcase.json5路径>`;② 失败时查看 repair-report.md 确认修补方向后再重跑。
249
248
 
@@ -1,91 +1,92 @@
1
- ---
2
- name: page-element-scan
3
- description: 基于 Playwright 实时渲染识别页面中的可操作元素(按钮、表单字段、列表行操作、标签页、链接等),输出带定位符和可见/可用状态的元素清单(JSON + Markdown)。可与页面源 html 交叉比对,标注「静态有渲染无」「渲染有静态无」的差异证据。当用户想盘点页面元素、摸清页面有哪些按钮和字段、生成页面元素清单、为自动化测试/用例编写摸清页面结构时使用,即使用户只给了一个 URL 也应主动使用本技能。
4
- ---
5
-
6
- # page-element-scan — 页面可操作元素识别
7
-
8
- ## 用途
9
-
10
- 对指定页面做一次「可操作元素盘点」:用 Playwright 真实渲染页面,提取所有用户可操作的元素,并为每个元素给出 Playwright 可用的定位符。
11
-
12
- 与静态读 html 源码的区别:运行时渲染才能回答「这个元素用户到底看不看得到、点不点得动」。 MiniUI 等框架会把声明式标记渲染成复杂 DOM,权限控制会让部分元素渲染时隐藏,脚本会动态创建新元素——这些只有渲染结果能告诉我们。如果用户同时提供了页面源 html,本技能会做双证据比对:
13
-
14
- - `both`:源码声明且渲染确认 —— 最可信
15
- - `runtime-only`:渲染时才出现(脚本动态创建)—— 静态分析会漏掉
16
- - `source-only`:源码声明但渲染时不可见(权限隐藏/逻辑移除)—— 对最终用户不可操作
17
-
18
- ## 输入收集
19
-
20
- 开始扫描前,向用户确认以下信息(能从上下文推断就不要再问):
21
-
22
- 1. **目标 URL**(必填)。本地 html 文件用 `file:///` 绝对路径。
23
- 2. **登录方式**(如需要):账号密码,或已有的 Playwright storage-state 文件。若当前目录是胶水/e2e 项目且有 `.env`(含 `LOGIN_SYSTEM_URL` / `LOGIN_USERNAME` / `LOGIN_PASSWORD`),直接读取复用,不要问用户要密码。
24
- 3. **源 html 路径**(可选):有就给 `--source`,触发双证据比对。
25
- 4. **输出位置**:默认 `./page-elements/` 下,`<页面名>.json` + `<页面名>.md`。
26
-
27
- ## 执行步骤
28
-
29
- 1. 确定一个安装了 playwright 的工作目录作为 `--project-dir`:当前项目根、或 `e2e-test/` 下任一胶水项目(它们的 node_modules 里有 playwright)。脚本用 `createRequire` 从该目录解析依赖。
30
-
31
- 2. 运行扫描脚本(路径相对于本技能目录):
32
-
33
- ```bash
34
- node <技能目录>/scripts/scan-page.mjs \
35
- --url "<目标URL>" \
36
- --out "<输出>.json" --md "<输出>.md" \
37
- --project-dir "<含playwright的目录>"
38
- ```
39
-
40
- 按需追加:
41
- - 登录:`--login-url <登录页> --login-user <账号> --login-pass <密码>`(启发式填用户名密码框);启发式失败时用 `--login-user-selector` / `--login-pass-selector` / `--login-submit-selector` 显式指定。
42
- - 登录态复用:`--storage-state <state.json>`。
43
- - 双证据:`--source <页面源html>`。
44
- - 渲染不充分时加大 `--wait 3000`;调试时 `--headed` 看浏览器实际行为。
45
-
46
- 3. 脚本默认扫描主 frame 和所有子 frame(epoint 页面常嵌 iframe),每个元素的 `frame` 字段标注来源;跨域 frame 会自动跳过。
47
-
48
- ## 结果呈现
49
-
50
- 扫描完成后读 JSON,向用户汇报:
51
-
52
- 1. **概览**:元素总数、可操作数、按类型分布(button / field / grid / tab / link)。
53
- 2. **值得注意的发现**(这是盘点的价值所在,不要只报数字):
54
- - 渲染时隐藏或禁用的元素(可能受权限/状态控制)
55
- - `runtime-only` 元素(动态创建,静态分析发现不了)
56
- - `source-only` 元素(声明了但用户看不到)
57
- - grid 的行操作和列信息
58
- 3. 文件路径,提示 JSON 里的 `locator` 可直接用于 Playwright 脚本。
59
-
60
- ## 输出格式
61
-
62
- JSON 结构:
63
-
64
- ```json
65
- {
66
- "url": "...", "title": "...", "scannedAt": "...",
67
- "summary": { "total": 42, "byType": {"button": 8, "field": 12}, "actionable": 35,
68
- "hiddenAtRuntime": 2, "runtimeOnly": 3, "sourceOnly": 1 },
69
- "dialogs": [{"trigger": "openChild", "title": "新增窗口", "pagePath": "xxx.html"}],
70
- "elements": [
71
- { "type": "button", "label": "新增", "locator": "xpath=//a[contains(@class,'mini-button')]...",
72
- "visible": true, "enabled": true, "evidence": "both", "frame": "main" }
73
- ]
74
- }
75
- ```
76
-
77
- `dialogs` 仅 `--source` 模式产出(从 script 中解析 openTopDialog 调用)。
78
-
79
- ## 边界与须知
80
-
81
- - 「可操作」判定 = 可见(非 display:none、有尺寸)且可用(非 disabled)。默认输出过滤不可见元素,`--include-hidden` 可保留。
82
- - 脚本不做交互(不点按钮、不开弹窗)。弹窗/二级页面内的元素需把对应 URL 再扫一遍,或先用 `--headed` 观察交互路径。
83
- - 登录启发式覆盖常见登录页;复杂登录(验证码、SSO 跳转)失败时,让用户手动登录后用 `--storage-state` 重试。
84
- - 元素去重键是 `type|label|locator`,同 label 不同类型控件不会合并。
85
- - **已知覆盖范围**(已验证于真实 epoint MiniUI 页面):
86
- - 按钮:MiniUI `a.mini-button`、epoint `a.cond-srh-btn`(搜索按钮)、原生 `button`、`[role=button]`
87
- - 字段:`div[label]` 包装的 MiniUI 控件(textbox/combobox/buttonedit/datepicker/spinner)、原生 `input/select/textarea`
88
- - Grid:`mini-datagrid` `.mini-grid-headertxt` 列名 + `[data-tooltip]` 行操作图标
89
- - 标签页:`.mini-tabs li`
90
- - 噪音过滤:无 label 的分页跳页输入框(`pagination-number`)等无业务意义输入不输出
91
- - **双证据实现说明**:源码侧使用 `DOMParser` 解析 HTML(不执行脚本),得到纯声明态 DOM;运行时侧用 Playwright 渲染;两者按 type+label 比对后标注 `both / runtime-only / source-only`。`setContent` 方案会执行内联脚本导致 evidence 误标,已废弃。
1
+ ---
2
+ name: page-element-scan
3
+ description: 使用时机:当用户想盘点页面元素、摸清页面有哪些按钮和字段、生成页面元素清单、为自动化测试/用例编写摸清页面结构时使用,即使用户只给了一个 URL 也应主动使用本技能。基于 Playwright 实时渲染识别页面中的可操作元素(按钮、表单字段、列表行操作、标签页、链接等),输出带定位符和可见/可用状态的元素清单(JSON + Markdown)。可与页面源 html 交叉比对,标注「静态有渲染无」「渲染有静态无」的差异证据。
4
+ version: 2026-08-20+6cf6d2e
5
+ ---
6
+
7
+ # page-element-scan — 页面可操作元素识别
8
+
9
+ ## 用途
10
+
11
+ 对指定页面做一次「可操作元素盘点」:用 Playwright 真实渲染页面,提取所有用户可操作的元素,并为每个元素给出 Playwright 可用的定位符。
12
+
13
+ 与静态读 html 源码的区别:运行时渲染才能回答「这个元素用户到底看不看得到、点不点得动」。 MiniUI 等框架会把声明式标记渲染成复杂 DOM,权限控制会让部分元素渲染时隐藏,脚本会动态创建新元素——这些只有渲染结果能告诉我们。如果用户同时提供了页面源 html,本技能会做双证据比对:
14
+
15
+ - `both`:源码声明且渲染确认 —— 最可信
16
+ - `runtime-only`:渲染时才出现(脚本动态创建)—— 静态分析会漏掉
17
+ - `source-only`:源码声明但渲染时不可见(权限隐藏/逻辑移除)—— 对最终用户不可操作
18
+
19
+ ## 输入收集
20
+
21
+ 开始扫描前,向用户确认以下信息(能从上下文推断就不要再问):
22
+
23
+ 1. **目标 URL**(必填)。本地 html 文件用 `file:///` 绝对路径。
24
+ 2. **登录方式**(如需要):账号密码,或已有的 Playwright storage-state 文件。若当前目录是胶水/e2e 项目且有 `.env`(含 `LOGIN_SYSTEM_URL` / `LOGIN_USERNAME` / `LOGIN_PASSWORD`),直接读取复用,不要问用户要密码。
25
+ 3. **源 html 路径**(可选):有就给 `--source`,触发双证据比对。
26
+ 4. **输出位置**:默认 `./page-elements/` 下,`<页面名>.json` + `<页面名>.md`。
27
+
28
+ ## 执行步骤
29
+
30
+ 1. 确定一个安装了 playwright 的工作目录作为 `--project-dir`:当前项目根、或 `e2e-test/` 下任一胶水项目(它们的 node_modules 里有 playwright)。脚本用 `createRequire` 从该目录解析依赖。
31
+
32
+ 2. 运行扫描脚本(路径相对于本技能目录):
33
+
34
+ ```bash
35
+ node <技能目录>/scripts/scan-page.mjs \
36
+ --url "<目标URL>" \
37
+ --out "<输出>.json" --md "<输出>.md" \
38
+ --project-dir "<含playwright的目录>"
39
+ ```
40
+
41
+ 按需追加:
42
+ - 登录:`--login-url <登录页> --login-user <账号> --login-pass <密码>`(启发式填用户名密码框);启发式失败时用 `--login-user-selector` / `--login-pass-selector` / `--login-submit-selector` 显式指定。
43
+ - 登录态复用:`--storage-state <state.json>`。
44
+ - 双证据:`--source <页面源html>`。
45
+ - 渲染不充分时加大 `--wait 3000`;调试时 `--headed` 看浏览器实际行为。
46
+
47
+ 3. 脚本默认扫描主 frame 和所有子 frame(epoint 页面常嵌 iframe),每个元素的 `frame` 字段标注来源;跨域 frame 会自动跳过。
48
+
49
+ ## 结果呈现
50
+
51
+ 扫描完成后读 JSON,向用户汇报:
52
+
53
+ 1. **概览**:元素总数、可操作数、按类型分布(button / field / grid / tab / link)。
54
+ 2. **值得注意的发现**(这是盘点的价值所在,不要只报数字):
55
+ - 渲染时隐藏或禁用的元素(可能受权限/状态控制)
56
+ - `runtime-only` 元素(动态创建,静态分析发现不了)
57
+ - `source-only` 元素(声明了但用户看不到)
58
+ - grid 的行操作和列信息
59
+ 3. 文件路径,提示 JSON 里的 `locator` 可直接用于 Playwright 脚本。
60
+
61
+ ## 输出格式
62
+
63
+ JSON 结构:
64
+
65
+ ```json
66
+ {
67
+ "url": "...", "title": "...", "scannedAt": "...",
68
+ "summary": { "total": 42, "byType": {"button": 8, "field": 12}, "actionable": 35,
69
+ "hiddenAtRuntime": 2, "runtimeOnly": 3, "sourceOnly": 1 },
70
+ "dialogs": [{"trigger": "openChild", "title": "新增窗口", "pagePath": "xxx.html"}],
71
+ "elements": [
72
+ { "type": "button", "label": "新增", "locator": "xpath=//a[contains(@class,'mini-button')]...",
73
+ "visible": true, "enabled": true, "evidence": "both", "frame": "main" }
74
+ ]
75
+ }
76
+ ```
77
+
78
+ `dialogs` 仅 `--source` 模式产出(从 script 中解析 openTopDialog 调用)。
79
+
80
+ ## 边界与须知
81
+
82
+ - 「可操作」判定 = 可见(非 display:none、有尺寸)且可用(非 disabled)。默认输出过滤不可见元素,`--include-hidden` 可保留。
83
+ - 脚本不做交互(不点按钮、不开弹窗)。弹窗/二级页面内的元素需把对应 URL 再扫一遍,或先用 `--headed` 观察交互路径。
84
+ - 登录启发式覆盖常见登录页;复杂登录(验证码、SSO 跳转)失败时,让用户手动登录后用 `--storage-state` 重试。
85
+ - 元素去重键是 `type|label|locator`,同 label 不同类型控件不会合并。
86
+ - **已知覆盖范围**(已验证于真实 epoint MiniUI 页面):
87
+ - 按钮:MiniUI `a.mini-button`、epoint `a.cond-srh-btn`(搜索按钮)、原生 `button`、`[role=button]`
88
+ - 字段:`div[label]` 包装的 MiniUI 控件(textbox/combobox/buttonedit/datepicker/spinner)、原生 `input/select/textarea`
89
+ - Grid:`mini-datagrid` 的 `.mini-grid-headertxt` 列名 + `[data-tooltip]` 行操作图标
90
+ - 标签页:`.mini-tabs li`
91
+ - 噪音过滤:无 label 的分页跳页输入框(`pagination-number`)等无业务意义输入不输出
92
+ - **双证据实现说明**:源码侧使用 `DOMParser` 解析 HTML(不执行脚本),得到纯声明态 DOM;运行时侧用 Playwright 渲染;两者按 type+label 比对后标注 `both / runtime-only / source-only`。`setContent` 方案会执行内联脚本导致 evidence 误标,已废弃。
@@ -55,15 +55,18 @@ function assertSymlink(linkPath, targetPath) {
55
55
  }
56
56
  }
57
57
 
58
- // ep-stage scope 下四个 skill 的包内真相源目录。
58
+ // ep-stage scope 下全部六个 skill 的包内真相源目录。
59
59
  // 注:Task 0.2 已 git mv 改名 3 个 skill 目录(glue-* 前缀化)。
60
60
  // - glue-create-project:Task 2.1 已同步 SKILL.md frontmatter name → 'glue-create-project'。
61
61
  // - glue-generate-testcase:Task 3.2 已同步 SKILL.md frontmatter name → 'glue-generate-testcase'。
62
62
  // - glue-run-test:Task 4.3 已同步 SKILL.md frontmatter name → 'glue-run-test'。
63
+ // 2026-08-20:补登 code-list-generate / page-element-scan(此前漏登,frontmatter 不受校验)。
63
64
  const skillSources = [
65
+ { name: 'code-list-generate', source: path.join(epStageRoot, 'code-list-generate') },
64
66
  { name: 'glue-create-project', source: path.join(epStageRoot, 'glue-create-project') },
65
67
  { name: 'glue-generate-testcase', source: path.join(epStageRoot, 'glue-generate-testcase') },
66
68
  { name: 'glue-run-test', source: path.join(epStageRoot, 'glue-run-test') },
69
+ { name: 'page-element-scan', source: path.join(epStageRoot, 'page-element-scan') },
67
70
  { name: 'recording-to-glue', source: path.join(epStageRoot, 'recording-to-glue') },
68
71
  ];
69
72
 
@@ -497,7 +497,7 @@ export async function runRun(args, deps) {
497
497
  trace.results = [...resolvedResults, ...needsReviewResults];
498
498
  if (needsReviewResults.length > 0) {
499
499
  writeAiRuntimeTrace(tracePath, trace);
500
- const reportDir = path.join(paths.projectDir, 'e2e/glue-code-mvp/glue-report', new Date().toISOString().replace(/[:.]/g, '-'));
500
+ const reportDir = path.join(paths.projectDir, 'glue-report', new Date().toISOString().replace(/[:.]/g, '-'));
501
501
  mkdirSync(reportDir, { recursive: true });
502
502
  return {
503
503
  specPath: paths.specPath,
@@ -510,7 +510,7 @@ export async function runRun(args, deps) {
510
510
  appendAiSnippets(paths.specPath, aiRuntimeTasks, resolvedResults);
511
511
  writeAiRuntimeTrace(tracePath, trace);
512
512
  // 报告目录先于执行创建:json reporter 结果文件落这里,供 glue 风格综合报告渲染。
513
- const reportDir = path.join(paths.projectDir, 'e2e/glue-code-mvp/glue-report', new Date().toISOString().replace(/[:.]/g, '-'));
513
+ const reportDir = path.join(paths.projectDir, 'glue-report', new Date().toISOString().replace(/[:.]/g, '-'));
514
514
  mkdirSync(reportDir, { recursive: true });
515
515
  const resultsJsonPath = path.join(reportDir, 'playwright-results.json');
516
516
  // 执行完整 spec。
@@ -566,8 +566,8 @@ export async function runRun(args, deps) {
566
566
  specFile: paths.specPath,
567
567
  items: parsedResults.items,
568
568
  aiTasks: aiRuntimeTasks.map((task) => ({ title: task.title, caseId: task.caseId })),
569
- playwrightReportHref: '../../../../playwright-report/index.html',
570
- stageReportHref: '../../../../stage-report/report.pdf',
569
+ playwrightReportHref: '../../playwright-report/index.html',
570
+ stageReportHref: '../../stage-report/report.pdf',
571
571
  });
572
572
  comprehensiveReportPath = path.join(reportDir, 'index.html');
573
573
  writeFileSync(comprehensiveReportPath, html);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epoint-testtech/ep-stage-skill",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",