@epoint-testtech/ep-stage-skill 0.0.10 → 0.5.0-alpha.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/SKILL.md +27 -27
- package/codex-skill/ep-stage/glue-create-project/SKILL.md +223 -223
- package/codex-skill/ep-stage/glue-generate-testcase/SKILL.md +275 -275
- package/codex-skill/ep-stage/glue-generate-testcase/examples/observable-testcase.json +40 -40
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-schema.md +95 -95
- package/codex-skill/ep-stage/glue-run-test/SKILL.md +273 -296
- package/codex-skill/ep-stage/glue-run-test/references/ai-runtime-loop.md +30 -30
- package/codex-skill/ep-stage/glue-run-test/references/crud-pipeline.md +132 -132
- package/codex-skill/ep-stage/glue-run-test/references/gap-review-protocol.md +44 -44
- package/codex-skill/ep-stage/glue-run-test/references/harness-principles.md +46 -46
- package/codex-skill/ep-stage/glue-run-test/references/playwright-cli-odav.md +127 -166
- package/codex-skill/ep-stage/glue-run-test/scripts/generate-crud-spec.mjs +149 -149
- package/codex-skill/ep-stage/recording-to-glue/SKILL.md +28 -28
- package/codex-skill/ep-stage/scripts/validate-skill.mjs +95 -98
- package/dist/src/cli/generate-testcase.d.ts +0 -1
- package/dist/src/cli/generate-testcase.d.ts.map +1 -1
- package/dist/src/cli/generate-testcase.js +1 -6
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +14 -38
- package/dist/src/cli/run.d.ts +0 -2
- package/dist/src/cli/run.d.ts.map +1 -1
- package/dist/src/cli/run.js +21 -70
- package/dist/src/cli/spec.d.ts.map +1 -1
- package/dist/src/cli/spec.js +0 -9
- package/dist/src/contracts/glue-contract-v1.d.ts +0 -35
- package/dist/src/contracts/glue-contract-v1.d.ts.map +1 -1
- package/dist/src/extractors/code-list-json5.d.ts +1 -34
- package/dist/src/extractors/code-list-json5.d.ts.map +1 -1
- package/dist/src/extractors/code-list-json5.js +0 -1
- package/dist/src/extractors/html-page.d.ts +0 -9
- package/dist/src/extractors/html-page.d.ts.map +1 -1
- package/dist/src/extractors/html-page.js +2 -26
- package/dist/src/generators/agent-inferred-workflow-script.js +66 -66
- package/dist/src/generators/stage-skeleton-script.d.ts +0 -50
- package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -1
- package/dist/src/generators/stage-skeleton-script.js +116 -449
- package/dist/src/runtime/ai-runtime-trace.d.ts.map +1 -1
- package/dist/src/runtime/ai-runtime-trace.js +0 -8
- package/dist/src/testcase/contract-testcase-assembler.d.ts +0 -28
- package/dist/src/testcase/contract-testcase-assembler.d.ts.map +1 -1
- package/dist/src/testcase/contract-testcase-assembler.js +75 -329
- package/dist/src/validation/contract.d.ts.map +1 -1
- package/dist/src/validation/contract.js +0 -29
- package/dist/test/cli/generate-testcase-json5.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-json5.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-json5.test.js +154 -0
- package/dist/test/cli/index.test.d.ts +2 -0
- package/dist/test/cli/index.test.d.ts.map +1 -0
- package/dist/test/cli/index.test.js +114 -0
- package/dist/test/cli/run.test.d.ts +2 -0
- package/dist/test/cli/run.test.d.ts.map +1 -0
- package/dist/test/cli/run.test.js +429 -0
- package/dist/test/cli/spec.test.d.ts +2 -0
- package/dist/test/cli/spec.test.d.ts.map +1 -0
- package/dist/test/cli/spec.test.js +112 -0
- package/dist/test/code-list-json5.test.d.ts +2 -0
- package/dist/test/code-list-json5.test.d.ts.map +1 -0
- package/dist/test/code-list-json5.test.js +84 -0
- package/dist/test/code-list.test.d.ts +2 -0
- package/dist/test/code-list.test.d.ts.map +1 -0
- package/dist/test/code-list.test.js +39 -0
- package/dist/test/gap-inference.test.d.ts +2 -0
- package/dist/test/gap-inference.test.d.ts.map +1 -0
- package/dist/test/gap-inference.test.js +597 -0
- package/dist/test/generalization.test.d.ts +2 -0
- package/dist/test/generalization.test.d.ts.map +1 -0
- package/dist/test/generalization.test.js +73 -0
- package/dist/test/material-inventory.test.d.ts +2 -0
- package/dist/test/material-inventory.test.d.ts.map +1 -0
- package/dist/test/material-inventory.test.js +155 -0
- package/dist/test/observable-chain.test.d.ts +2 -0
- package/dist/test/observable-chain.test.d.ts.map +1 -0
- package/dist/test/observable-chain.test.js +123 -0
- package/dist/test/page-structure.test.d.ts +2 -0
- package/dist/test/page-structure.test.d.ts.map +1 -0
- package/dist/test/page-structure.test.js +45 -0
- package/dist/test/runtime/ai-runtime-trace.test.d.ts +2 -0
- package/dist/test/runtime/ai-runtime-trace.test.d.ts.map +1 -0
- package/dist/test/runtime/ai-runtime-trace.test.js +78 -0
- package/dist/test/scenario-inference.test.d.ts +2 -0
- package/dist/test/scenario-inference.test.d.ts.map +1 -0
- package/dist/test/scenario-inference.test.js +73 -0
- package/dist/test/stage-context.test.d.ts +2 -0
- package/dist/test/stage-context.test.d.ts.map +1 -0
- package/dist/test/stage-context.test.js +395 -0
- package/dist/test/testcase/testcase-markdown.test.d.ts +2 -0
- package/dist/test/testcase/testcase-markdown.test.d.ts.map +1 -0
- package/dist/test/testcase/testcase-markdown.test.js +48 -0
- package/dist/test/testcase-generator.test.d.ts +2 -0
- package/dist/test/testcase-generator.test.d.ts.map +1 -0
- package/dist/test/testcase-generator.test.js +276 -0
- package/dist/test/testcase-skeleton.test.d.ts +2 -0
- package/dist/test/testcase-skeleton.test.d.ts.map +1 -0
- package/dist/test/testcase-skeleton.test.js +185 -0
- package/dist/test/testcase-spec-assembly.test.d.ts +2 -0
- package/dist/test/testcase-spec-assembly.test.d.ts.map +1 -0
- package/dist/test/testcase-spec-assembly.test.js +105 -0
- package/dist/test/util/credentials.test.d.ts +2 -0
- package/dist/test/util/credentials.test.d.ts.map +1 -0
- package/dist/test/util/credentials.test.js +64 -0
- package/dist/test/util/i18n-testcase.test.d.ts +2 -0
- package/dist/test/util/i18n-testcase.test.d.ts.map +1 -0
- package/dist/test/util/i18n-testcase.test.js +119 -0
- package/dist/test/util/softlink.test.d.ts +2 -0
- package/dist/test/util/softlink.test.d.ts.map +1 -0
- package/dist/test/util/softlink.test.js +82 -0
- package/dist/test/validation/contract.test.d.ts +2 -0
- package/dist/test/validation/contract.test.d.ts.map +1 -0
- package/dist/test/validation/contract.test.js +116 -0
- package/dist/test/validation/credentials.test.d.ts +2 -0
- package/dist/test/validation/credentials.test.d.ts.map +1 -0
- package/dist/test/validation/credentials.test.js +74 -0
- package/dist/test/validation/projects-index.test.d.ts +2 -0
- package/dist/test/validation/projects-index.test.d.ts.map +1 -0
- package/dist/test/validation/projects-index.test.js +48 -0
- package/dist/test/validation/testcase-v1-draft.test.d.ts +2 -0
- package/dist/test/validation/testcase-v1-draft.test.d.ts.map +1 -0
- package/dist/test/validation/testcase-v1-draft.test.js +173 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +7 -0
- package/docs/README.md +124 -124
- package/examples/schemeresource-observable-docs/schemeresource.context.md +20 -20
- package/examples/schemeresource.module-hints.json +38 -38
- package/examples/schemeresource.observable.code_list.md +37 -37
- package/examples/zwplace-observable-docs/zwplace.context.md +16 -16
- package/examples/zwplace-placecategory-validation.json +29 -29
- package/examples/zwplace.module-hints.json +69 -69
- package/examples/zwplace.observable.code_list.md +37 -37
- package/package.json +19 -13
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md +0 -72
- package/codex-skill/ep-stage/glue-run-test/scripts/extract-page-elements-eval.mjs +0 -233
- package/codex-skill/ep-stage/page-element-scan/SKILL.md +0 -91
- package/codex-skill/ep-stage/page-element-scan/evals/evals.json +0 -37
- package/codex-skill/ep-stage/page-element-scan/evals/fixtures/sample-list-page.html +0 -85
- package/codex-skill/ep-stage/page-element-scan/references/pagination-controls.md +0 -153
- package/codex-skill/ep-stage/page-element-scan/scripts/extract-page-elements-eval.mjs +0 -233
- package/codex-skill/ep-stage/page-element-scan/scripts/extract-page-elements.mjs +0 -298
- package/codex-skill/ep-stage/page-element-scan/scripts/scan-page.mjs +0 -749
- package/dist/src/cli/probe.d.ts +0 -46
- package/dist/src/cli/probe.d.ts.map +0 -1
- package/dist/src/cli/probe.js +0 -447
- package/dist/src/cli/run-report.d.ts +0 -46
- package/dist/src/cli/run-report.d.ts.map +0 -1
- package/dist/src/cli/run-report.js +0 -331
- package/dist/src/extractors/prd-extractor.d.ts +0 -70
- package/dist/src/extractors/prd-extractor.d.ts.map +0 -1
- package/dist/src/extractors/prd-extractor.js +0 -248
- package/dist/src/testcase/button-interaction-inference.d.ts +0 -37
- package/dist/src/testcase/button-interaction-inference.d.ts.map +0 -1
- package/dist/src/testcase/button-interaction-inference.js +0 -385
- package/dist/src/testcase/prd-button-mapper.d.ts +0 -72
- package/dist/src/testcase/prd-button-mapper.d.ts.map +0 -1
- package/dist/src/testcase/prd-button-mapper.js +0 -148
- package/dist/src/testcase/testcase-v2.d.ts +0 -50
- package/dist/src/testcase/testcase-v2.d.ts.map +0 -1
- package/dist/src/testcase/testcase-v2.js +0 -1
- package/docs/mvp-usage-guide.md +0 -298
|
@@ -1,296 +1,273 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: glue-run-test
|
|
3
|
-
description: 使用时机:当用户对某需求要「跑测试 / 验证 / 端到端执行 / 跑胶水测试 / 看报告」或显式触发 `/glue-run-test <testcase.json5路径>` 时使用。
|
|
4
|
-
version: 2026-
|
|
5
|
-
argument-hint: "<testcase.json5绝对/相对路径>"
|
|
6
|
-
compatibility: 需要由 stage-create 生成的 glue 模式 Playwright 项目 + 已审过的 `testcase.json5` + 同目录 `credentials.json5`。
|
|
7
|
-
metadata:
|
|
8
|
-
source-package: "@epoint-testtech/ep-stage-skill"
|
|
9
|
-
contract: "crud-business-module/v1"
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# ep-stage: glue-run-test
|
|
13
|
-
|
|
14
|
-
本 skill 编排 `@epoint-testtech/ep-stage-skill` CLI 与 Agent Runtime。分工固定:
|
|
15
|
-
|
|
16
|
-
1. 用户入口只收 `/glue-run-test <testcase.json5路径>`。
|
|
17
|
-
2. CLI `prepare-tasks` 只做确定性工作:定位项目、补组装 glue 骨架、生成 `.ep-stage/ai-runtime-trace.json5` 任务包。
|
|
18
|
-
3. Agent 读取 trace tasks,使用 playwright-cli 观察和操作真实页面,按 O-D-A-V 产出 `.ep-stage/ai-snippets.json5`。
|
|
19
|
-
4. CLI `run` 只读取 Agent 产出的 resolved snippets,幂等追加到 `AI_APPEND_MARKER` 后并执行完整 spec。
|
|
20
|
-
5. 缺少真实 resolved snippet 时,CLI 只写 `needs_review` trace,不追加占位代码、不执行 Playwright,避免假通过。
|
|
21
|
-
6. 失败时写 `.ep-stage/repair-runs/<round>/repair-report.md` 并回写 trace.repairRounds,等待人审确认修补方向。
|
|
22
|
-
|
|
23
|
-
skill 负责:路径解析、必要前置校验、任务清单打印、结果回显。用户视角全中文,不暴露 CLI 名称。
|
|
24
|
-
|
|
25
|
-
> 钻探已前置:上游钻探、contract 提取、coverage 分析、`uncoveredCandidates` 推断由 `/glue-generate-testcase` 完成。本 skill 只消费 `testcase.json5` 和 `.ep-stage/contract.json5`,不再自行钻探,不读取 `inference-trace.json`,也不对 contract 缺失槽位二次猜测。
|
|
26
|
-
>
|
|
27
|
-
> 修补边界:run 失败时先落 repair-report.md,等待用户确认修补方向后再重跑。不静默削弱断言、不改变 testcase 意图。重跑读取更新后的 spec/testcase 重新进入状态机。
|
|
28
|
-
>
|
|
29
|
-
> 详细状态机和修补边界见 references/ai-runtime-loop.md。
|
|
30
|
-
|
|
31
|
-
## 1. 自然语言映射
|
|
32
|
-
|
|
33
|
-
```text
|
|
34
|
-
/glue-run-test /abs/path/.../src/tests/014-测试需求10-20260622/testcase.json5
|
|
35
|
-
/glue-run-test ../glue-project/src/tests/014-测试需求10-20260622/testcase.json5
|
|
36
|
-
/glue-run-test # 无参数 → 问 testcase.json5 路径
|
|
37
|
-
/glue-run-test /abs/path/.../testcase.json5 --debug # 调试模式 → 跑本地 ep-stage-skill dist
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
> `--debug` flag:正常调用走远程 `npx @epoint-testtech/ep-stage-skill@latest`。开发期想测试未发布的本地代码时传 `--debug`,skill 在 Step 4/Step 6 都改用 `node <repo>/packages/ep-stage-skill/dist/src/cli/index.js`:先跑 `prepare-tasks --testcase ...`,Agent 产出 `ai-snippets.json5` 后再跑 `run --testcase ... --ai-snippets ...`。前提:cwd 在 ep-stage monorepo 内(向上能找到 `pnpm-workspace.yaml`);找不到时直接 exit 1 报错,不静默 fallback 到 npx。
|
|
41
|
-
|
|
42
|
-
skill 把入参 `path.resolve` 绝对化,直接消费 `testcase.json5`。用户心智只保留这一个入口,不要求先显式跑 `spec` 再跑 `run`。
|
|
43
|
-
|
|
44
|
-
## 2. Agent 执行剧本(7 步任务清单协议)
|
|
45
|
-
|
|
46
|
-
**任务清单协议(REQ-UX-01)**:load
|
|
47
|
-
|
|
48
|
-
### Step 0 — 打印任务清单
|
|
49
|
-
|
|
50
|
-
```markdown
|
|
51
|
-
**执行胶水测试任务清单**
|
|
52
|
-
|
|
53
|
-
- [ ] 第 1 步 — 解析 testcase.json5 路径并定位测试项目
|
|
54
|
-
- [ ] 第 2 步 — 校验 testcase.json5 输入
|
|
55
|
-
- [ ] 第 3 步 — 校验 credentials.json5 凭据
|
|
56
|
-
- [ ] 第 4 步 — 调用 prepare-tasks 输出 AI 任务包
|
|
57
|
-
- [ ] 第 5 步 — Agent 使用 playwright-cli 完成 O-D-A-V 并写 ai-snippets.json5
|
|
58
|
-
- [ ] 第 6 步 — 调用 run CLI 合并 snippet 并执行完整 spec
|
|
59
|
-
- [ ] 第 7 步 — 收集 spec、trace 与报告产物并输出摘要
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Step 1 — 解析 testcase.json5 路径并定位测试项目
|
|
63
|
-
|
|
64
|
-
- 从用户消息 / args 抽取 `testcase.json5` 路径,绝对化。入参缺失 → free text 询问"请给我 testcase.json5 的绝对或相对路径"。
|
|
65
|
-
- 优先读取 `testcase.json5.runtimeContext.testProjectDir / specPath`;若缺失或校验失败,再从 testcase 所在目录向上查找 `package.json + playwright.config.ts + src/skeletons`。
|
|
66
|
-
- 中文复述识别结果:"已识别:testcase.json5 = `<abs>`,项目目录 = `<projectDir>`,spec = `<specPath>`"。
|
|
67
|
-
|
|
68
|
-
### Step 2 — 校验 testcase.json5 输入(缺 → 引导 B)
|
|
69
|
-
|
|
70
|
-
校验 `<projectDir>/src/tests/<需求名>/testcase.json5` 是否存在,且 `schemaVersion` 字段存在且合法。
|
|
71
|
-
|
|
72
|
-
缺失 / schema 不合法 → 引导场景 B,AskUserQuestion 三选一:
|
|
73
|
-
|
|
74
|
-
1. 跑 `/glue-generate-testcase <code_list.json5路径>`:先生成用例,回头再跑 run。
|
|
75
|
-
2. 跳过用例直接组装(不推荐):警告"无 testcase 时 run 内部也无法自动补出有效 glue 骨架",确认后继续。
|
|
76
|
-
3. 取消:直接退出,不调 CLI。
|
|
77
|
-
|
|
78
|
-
### Step 3 — 校验 credentials.json5 凭据(缺 → 引导 C)
|
|
79
|
-
|
|
80
|
-
校验 `<projectDir>/src/tests/<需求名>/credentials.json5` 存在,数组至少 1 条,且每条 `url / username / password` 非空。
|
|
81
|
-
|
|
82
|
-
缺失 / 字段空 → 引导场景 C,先读 `~/.ep-stage/projects.index.json5` 的 `systems[].credentialsCache`,按 `url` 比对算 `cachedSystemsHit`。AskUserQuestion 三选一:
|
|
83
|
-
|
|
84
|
-
1. 从全局缓存复用(仅 `cachedSystemsHit` 非空时显示):列出命中的 url + 已缓存角色,自动拼出 `credentials.json5`(缺失角色用占位符保留)。
|
|
85
|
-
2. 现在补:skill 顺序问每条角色的 URL / username / password / systemName(free text),直接写 `<需求名>/credentials.json5`。
|
|
86
|
-
3. 取消:直接退出,不调 CLI。
|
|
87
|
-
|
|
88
|
-
### Step 4 — 调用 prepare-tasks 输出 AI 任务包
|
|
89
|
-
|
|
90
|
-
固定流程:不 which、不扫 monorepo、不 cd、不喂 stdin。用户入口仍只保留 `/glue-run-test <testcase.json5路径>`,但内部先调用 CLI `prepare-tasks`。
|
|
91
|
-
|
|
92
|
-
正常模式:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
npx -y @epoint-testtech/ep-stage-skill@latest prepare-tasks \
|
|
96
|
-
--testcase <projectDir>/src/tests/<需求名>/testcase.json5
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
调试模式:
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
D="$PWD"; REPO=""
|
|
103
|
-
while [ "$D" != "/" ]; do
|
|
104
|
-
if [ -f "$D/pnpm-workspace.yaml" ] && [ -f "$D/packages/ep-stage-skill/dist/src/cli/index.js" ]; then
|
|
105
|
-
REPO="$D"; break
|
|
106
|
-
fi
|
|
107
|
-
D="$(dirname "$D")"
|
|
108
|
-
done
|
|
109
|
-
[ -z "$REPO" ] && { echo "错误:--debug 但找不到本地 monorepo"; exit 1; }
|
|
110
|
-
echo "调试模式:本地 $REPO/packages/ep-stage-skill/dist/src/cli/index.js"
|
|
111
|
-
node "$REPO/packages/ep-stage-skill/dist/src/cli/index.js" prepare-tasks \
|
|
112
|
-
--testcase <projectDir>/src/tests/<需求名>/testcase.json5
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
CLI prepare-tasks 行为:
|
|
116
|
-
|
|
117
|
-
1. 解析 `runtimeContext` 或向上查找测试项目;若 `crud.spec.ts` 不存在,先自动补跑 `spec` 生成 glue 骨架。
|
|
118
|
-
2. 构建 AI Runtime Tasks:取 `uncoveredCandidates` 中 `generationStrategy="ai"` 且 `coverageStatus!="blocked"` 的候选;`blocked` 候选不进入后续步骤。
|
|
119
|
-
3. 写 `<caseDir>/.ep-stage/ai-runtime-trace.json5`:`tasks` 就绪,`results` 为空。
|
|
120
|
-
4. 输出 trace 路径、spec 路径、AI task 数量和 blocked 数量。
|
|
121
|
-
|
|
122
|
-
CLI 非 0 退出 → 复述 stderr,不进 Step 5。
|
|
123
|
-
|
|
124
|
-
### Step 5 — Agent 使用 playwright-cli 完成 O-D-A-V 并写 ai-snippets.json5
|
|
125
|
-
|
|
126
|
-
读取 `<caseDir>/.ep-stage/ai-runtime-trace.json5` 的 `tasks[]`。若任务数为 0,写一个空结果包:
|
|
127
|
-
|
|
128
|
-
```json5
|
|
129
|
-
{
|
|
130
|
-
schemaVersion: 'ep-stage-ai-snippets/v1',
|
|
131
|
-
testcasePath: '<testcase.json5绝对路径>',
|
|
132
|
-
generatedAt: '<ISO时间>',
|
|
133
|
-
results: [],
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
若存在任务,先跑 `which playwright-cli` 校验本机已安装官方 CLI(v0.1.15+ 起支持 coding agent one-shot 子命令 + daemon session 模型)。缺失 → 整包 `needs_review` 后退出。可用则读 `docs/00-memory/dev-rules.md`,再按 `references/playwright-cli-odav.md` 执行:
|
|
138
|
-
|
|
139
|
-
1. 生成一个命名 session:`SESSION="<moduleId>-$(date +%Y%m%d%H%M%S)"`,后续所有子命令都传 `-s=$SESSION`(daemon 保持浏览器 + cookies + localStorage 跨命令)。
|
|
140
|
-
2. 从 `testcase.json5.testAccess.requiredRoles[0]` 取 primary role,从 `credentials.json5` 匹配该角色的 `loginUrl / username / password`。跑 `playwright-cli -s=$SESSION open <loginUrl> --headed`(**必须 `--headed`**,人工旁观 O-D-A-V 过程;不允许无头默认,避免运行态钻探变成无监督黑盒)→ `snapshot` 读 accessibility tree yml 拿 refs → `fill <userRef> <username>` / `fill <passRef> <password>` / `click <loginRef>` → 再 `snapshot` 验证登录成功。可选 `state-save <caseDir>/.ep-stage/auth.json` 便于跨 session 复用。
|
|
141
|
-
3. `playwright-cli -s=$SESSION goto <contract.base.navigation.directUrl>` 直达列表页 → `snapshot` 观察 iframe 与初始 DOM。
|
|
142
|
-
4.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
3.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
|
210
|
-
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
>
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
##
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
## 8. 引导场景
|
|
276
|
-
|
|
277
|
-
- A(缺脚手架):Step 1 反查 projects.index.json5 无 glue 条目 → 提示先跑 `/glue-create-project` 退出。
|
|
278
|
-
- B(缺 testcase):Step 2 缺失 / schema 不合法 → AskUserQuestion 三选一(跑 testcase / 强组装 / 取消)。
|
|
279
|
-
- C(缺凭据):Step 3 字段空 → AskUserQuestion 三选一(缓存复用 / 现在补 / 取消)。
|
|
280
|
-
- D(缺 code_list.json5):归 `/glue-generate-testcase` 处理。
|
|
281
|
-
|
|
282
|
-
## 9. 按需加载
|
|
283
|
-
|
|
284
|
-
- AI Runtime Loop 状态机与修补边界:`references/ai-runtime-loop.md`
|
|
285
|
-
- CRUD 组装 pipeline + 失败归类:`references/crud-pipeline.md`
|
|
286
|
-
- harness 治理原则:`references/harness-principles.md`
|
|
287
|
-
- gap 评审协议:`references/gap-review-protocol.md`
|
|
288
|
-
|
|
289
|
-
## 10. 关键约束
|
|
290
|
-
|
|
291
|
-
- 钻探前置:本 skill 不再实现 contract 提取、coverage 分析、`uncoveredCandidates` 推断;这些在 `/glue-generate-testcase` 完成。
|
|
292
|
-
- 当前用户入口只保留 `/glue-run-test <testcase.json5路径>`;不要要求用户先显式跑 `spec`。
|
|
293
|
-
- Agent 对 AI 用例执行受控运行态推理并写 ai-snippets.json5;run 子命令只合并 resolved snippet 后执行完整 spec;失败时先落 repair-report.md 等待确认,不静默改变 testcase 意图。
|
|
294
|
-
- `coverageStatus="blocked"` 的候选不进入 AI Runtime Task、不写 trace、不进 spec 追加段。
|
|
295
|
-
- spec / run 都不得对 contract 缺失槽位二次猜测。
|
|
296
|
-
- 用户视角始终全中文;业务断言、selector、iframe 关键字、按钮文案均由骨架 + `contract.json5` 的 `scenario.skeletonSlots` 决策,skill 不发明。
|
|
1
|
+
---
|
|
2
|
+
name: glue-run-test
|
|
3
|
+
description: 使用时机:当用户对某需求要「跑测试 / 验证 / 端到端执行 / 跑胶水测试 / 看报告」或显式触发 `/glue-run-test <testcase.json5路径>` 时使用。
|
|
4
|
+
version: 2026-07-03+06ded5d
|
|
5
|
+
argument-hint: "<testcase.json5绝对/相对路径>"
|
|
6
|
+
compatibility: 需要由 stage-create 生成的 glue 模式 Playwright 项目 + 已审过的 `testcase.json5` + 同目录 `credentials.json5`。
|
|
7
|
+
metadata:
|
|
8
|
+
source-package: "@epoint-testtech/ep-stage-skill"
|
|
9
|
+
contract: "crud-business-module/v1"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ep-stage: glue-run-test
|
|
13
|
+
|
|
14
|
+
本 skill 编排 `@epoint-testtech/ep-stage-skill` CLI 与 Agent Runtime。分工固定:
|
|
15
|
+
|
|
16
|
+
1. 用户入口只收 `/glue-run-test <testcase.json5路径>`。
|
|
17
|
+
2. CLI `prepare-tasks` 只做确定性工作:定位项目、补组装 glue 骨架、生成 `.ep-stage/ai-runtime-trace.json5` 任务包。
|
|
18
|
+
3. Agent 读取 trace tasks,使用 playwright-cli 观察和操作真实页面,按 O-D-A-V 产出 `.ep-stage/ai-snippets.json5`。
|
|
19
|
+
4. CLI `run` 只读取 Agent 产出的 resolved snippets,幂等追加到 `AI_APPEND_MARKER` 后并执行完整 spec。
|
|
20
|
+
5. 缺少真实 resolved snippet 时,CLI 只写 `needs_review` trace,不追加占位代码、不执行 Playwright,避免假通过。
|
|
21
|
+
6. 失败时写 `.ep-stage/repair-runs/<round>/repair-report.md` 并回写 trace.repairRounds,等待人审确认修补方向。
|
|
22
|
+
|
|
23
|
+
skill 负责:路径解析、必要前置校验、任务清单打印、结果回显。用户视角全中文,不暴露 CLI 名称。
|
|
24
|
+
|
|
25
|
+
> 钻探已前置:上游钻探、contract 提取、coverage 分析、`uncoveredCandidates` 推断由 `/glue-generate-testcase` 完成。本 skill 只消费 `testcase.json5` 和 `.ep-stage/contract.json5`,不再自行钻探,不读取 `inference-trace.json`,也不对 contract 缺失槽位二次猜测。
|
|
26
|
+
>
|
|
27
|
+
> 修补边界:run 失败时先落 repair-report.md,等待用户确认修补方向后再重跑。不静默削弱断言、不改变 testcase 意图。重跑读取更新后的 spec/testcase 重新进入状态机。
|
|
28
|
+
>
|
|
29
|
+
> 详细状态机和修补边界见 references/ai-runtime-loop.md。
|
|
30
|
+
|
|
31
|
+
## 1. 自然语言映射
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
/glue-run-test /abs/path/.../src/tests/014-测试需求10-20260622/testcase.json5
|
|
35
|
+
/glue-run-test ../glue-project/src/tests/014-测试需求10-20260622/testcase.json5
|
|
36
|
+
/glue-run-test # 无参数 → 问 testcase.json5 路径
|
|
37
|
+
/glue-run-test /abs/path/.../testcase.json5 --debug # 调试模式 → 跑本地 ep-stage-skill dist
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> `--debug` flag:正常调用走远程 `npx @epoint-testtech/ep-stage-skill@latest`。开发期想测试未发布的本地代码时传 `--debug`,skill 在 Step 4/Step 6 都改用 `node <repo>/packages/ep-stage-skill/dist/src/cli/index.js`:先跑 `prepare-tasks --testcase ...`,Agent 产出 `ai-snippets.json5` 后再跑 `run --testcase ... --ai-snippets ...`。前提:cwd 在 ep-stage monorepo 内(向上能找到 `pnpm-workspace.yaml`);找不到时直接 exit 1 报错,不静默 fallback 到 npx。
|
|
41
|
+
|
|
42
|
+
skill 把入参 `path.resolve` 绝对化,直接消费 `testcase.json5`。用户心智只保留这一个入口,不要求先显式跑 `spec` 再跑 `run`。
|
|
43
|
+
|
|
44
|
+
## 2. Agent 执行剧本(7 步任务清单协议)
|
|
45
|
+
|
|
46
|
+
**任务清单协议(REQ-UX-01)**:load 后立即打印初始任务清单(Step 0);每完成一步输出单行 `第 N 步 — <中文名> 已完成,进入第 N+1 步 — <下一中文名>...`;Step 7 输出全勾选终态清单 + 摘要(spec 路径 + trace 路径 + 报告路径)。
|
|
47
|
+
|
|
48
|
+
### Step 0 — 打印任务清单
|
|
49
|
+
|
|
50
|
+
```markdown
|
|
51
|
+
**执行胶水测试任务清单**
|
|
52
|
+
|
|
53
|
+
- [ ] 第 1 步 — 解析 testcase.json5 路径并定位测试项目
|
|
54
|
+
- [ ] 第 2 步 — 校验 testcase.json5 输入
|
|
55
|
+
- [ ] 第 3 步 — 校验 credentials.json5 凭据
|
|
56
|
+
- [ ] 第 4 步 — 调用 prepare-tasks 输出 AI 任务包
|
|
57
|
+
- [ ] 第 5 步 — Agent 使用 playwright-cli 完成 O-D-A-V 并写 ai-snippets.json5
|
|
58
|
+
- [ ] 第 6 步 — 调用 run CLI 合并 snippet 并执行完整 spec
|
|
59
|
+
- [ ] 第 7 步 — 收集 spec、trace 与报告产物并输出摘要
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Step 1 — 解析 testcase.json5 路径并定位测试项目
|
|
63
|
+
|
|
64
|
+
- 从用户消息 / args 抽取 `testcase.json5` 路径,绝对化。入参缺失 → free text 询问"请给我 testcase.json5 的绝对或相对路径"。
|
|
65
|
+
- 优先读取 `testcase.json5.runtimeContext.testProjectDir / specPath`;若缺失或校验失败,再从 testcase 所在目录向上查找 `package.json + playwright.config.ts + src/skeletons`。
|
|
66
|
+
- 中文复述识别结果:"已识别:testcase.json5 = `<abs>`,项目目录 = `<projectDir>`,spec = `<specPath>`"。
|
|
67
|
+
|
|
68
|
+
### Step 2 — 校验 testcase.json5 输入(缺 → 引导 B)
|
|
69
|
+
|
|
70
|
+
校验 `<projectDir>/src/tests/<需求名>/testcase.json5` 是否存在,且 `schemaVersion` 字段存在且合法。
|
|
71
|
+
|
|
72
|
+
缺失 / schema 不合法 → 引导场景 B,AskUserQuestion 三选一:
|
|
73
|
+
|
|
74
|
+
1. 跑 `/glue-generate-testcase <code_list.json5路径>`:先生成用例,回头再跑 run。
|
|
75
|
+
2. 跳过用例直接组装(不推荐):警告"无 testcase 时 run 内部也无法自动补出有效 glue 骨架",确认后继续。
|
|
76
|
+
3. 取消:直接退出,不调 CLI。
|
|
77
|
+
|
|
78
|
+
### Step 3 — 校验 credentials.json5 凭据(缺 → 引导 C)
|
|
79
|
+
|
|
80
|
+
校验 `<projectDir>/src/tests/<需求名>/credentials.json5` 存在,数组至少 1 条,且每条 `url / username / password` 非空。
|
|
81
|
+
|
|
82
|
+
缺失 / 字段空 → 引导场景 C,先读 `~/.ep-stage/projects.index.json5` 的 `systems[].credentialsCache`,按 `url` 比对算 `cachedSystemsHit`。AskUserQuestion 三选一:
|
|
83
|
+
|
|
84
|
+
1. 从全局缓存复用(仅 `cachedSystemsHit` 非空时显示):列出命中的 url + 已缓存角色,自动拼出 `credentials.json5`(缺失角色用占位符保留)。
|
|
85
|
+
2. 现在补:skill 顺序问每条角色的 URL / username / password / systemName(free text),直接写 `<需求名>/credentials.json5`。
|
|
86
|
+
3. 取消:直接退出,不调 CLI。
|
|
87
|
+
|
|
88
|
+
### Step 4 — 调用 prepare-tasks 输出 AI 任务包
|
|
89
|
+
|
|
90
|
+
固定流程:不 which、不扫 monorepo、不 cd、不喂 stdin。用户入口仍只保留 `/glue-run-test <testcase.json5路径>`,但内部先调用 CLI `prepare-tasks`。
|
|
91
|
+
|
|
92
|
+
正常模式:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx -y @epoint-testtech/ep-stage-skill@latest prepare-tasks \
|
|
96
|
+
--testcase <projectDir>/src/tests/<需求名>/testcase.json5
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
调试模式:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
D="$PWD"; REPO=""
|
|
103
|
+
while [ "$D" != "/" ]; do
|
|
104
|
+
if [ -f "$D/pnpm-workspace.yaml" ] && [ -f "$D/packages/ep-stage-skill/dist/src/cli/index.js" ]; then
|
|
105
|
+
REPO="$D"; break
|
|
106
|
+
fi
|
|
107
|
+
D="$(dirname "$D")"
|
|
108
|
+
done
|
|
109
|
+
[ -z "$REPO" ] && { echo "错误:--debug 但找不到本地 monorepo"; exit 1; }
|
|
110
|
+
echo "调试模式:本地 $REPO/packages/ep-stage-skill/dist/src/cli/index.js"
|
|
111
|
+
node "$REPO/packages/ep-stage-skill/dist/src/cli/index.js" prepare-tasks \
|
|
112
|
+
--testcase <projectDir>/src/tests/<需求名>/testcase.json5
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
CLI prepare-tasks 行为:
|
|
116
|
+
|
|
117
|
+
1. 解析 `runtimeContext` 或向上查找测试项目;若 `crud.spec.ts` 不存在,先自动补跑 `spec` 生成 glue 骨架。
|
|
118
|
+
2. 构建 AI Runtime Tasks:取 `uncoveredCandidates` 中 `generationStrategy="ai"` 且 `coverageStatus!="blocked"` 的候选;`blocked` 候选不进入后续步骤。
|
|
119
|
+
3. 写 `<caseDir>/.ep-stage/ai-runtime-trace.json5`:`tasks` 就绪,`results` 为空。
|
|
120
|
+
4. 输出 trace 路径、spec 路径、AI task 数量和 blocked 数量。
|
|
121
|
+
|
|
122
|
+
CLI 非 0 退出 → 复述 stderr,不进 Step 5。
|
|
123
|
+
|
|
124
|
+
### Step 5 — Agent 使用 playwright-cli 完成 O-D-A-V 并写 ai-snippets.json5
|
|
125
|
+
|
|
126
|
+
读取 `<caseDir>/.ep-stage/ai-runtime-trace.json5` 的 `tasks[]`。若任务数为 0,写一个空结果包:
|
|
127
|
+
|
|
128
|
+
```json5
|
|
129
|
+
{
|
|
130
|
+
schemaVersion: 'ep-stage-ai-snippets/v1',
|
|
131
|
+
testcasePath: '<testcase.json5绝对路径>',
|
|
132
|
+
generatedAt: '<ISO时间>',
|
|
133
|
+
results: [],
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
若存在任务,先跑 `which playwright-cli` 校验本机已安装官方 CLI(v0.1.15+ 起支持 coding agent one-shot 子命令 + daemon session 模型)。缺失 → 整包 `needs_review` 后退出。可用则读 `docs/00-memory/dev-rules.md`,再按 `references/playwright-cli-odav.md` 执行:
|
|
138
|
+
|
|
139
|
+
1. 生成一个命名 session:`SESSION="<moduleId>-$(date +%Y%m%d%H%M%S)"`,后续所有子命令都传 `-s=$SESSION`(daemon 保持浏览器 + cookies + localStorage 跨命令)。
|
|
140
|
+
2. 从 `testcase.json5.testAccess.requiredRoles[0]` 取 primary role,从 `credentials.json5` 匹配该角色的 `loginUrl / username / password`。跑 `playwright-cli -s=$SESSION open <loginUrl> --headed`(**必须 `--headed`**,人工旁观 O-D-A-V 过程;不允许无头默认,避免运行态钻探变成无监督黑盒)→ `snapshot` 读 accessibility tree yml 拿 refs → `fill <userRef> <username>` / `fill <passRef> <password>` / `click <loginRef>` → 再 `snapshot` 验证登录成功。可选 `state-save <caseDir>/.ep-stage/auth.json` 便于跨 session 复用。
|
|
141
|
+
3. `playwright-cli -s=$SESSION goto <contract.base.navigation.directUrl>` 直达列表页 → `snapshot` 观察 iframe 与初始 DOM。
|
|
142
|
+
4. 对每条 task 做 O-D-A-V:`snapshot` 观察 → 推理决策 → `click <ref>` / `fill <ref> <text>` / `select <ref> <val>` 动作 → `snapshot` 或 `eval "<js>"` 验证并抽取断言值。**refs 每次 snapshot 后重新编号,禁止跨 snapshot 缓存**。
|
|
143
|
+
5. Agent 按 `dev-rules.md` 把观察 + 动作原料改写为符合本项目规范的 `test()` snippet(`repo*` 前缀、锚点作用域、复用 crud.spec.ts 已声明的 `directListUrl / credentialsPath / primaryRole / crudSlots / exportSlots` 常量,不重复声明)。
|
|
144
|
+
6. 写 `<caseDir>/.ep-stage/ai-snippets.json5`,格式 `{ schemaVersion, testcasePath, generatedAt, results }`;每条 result 的 `evidence` 保留 `source: 'playwright-cli'` + snapshot yml 路径,支撑可观测性 gate。
|
|
145
|
+
7. 全部 task 完成后跑 `playwright-cli -s=$SESSION close` 释放 session(异常时 `playwright-cli kill-all` 兜底)。
|
|
146
|
+
|
|
147
|
+
宿主 Agent 无 `playwright-cli`、目标系统网络不可达、testcase 信息不足或断言无法确认时,不强造 snippet;对应 result 标 `needs_review`,并在 observation/evidence 中写明原因。
|
|
148
|
+
|
|
149
|
+
### Step 6 — 调用 run CLI 合并 snippet 并执行完整 spec
|
|
150
|
+
|
|
151
|
+
正常模式:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npx -y @epoint-testtech/ep-stage-skill@latest run \
|
|
155
|
+
--testcase <projectDir>/src/tests/<需求名>/testcase.json5 \
|
|
156
|
+
--ai-snippets <projectDir>/src/tests/<需求名>/.ep-stage/ai-snippets.json5 \
|
|
157
|
+
--headless false
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
调试模式:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
node "$REPO/packages/ep-stage-skill/dist/src/cli/index.js" run \
|
|
164
|
+
--testcase <projectDir>/src/tests/<需求名>/testcase.json5 \
|
|
165
|
+
--ai-snippets <projectDir>/src/tests/<需求名>/.ep-stage/ai-snippets.json5 \
|
|
166
|
+
--headless false
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
CLI run 行为:
|
|
170
|
+
|
|
171
|
+
1. 读取 ai-snippets.json5;只合并 `status="resolved"` 且 `specSnippet` 非空、caseId 属于当前 tasks 的结果。
|
|
172
|
+
2. 若存在 AI tasks 但缺少完整 resolved snippet,写 trace `needs_review` 后停止,不追加占位代码、不执行 Playwright。
|
|
173
|
+
3. 若 snippets 完整,定位 `AI_APPEND_MARKER` 截断旧追加段,按任务顺序追加 snippets。
|
|
174
|
+
4. 从 `projectDir` 跑 `npx playwright test <specPath>`,`headless=false` 时带 `--headed`。
|
|
175
|
+
5. 失败时归类并写 `.ep-stage/repair-runs/<round>/repair-report.md`,同时回写 `trace.repairRounds`。
|
|
176
|
+
|
|
177
|
+
CLI 非 0 退出 → 复述 stderr,不进 Step 7。
|
|
178
|
+
|
|
179
|
+
### Step 7 — 收集 spec、trace 与报告产物并输出摘要
|
|
180
|
+
|
|
181
|
+
用 `ls` / `Read` 校验 §3 验证清单。成功信号:
|
|
182
|
+
|
|
183
|
+
- `crud.spec.ts` 已存在;若原先缺失,说明 prepare-tasks 已自动补组装。
|
|
184
|
+
- `ai-runtime-trace.json5` 已落盘且含 tasks + results;若 results 含 `needs_review`,按原因提示继续 Agent O-D-A-V。
|
|
185
|
+
- `ai-snippets.json5` 已落盘;resolved 结果已合并到 spec,needs_review 结果不会合并。
|
|
186
|
+
- 报告目录已创建。
|
|
187
|
+
- 成功路径不落 repair report;若失败,`.ep-stage/repair-runs/<round>/repair-report.md` 存在,按 §4 引导人审确认修补方向。
|
|
188
|
+
- 若 CLI 返回 `credentialsNotice`,按原文回显给用户。
|
|
189
|
+
|
|
190
|
+
## 3. 验证清单
|
|
191
|
+
|
|
192
|
+
| 路径 | 说明 |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `<projectDir>/src/tests/<需求名>/crud.spec.ts` | prepare-tasks 自动补组装 glue 骨架;run 在 `AI_APPEND_MARKER` 后合并 Agent snippet(幂等) |
|
|
195
|
+
| `<projectDir>/src/tests/<需求名>/testcase.json5` | 必须存在 + `schemaVersion` 合法 |
|
|
196
|
+
| `<projectDir>/src/tests/<需求名>/credentials.json5` | 必须存在 + 数组 ≥ 1 条 + 必填字段非空 |
|
|
197
|
+
| `<projectDir>/src/tests/<需求名>/.ep-stage/contract.json5` | 由 testcase 阶段产,run 阶段只读不写 |
|
|
198
|
+
| `<projectDir>/src/tests/<需求名>/.ep-stage/ai-runtime-trace.json5` | prepare-tasks 先写 tasks;run 回写 results / repairRounds |
|
|
199
|
+
| `<projectDir>/src/tests/<需求名>/.ep-stage/repair-runs/<round>/repair-report.md` | 失败时才产;含失败分类与摘要,待人审确认 |
|
|
200
|
+
| `e2e/glue-code-mvp/glue-report/<run-timestamp>/` | run 子命令产;执行结果账本目录 |
|
|
201
|
+
|
|
202
|
+
## 4. 错误处理
|
|
203
|
+
|
|
204
|
+
| 触发时机 | Agent 中文呈现 + 建议 |
|
|
205
|
+
|---|---|
|
|
206
|
+
| 引导 A(缺脚手架) | 中文提示+退出,引导先跑 `/glue-create-project <项目名>` |
|
|
207
|
+
| 引导 B(缺 testcase) | AskUserQuestion 三选一:跑 testcase / 强组装 / 取消(schema 不合法归入此类) |
|
|
208
|
+
| 引导 C(缺凭据) | AskUserQuestion 三选一:缓存复用 / 现在补 / 取消 |
|
|
209
|
+
| prepare-tasks / run 子命令 exit ≠ 0 | 复述 stderr;若缺 spec,也可能是 prepare-tasks 自动补跑 spec 失败 |
|
|
210
|
+
| glue cases 为空 | 阻断 prepare-tasks 内部 spec 组装;提示用户回 `/glue-generate-testcase` 补齐 |
|
|
211
|
+
| Playwright 执行失败 | 回显 `repairReportPath` 与失败分类;建议用户确认修补方向后重跑 `/glue-run-test <testcase.json5路径>`,不静默改 testcase |
|
|
212
|
+
| 用户中途取消 | AskUserQuestion 阶段说「算了/取消」立即终止;CLI 启动后等其退出再复述 |
|
|
213
|
+
|
|
214
|
+
## 5. 完成提示
|
|
215
|
+
|
|
216
|
+
Step 7 全部通过后,按以下中文格式呈现:
|
|
217
|
+
|
|
218
|
+
> 胶水测试执行完成
|
|
219
|
+
>
|
|
220
|
+
> 需求:`<需求名>`/项目:`<projectDir>`
|
|
221
|
+
> Spec:`<projectDir>/src/tests/<需求名>/crud.spec.ts`(glue 骨架 + Agent snippet 合并)
|
|
222
|
+
> AI Runtime Trace:`<projectDir>/src/tests/<需求名>/.ep-stage/ai-runtime-trace.json5`
|
|
223
|
+
> 报告目录:`e2e/glue-code-mvp/glue-report/<run-timestamp>/`
|
|
224
|
+
> 运行版本:`version = v1`
|
|
225
|
+
>
|
|
226
|
+
> 下一步:① 调整 `testcase.json5` / `contract.json5` 后重跑 `/glue-run-test <testcase.json5路径>`;② 失败时查看 repair-report.md 确认修补方向后再重跑。
|
|
227
|
+
|
|
228
|
+
失败时不要发完成提示:Playwright 失败已落 repair-report.md,按 §4 引导人审确认修补方向,不允许混合"执行完成"字样。
|
|
229
|
+
|
|
230
|
+
## 6. 产物生命周期
|
|
231
|
+
|
|
232
|
+
| 层 | 文件内容 | 由谁产 |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| glue 骨架 | 顶部 `// === 胶水模式生成 ===`,只含 glue cases | `spec` 子命令,或 `prepare-tasks` 内部自动补跑 |
|
|
235
|
+
| AI 推理结果 | `.ep-stage/ai-snippets.json5`,由 Agent Runtime O-D-A-V 产出 | Agent + playwright-cli |
|
|
236
|
+
| AI snippet 追加 | `AI_APPEND_MARKER` 后的 snippet,由 run 子命令按 ai-snippets.json5 合并 | `run` 子命令 |
|
|
237
|
+
| trace | `.ep-stage/ai-runtime-trace.json5`,prepare-tasks 写 tasks,run 回写 results / repairRounds | `prepare-tasks` + `run` 子命令 |
|
|
238
|
+
| repair report | `.ep-stage/repair-runs/<round>/repair-report.md`,失败分类 + 摘要 | `run` 子命令(仅失败) |
|
|
239
|
+
|
|
240
|
+
重跑幂等:AI 追加段在 `AI_APPEND_MARKER` 处截断旧段后重新追加,不堆积。
|
|
241
|
+
|
|
242
|
+
## 7. 内嵌数据契约范例
|
|
243
|
+
|
|
244
|
+
`<需求名>/credentials.json5`:
|
|
245
|
+
|
|
246
|
+
```json5
|
|
247
|
+
[ { url: "<请填登录页 URL>", username: "<请填>", password: "<请填>", role: "业务管理员" } ]
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
字段约束:必填 `url / username / password`;可选 `role / systemName`;数组至少 1 条;同 `(url, role)` 组合唯一;文件 gitignore。
|
|
251
|
+
|
|
252
|
+
## 8. 引导场景
|
|
253
|
+
|
|
254
|
+
- A(缺脚手架):Step 1 反查 projects.index.json5 无 glue 条目 → 提示先跑 `/glue-create-project` 退出。
|
|
255
|
+
- B(缺 testcase):Step 2 缺失 / schema 不合法 → AskUserQuestion 三选一(跑 testcase / 强组装 / 取消)。
|
|
256
|
+
- C(缺凭据):Step 3 字段空 → AskUserQuestion 三选一(缓存复用 / 现在补 / 取消)。
|
|
257
|
+
- D(缺 code_list.json5):归 `/glue-generate-testcase` 处理。
|
|
258
|
+
|
|
259
|
+
## 9. 按需加载
|
|
260
|
+
|
|
261
|
+
- AI Runtime Loop 状态机与修补边界:`references/ai-runtime-loop.md`
|
|
262
|
+
- CRUD 组装 pipeline + 失败归类:`references/crud-pipeline.md`
|
|
263
|
+
- harness 治理原则:`references/harness-principles.md`
|
|
264
|
+
- gap 评审协议:`references/gap-review-protocol.md`
|
|
265
|
+
|
|
266
|
+
## 10. 关键约束
|
|
267
|
+
|
|
268
|
+
- 钻探前置:本 skill 不再实现 contract 提取、coverage 分析、`uncoveredCandidates` 推断;这些在 `/glue-generate-testcase` 完成。
|
|
269
|
+
- 当前用户入口只保留 `/glue-run-test <testcase.json5路径>`;不要要求用户先显式跑 `spec`。
|
|
270
|
+
- Agent 对 AI 用例执行受控运行态推理并写 ai-snippets.json5;run 子命令只合并 resolved snippet 后执行完整 spec;失败时先落 repair-report.md 等待确认,不静默改变 testcase 意图。
|
|
271
|
+
- `coverageStatus="blocked"` 的候选不进入 AI Runtime Task、不写 trace、不进 spec 追加段。
|
|
272
|
+
- spec / run 都不得对 contract 缺失槽位二次猜测。
|
|
273
|
+
- 用户视角始终全中文;业务断言、selector、iframe 关键字、按钮文案均由骨架 + `contract.json5` 的 `scenario.skeletonSlots` 决策,skill 不发明。
|