@epoint-testtech/ep-stage-skill 0.0.3-alpha.1
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 -0
- package/codex-skill/ep-stage/create-project/SKILL.md +59 -0
- package/codex-skill/ep-stage/glue-test/SKILL.md +258 -0
- package/codex-skill/ep-stage/glue-test/references/crud-pipeline.md +139 -0
- package/codex-skill/ep-stage/glue-test/references/gap-review-protocol.md +43 -0
- package/codex-skill/ep-stage/glue-test/references/harness-principles.md +46 -0
- package/codex-skill/ep-stage/glue-test/scripts/generate-crud-spec.mjs +149 -0
- package/codex-skill/ep-stage/glue-testcase/SKILL.md +31 -0
- package/codex-skill/ep-stage/glue-testcase/examples/observable-testcase.json +40 -0
- package/codex-skill/ep-stage/glue-testcase/references/testcase-schema.md +67 -0
- package/codex-skill/ep-stage/recording-to-glue/SKILL.md +27 -0
- package/codex-skill/ep-stage/scripts/validate-skill.mjs +73 -0
- package/dist/src/capability/coverage-diff.d.ts +34 -0
- package/dist/src/capability/coverage-diff.d.ts.map +1 -0
- package/dist/src/capability/coverage-diff.js +91 -0
- package/dist/src/capability/page-structure.d.ts +31 -0
- package/dist/src/capability/page-structure.d.ts.map +1 -0
- package/dist/src/capability/page-structure.js +50 -0
- package/dist/src/capability/scenario-inference.d.ts +36 -0
- package/dist/src/capability/scenario-inference.d.ts.map +1 -0
- package/dist/src/capability/scenario-inference.js +114 -0
- package/dist/src/cli/generate-crud-contract.d.ts +2 -0
- package/dist/src/cli/generate-crud-contract.d.ts.map +1 -0
- package/dist/src/cli/generate-crud-contract.js +77 -0
- package/dist/src/cli/generate-playwright-tests.d.ts +30 -0
- package/dist/src/cli/generate-playwright-tests.d.ts.map +1 -0
- package/dist/src/cli/generate-playwright-tests.js +81 -0
- package/dist/src/cli/run-gap-pipeline.d.ts +256 -0
- package/dist/src/cli/run-gap-pipeline.d.ts.map +1 -0
- package/dist/src/cli/run-gap-pipeline.js +1468 -0
- package/dist/src/context/stage-context.d.ts +63 -0
- package/dist/src/context/stage-context.d.ts.map +1 -0
- package/dist/src/context/stage-context.js +297 -0
- package/dist/src/contracts/crud-business-module.d.ts +645 -0
- package/dist/src/contracts/crud-business-module.d.ts.map +1 -0
- package/dist/src/contracts/crud-business-module.js +1 -0
- package/dist/src/contracts/gap-inference.d.ts +213 -0
- package/dist/src/contracts/gap-inference.d.ts.map +1 -0
- package/dist/src/contracts/gap-inference.js +11 -0
- package/dist/src/contracts/observable-chain.d.ts +250 -0
- package/dist/src/contracts/observable-chain.d.ts.map +1 -0
- package/dist/src/contracts/observable-chain.js +1 -0
- package/dist/src/extractors/code-list.d.ts +40 -0
- package/dist/src/extractors/code-list.d.ts.map +1 -0
- package/dist/src/extractors/code-list.js +225 -0
- package/dist/src/extractors/html-page.d.ts +67 -0
- package/dist/src/extractors/html-page.d.ts.map +1 -0
- package/dist/src/extractors/html-page.js +195 -0
- package/dist/src/extractors/java-action.d.ts +8 -0
- package/dist/src/extractors/java-action.d.ts.map +1 -0
- package/dist/src/extractors/java-action.js +53 -0
- package/dist/src/extractors/spec-yaml.d.ts +28 -0
- package/dist/src/extractors/spec-yaml.d.ts.map +1 -0
- package/dist/src/extractors/spec-yaml.js +29 -0
- package/dist/src/gap-planner/action-candidates.d.ts +9 -0
- package/dist/src/gap-planner/action-candidates.d.ts.map +1 -0
- package/dist/src/gap-planner/action-candidates.js +66 -0
- package/dist/src/gap-planner/list-gap-workflows.d.ts +17 -0
- package/dist/src/gap-planner/list-gap-workflows.d.ts.map +1 -0
- package/dist/src/gap-planner/list-gap-workflows.js +47 -0
- package/dist/src/gap-planner/plan-agent-workflows.d.ts +26 -0
- package/dist/src/gap-planner/plan-agent-workflows.d.ts.map +1 -0
- package/dist/src/gap-planner/plan-agent-workflows.js +116 -0
- package/dist/src/gap-planner/skeleton-coverage.d.ts +9 -0
- package/dist/src/gap-planner/skeleton-coverage.d.ts.map +1 -0
- package/dist/src/gap-planner/skeleton-coverage.js +41 -0
- package/dist/src/gap-planner/stable-id.d.ts +16 -0
- package/dist/src/gap-planner/stable-id.d.ts.map +1 -0
- package/dist/src/gap-planner/stable-id.js +19 -0
- package/dist/src/generalization/generalization-eval.d.ts +71 -0
- package/dist/src/generalization/generalization-eval.d.ts.map +1 -0
- package/dist/src/generalization/generalization-eval.js +53 -0
- package/dist/src/generators/agent-inferred-workflow-script.d.ts +22 -0
- package/dist/src/generators/agent-inferred-workflow-script.d.ts.map +1 -0
- package/dist/src/generators/agent-inferred-workflow-script.js +230 -0
- package/dist/src/generators/stage-skeleton-script.d.ts +107 -0
- package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -0
- package/dist/src/generators/stage-skeleton-script.js +607 -0
- package/dist/src/index.d.ts +52 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/material/material-inventory.d.ts +92 -0
- package/dist/src/material/material-inventory.d.ts.map +1 -0
- package/dist/src/material/material-inventory.js +191 -0
- package/dist/src/normalizers/crud-contract.d.ts +107 -0
- package/dist/src/normalizers/crud-contract.d.ts.map +1 -0
- package/dist/src/normalizers/crud-contract.js +1068 -0
- package/dist/src/testcase/testcase-generator.d.ts +43 -0
- package/dist/src/testcase/testcase-generator.d.ts.map +1 -0
- package/dist/src/testcase/testcase-generator.js +152 -0
- package/dist/src/testcase/testcase-skeleton.d.ts +91 -0
- package/dist/src/testcase/testcase-skeleton.d.ts.map +1 -0
- package/dist/src/testcase/testcase-skeleton.js +121 -0
- package/dist/src/testcase/testcase-spec-assembly.d.ts +11 -0
- package/dist/src/testcase/testcase-spec-assembly.d.ts.map +1 -0
- package/dist/src/testcase/testcase-spec-assembly.js +24 -0
- package/dist/src/trace/review-summary.d.ts +17 -0
- package/dist/src/trace/review-summary.d.ts.map +1 -0
- package/dist/src/trace/review-summary.js +34 -0
- package/dist/src/trace/trace-writer.d.ts +17 -0
- package/dist/src/trace/trace-writer.d.ts.map +1 -0
- package/dist/src/trace/trace-writer.js +81 -0
- package/dist/test/crud-contract.test.d.ts +2 -0
- package/dist/test/crud-contract.test.d.ts.map +1 -0
- package/dist/test/crud-contract.test.js +819 -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 +141 -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/observable-pipeline.test.d.ts +2 -0
- package/dist/test/observable-pipeline.test.d.ts.map +1 -0
- package/dist/test/observable-pipeline.test.js +461 -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/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 +263 -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/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 +134 -0
- package/docs/mvp-usage-guide.md +298 -0
- package/examples/schemeresource-observable-docs/schemeresource.context.md +20 -0
- package/examples/schemeresource.module-hints.json +38 -0
- package/examples/schemeresource.observable.code_list.md +37 -0
- package/examples/zwplace-observable-docs/zwplace.context.md +16 -0
- package/examples/zwplace-placecategory-validation.json +29 -0
- package/examples/zwplace.module-hints.json +69 -0
- package/examples/zwplace.observable.code_list.md +37 -0
- package/package.json +38 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# glue-test CRUD 契约生成器 — MVP 使用手册
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
`glue-test` 是一个 TypeScript agent skill,用于从上游业务模块物料中提取结构化信息,归一化为 `crud-business-module/v1` 契约 JSON。该契约作为 AI Agent 生成 Playwright 测试脚本的地基,确保 Agent 不需要自己编造 selector、按钮文本或业务预期。
|
|
6
|
+
|
|
7
|
+
当前 MVP 只面向公司自研 `zwplace` CRUD 场景,负责:
|
|
8
|
+
|
|
9
|
+
- 确定性提取:从 `spec.yaml`、HTML、`code_list.md`、Java Action 中抽取结构事实。
|
|
10
|
+
- 策略补齐:通过 `ModuleHints` 显式补充 `dataKey`、数据生成策略、按钮别名、auto-fill 覆盖字段、删除策略和断言策略。
|
|
11
|
+
|
|
12
|
+
当前 MVP 已包含胶水模板骨架测试代码组装,但不负责直接替代骨架中的登录、菜单和 CRUD 模块实现。
|
|
13
|
+
|
|
14
|
+
## 数据流
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
上游物料 glue-test 输出
|
|
18
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
19
|
+
│ HTML 页面 │──extractor──→ │ │ │ │
|
|
20
|
+
│ spec.yaml │──extractor──→ │ normalizer │──CLI 输出──→ │ 契约 JSON │
|
|
21
|
+
│ code_list.md │──extractor──→ │ │ │ │
|
|
22
|
+
│ Java Action │──extractor──→ │ │ │ │
|
|
23
|
+
└──────────────┘ └──────────────┘ └──────────────┘
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 前置条件
|
|
27
|
+
|
|
28
|
+
- Node.js 18+(注意:Node v24 下 `--module` 与 Node 内置 flag 冲突,需用 `tsx` 直接调用)
|
|
29
|
+
- pnpm 10+
|
|
30
|
+
|
|
31
|
+
## 安装
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd src/test-glue
|
|
35
|
+
pnpm install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 快速开始
|
|
39
|
+
|
|
40
|
+
### 1. 运行 CLI 生成契约
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd src/test-glue
|
|
44
|
+
|
|
45
|
+
# 方式一:通过 pnpm script
|
|
46
|
+
pnpm generate:crud-contract -- \
|
|
47
|
+
--module-id zwplace \
|
|
48
|
+
--docs ../../knowledge-project/epoint-web-v9.5.2/_docs/003-场所窗口信息管理-20260518 \
|
|
49
|
+
--code-list ../../knowledge-project/epoint-web-v9.5.2/_bmad-output/code_list.md \
|
|
50
|
+
--webapp ../../knowledge-project/epoint-web-v9.5.2/src/webapp/perpage/zwplace \
|
|
51
|
+
--java-actions ../../knowledge-project/epoint-web-v9.5.2/src/main/java/com/epoint/zwplace/action \
|
|
52
|
+
--hints examples/zwplace.module-hints.json \
|
|
53
|
+
--out output/zwplace.crud.contract.json
|
|
54
|
+
|
|
55
|
+
# 方式二:直接用 tsx
|
|
56
|
+
npx tsx src/cli/generate-crud-contract.ts \
|
|
57
|
+
--module-id zwplace \
|
|
58
|
+
--docs ../../knowledge-project/epoint-web-v9.5.2/_docs/003-场所窗口信息管理-20260518 \
|
|
59
|
+
--code-list ../../knowledge-project/epoint-web-v9.5.2/_bmad-output/code_list.md \
|
|
60
|
+
--webapp ../../knowledge-project/epoint-web-v9.5.2/src/webapp/perpage/zwplace \
|
|
61
|
+
--java-actions ../../knowledge-project/epoint-web-v9.5.2/src/main/java/com/epoint/zwplace/action \
|
|
62
|
+
--hints examples/zwplace.module-hints.json \
|
|
63
|
+
--out output/zwplace.crud.contract.json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
输出:`Wrote output/zwplace.crud.contract.json`
|
|
67
|
+
|
|
68
|
+
### 1.1 `ModuleHints` 示例
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"dataKey": {
|
|
73
|
+
"selectedField": "placename",
|
|
74
|
+
"generationStrategy": "timestamp_prefix"
|
|
75
|
+
},
|
|
76
|
+
"autofill": {
|
|
77
|
+
"overrideFields": [
|
|
78
|
+
{
|
|
79
|
+
"field": "placename",
|
|
80
|
+
"strategy": "timestamp_prefix",
|
|
81
|
+
"value": "自动化测试场所名称"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"deletePolicy": "blocked_by_business_rule"
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
建议直接从 [examples/zwplace.module-hints.json](/Users/taurus/0-ws/01-work-repo/test-tech/BG-ZW/stage-glue/src/test-glue/examples/zwplace.module-hints.json) 起步。
|
|
90
|
+
|
|
91
|
+
### 2. 生成胶水模板测试脚本
|
|
92
|
+
|
|
93
|
+
在契约生成后,直接生成调用骨架模块的 Playwright `.spec.ts`:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm generate:playwright-tests -- \
|
|
97
|
+
--contract output/zwplace.crud.contract.json \
|
|
98
|
+
--out ../stage-project/src/tests/generated-zwplace.skeleton.spec.ts \
|
|
99
|
+
--menu "场所窗口信息管理>场所窗口信息列表"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
参数说明:
|
|
103
|
+
|
|
104
|
+
| 参数 | 必填 | 说明 |
|
|
105
|
+
|------|------|------|
|
|
106
|
+
| `--contract` | 是 | 契约 JSON 文件路径 |
|
|
107
|
+
| `--out` | 是 | 输出 `.spec.ts` 文件路径 |
|
|
108
|
+
| `--menu` | 是 | 菜单路径,传给 `MenuPage.navigateToMenu()` |
|
|
109
|
+
|
|
110
|
+
输出示例(片段):
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { test } from '@playwright/test';
|
|
114
|
+
import { CrudPage, LoginPage, MenuPage } from '../skeletons';
|
|
115
|
+
|
|
116
|
+
test('zwplace CRUD 胶水生成链路', async ({ page }) => {
|
|
117
|
+
const loginPage = new LoginPage(page);
|
|
118
|
+
const menuPage = new MenuPage(page);
|
|
119
|
+
const crudPage = new CrudPage(page, crudSlots);
|
|
120
|
+
|
|
121
|
+
await loginPage.login();
|
|
122
|
+
await menuPage.navigateToMenu('场所窗口信息管理>场所窗口信息列表');
|
|
123
|
+
await crudPage.runCrudFlow();
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
先做编译验证:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd ../stage-project
|
|
131
|
+
pnpm exec tsc --noEmit
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
再执行 Playwright:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx playwright test src/tests/generated-zwplace.skeleton.spec.ts
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 2. 检查契约内容
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cat output/zwplace.crud.contract.json | head -20
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 3. 检查 unresolvedSlots
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cat output/zwplace.crud.contract.json | python3 -c "
|
|
150
|
+
import json,sys
|
|
151
|
+
d=json.load(sys.stdin)
|
|
152
|
+
for s in d['unresolvedSlots']:
|
|
153
|
+
print(f\"[{s['slotId']}] {s['reason']}\")
|
|
154
|
+
print(f\" 需要由: {s['expectedProvider']} 提供\")
|
|
155
|
+
print(f\" 格式建议: {s['suggestedFormat']}\")
|
|
156
|
+
"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## CLI 参数说明
|
|
160
|
+
|
|
161
|
+
| 参数 | 必填 | 说明 |
|
|
162
|
+
|------|------|------|
|
|
163
|
+
| `--module-id` | 是 | 模块 ID(如 `zwplace`),作为契约中 `module.id` 的权威值 |
|
|
164
|
+
| `--docs` | 是 | 需求文档目录路径,需包含 `spec.yaml` |
|
|
165
|
+
| `--code-list` | 是 | `_bmad-output/code_list.md` 文件路径 |
|
|
166
|
+
| `--webapp` | 是 | webapp 页面目录路径(含 `.html` 文件) |
|
|
167
|
+
| `--java-actions` | 是 | Java Action 源码目录路径(含 `*Action.java` 文件) |
|
|
168
|
+
| `--hints` | 否 | `ModuleHints` JSON 文件路径,用于补充测试策略槽位 |
|
|
169
|
+
| `--out` | 是 | 输出 JSON 文件路径(父目录不存在会自动创建) |
|
|
170
|
+
|
|
171
|
+
## 契约结构
|
|
172
|
+
|
|
173
|
+
生成的 JSON 契约遵循 `crud-business-module/v1` 版本,顶层结构:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"contractVersion": "crud-business-module/v1",
|
|
178
|
+
"module": { "id": "zwplace", "label": "场所信息管理" },
|
|
179
|
+
"pages": { "list": {...}, "add": {...}, "edit": {...}, "detail": {...} },
|
|
180
|
+
"dataKey": { "field": "placename", "label": "场所名称", "availability": "derivable", ... },
|
|
181
|
+
"flows": { "create": {...}, "search": {...}, "update": {...}, "delete": {...} },
|
|
182
|
+
"assertions": [...],
|
|
183
|
+
"businessRules": [...],
|
|
184
|
+
"unresolvedSlots": [...]
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 核心字段说明
|
|
189
|
+
|
|
190
|
+
**pages** — 四个 CRUD 页面的结构化描述:
|
|
191
|
+
|
|
192
|
+
| 字段 | 说明 |
|
|
193
|
+
|------|------|
|
|
194
|
+
| `fields` | 页面表单字段(含 locator、controlType、bind、required) |
|
|
195
|
+
| `buttons` | 页面按钮(含 XPath locator) |
|
|
196
|
+
| `grids` | 数据表格(含列定义) |
|
|
197
|
+
| `dialogs` | 弹窗(含触发函数、标题、目标页) |
|
|
198
|
+
|
|
199
|
+
**dataKey** — 测试数据的关键标识:
|
|
200
|
+
|
|
201
|
+
| 字段 | 说明 |
|
|
202
|
+
|------|------|
|
|
203
|
+
| `field` | 唯一标识字段名(如 `placename`) |
|
|
204
|
+
| `generationStrategy` | 数据生成策略(`timestamp_prefix` / `fixed_value` / `external_data_pool`) |
|
|
205
|
+
| `availability` | 可获取性(`auto_extractable` / `derivable` / `human_required`) |
|
|
206
|
+
|
|
207
|
+
**flows** — 四个 CRUD 操作流程:
|
|
208
|
+
|
|
209
|
+
| 流程 | 关键内容 |
|
|
210
|
+
|------|----------|
|
|
211
|
+
| `create` | 入口按钮、目标页面、保存按钮、需要覆盖的字段 |
|
|
212
|
+
| `search` | 搜索字段、提交控件、结果表格 |
|
|
213
|
+
| `update` | 入口操作、目标页面、修改字段、保存按钮 |
|
|
214
|
+
| `delete` | 入口按钮、预期结果(`blocked_by_business_rule` / `success_delete`) |
|
|
215
|
+
|
|
216
|
+
**unresolvedSlots** — 需要人工补充的信息缺口:
|
|
217
|
+
|
|
218
|
+
每个 slot 包含 `slotId`(缺口标识)、`reason`(原因)、`expectedProvider`(应由谁补充:tester / developer / runtime_config)、`suggestedFormat`(建议格式)。
|
|
219
|
+
|
|
220
|
+
当前规则:
|
|
221
|
+
|
|
222
|
+
- 如果 `searchable` 字段不止一个,且没有 `ModuleHints.dataKey.selectedField`,则 `dataKey.selectedField` 必须进入 `unresolvedSlots`。
|
|
223
|
+
- 如果没有传入 `ModuleHints.dataKey.generationStrategy`、`ModuleHints.autofill.overrideFields`、`ModuleHints.deletePolicy`,对应策略槽位也必须进入 `unresolvedSlots`。
|
|
224
|
+
- 已由 `ModuleHints` 明确确认的策略槽位,不应再出现在 `unresolvedSlots`。
|
|
225
|
+
|
|
226
|
+
### 来源溯源(sources)
|
|
227
|
+
|
|
228
|
+
契约中每个字段都带有 `sources` 数组,记录信息来源:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"kind": "html",
|
|
233
|
+
"path": "../../knowledge-project/.../gxhzwplacelist.html",
|
|
234
|
+
"confidence": "high"
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
| kind | 说明 |
|
|
239
|
+
|------|------|
|
|
240
|
+
| `html` | 来自 HTML 页面 |
|
|
241
|
+
| `spec` | 来自 spec.yaml |
|
|
242
|
+
| `code_list` | 来自 code_list.md |
|
|
243
|
+
| `java_action` | 来自 Java Action 源码 |
|
|
244
|
+
| `human_required` | 找不到来源,需人工补充 |
|
|
245
|
+
|
|
246
|
+
## 编程接口
|
|
247
|
+
|
|
248
|
+
除了 CLI,也可以在 TypeScript 中直接调用:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import {
|
|
252
|
+
extractHtmlPage,
|
|
253
|
+
extractSpecYaml,
|
|
254
|
+
extractCodeListSummary,
|
|
255
|
+
extractJavaAction,
|
|
256
|
+
buildCrudBusinessModuleContract
|
|
257
|
+
} from './index.js';
|
|
258
|
+
|
|
259
|
+
const spec = extractSpecYaml('path/to/spec.yaml');
|
|
260
|
+
const codeList = extractCodeListSummary('path/to/code_list.md');
|
|
261
|
+
const pages = ['list.html', 'add.html'].map(f => extractHtmlPage(f));
|
|
262
|
+
const actions = ['ListAction.java'].map(f => extractJavaAction(f));
|
|
263
|
+
|
|
264
|
+
const contract = buildCrudBusinessModuleContract({
|
|
265
|
+
moduleId: 'zwplace',
|
|
266
|
+
spec,
|
|
267
|
+
codeList,
|
|
268
|
+
pages,
|
|
269
|
+
actions,
|
|
270
|
+
hints: {
|
|
271
|
+
dataKey: {
|
|
272
|
+
selectedField: 'placename',
|
|
273
|
+
generationStrategy: 'timestamp_prefix'
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## 运行测试
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
cd src/test-glue
|
|
283
|
+
|
|
284
|
+
# 运行全部测试
|
|
285
|
+
pnpm test
|
|
286
|
+
|
|
287
|
+
# 类型检查
|
|
288
|
+
pnpm typecheck
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
测试使用本地 `knowledge-project/` 中的真实 zwplace 物料,覆盖 extractor、normalizer 和 CLI 三个层面。
|
|
292
|
+
|
|
293
|
+
## 已知限制
|
|
294
|
+
|
|
295
|
+
1. **只覆盖 zwplace 同栈 CRUD**:当前不考虑外部技术栈,但已接入登录、菜单和 CRUD 骨架模块编排。
|
|
296
|
+
2. **策略值仍需显式输入**:`dataKey`、auto-fill 覆盖策略、删除预期、断言策略不能只靠源码结构盲猜。
|
|
297
|
+
3. **断言策略已消费**:`ModuleHints.assertionPolicy` 现影响 `buildAssertions` 输出,`afterCreate`/`afterDelete` 策略已生效。
|
|
298
|
+
4. **组装链路已切到骨架模式**:`pnpm generate:playwright-tests` 现在只生成基于 skeleton 的 `.spec.ts`,旧的平铺 `page.fill()` / `page.click()` 生成器已移除。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 方案资源文档可观测入口补充说明
|
|
2
|
+
|
|
3
|
+
本文件是 `packages/ep-stage-skill/examples/schemeresource.observable.code_list.md` 的配套文档物料,用于模拟
|
|
4
|
+
`stage-glue` 在交互补齐后,为 `code_list.md` 增补的可消费上下文。
|
|
5
|
+
|
|
6
|
+
## 当前确定信息
|
|
7
|
+
|
|
8
|
+
- 模块:方案资源文档(`schemeresource`)
|
|
9
|
+
- 菜单(当前模拟值):`方案资源文档>方案资源文档列表`
|
|
10
|
+
- 列表页标题:`方案资源文档列表`
|
|
11
|
+
- 当前结构判断:标准单列表 CRUD,列表页具备 `新增记录 / 删除选定 / 修改记录 / 详细信息`
|
|
12
|
+
- 已知约束:新增页要求上传附件,`类型` 字段来自下拉代码项 `方案资源类型`
|
|
13
|
+
- 已知删除策略:列表页 `deleteSelect()` 调用 `service.deleteByGuid(sel)`,成功后回调消息为 `成功删除!`,当前样例已写入 `deletePolicy=success_delete`
|
|
14
|
+
- 当前一期目标:先把第二个真实业务模块的 `code_list.md` 默认入口样例落出来,再在 e2e 中验证是否需要交互补齐附件、下拉值和菜单真值
|
|
15
|
+
|
|
16
|
+
## 备注
|
|
17
|
+
|
|
18
|
+
- 上游真实 HTML / Java Action 仍来自 `knowledge-project/epoint-web-v9.5.2`
|
|
19
|
+
- 当前样例的价值在于:让 `--code-list` 默认入口对第二个普通 CRUD 样本也可以只依赖一个可写文件完成物料扎口
|
|
20
|
+
- 本样例不预设附件文件、不猜测 `方案资源类型` 的实际取值;这些属于后续 e2e 联调时的交互补齐范围
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dataKey": {
|
|
3
|
+
"selectedField": "scheme_name",
|
|
4
|
+
"generationStrategy": "timestamp_prefix"
|
|
5
|
+
},
|
|
6
|
+
"searchConditions": [
|
|
7
|
+
{
|
|
8
|
+
"field": "scheme_name",
|
|
9
|
+
"component": "input",
|
|
10
|
+
"seedValue": "自动化测试方案资源",
|
|
11
|
+
"strategy": "timestamp_prefix",
|
|
12
|
+
"updatePrefix": "修改"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"buttonAliases": {
|
|
16
|
+
"create": ["新增记录", "新增"],
|
|
17
|
+
"saveAndClose": ["保存并关闭"],
|
|
18
|
+
"search": ["搜索", "查询"],
|
|
19
|
+
"edit": ["修改记录", "修改"],
|
|
20
|
+
"delete": ["删除选定"],
|
|
21
|
+
"confirm": ["确定"]
|
|
22
|
+
},
|
|
23
|
+
"autofill": {
|
|
24
|
+
"overrideFields": [
|
|
25
|
+
{
|
|
26
|
+
"field": "scheme_name",
|
|
27
|
+
"strategy": "timestamp_prefix",
|
|
28
|
+
"value": "自动化测试方案资源"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"deletePolicy": "success_delete",
|
|
33
|
+
"assertionPolicy": {
|
|
34
|
+
"afterCreate": "record_exists",
|
|
35
|
+
"afterUpdate": "record_exists",
|
|
36
|
+
"afterDelete": "toast_message"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# 方案资源文档代码清单
|
|
2
|
+
|
|
3
|
+
> 此文件用于模拟 `stage-glue` 在交互补齐后回写到 `code_list.md` 的结果。
|
|
4
|
+
> 当前样例面向 `schemeresource` 普通 CRUD;真实 e2e 时仍允许继续通过交互补齐菜单真值和业务种子值。
|
|
5
|
+
|
|
6
|
+
knowledgeRoot: ../../../knowledge-project/epoint-web-v9.5.2
|
|
7
|
+
menu: 方案资源文档>方案资源文档列表
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 已补齐入口字段
|
|
12
|
+
|
|
13
|
+
- `knowledgeRoot`:用于把 `code_list.md` 中的相对物料路径统一解析到真实上游物料根目录。
|
|
14
|
+
- `menu`:先给默认入口一个可消费的菜单路径,避免链路一开始就停在 menu gate。
|
|
15
|
+
- `./schemeresource.module-hints.json`:补齐当前已知的 `dataKey`、按钮别名、删除策略和断言策略;附件文件、下拉值等未确认业务值留待 e2e 交互补齐。
|
|
16
|
+
|
|
17
|
+
## 文档物料(模拟交互补齐后的可消费 docsDir)
|
|
18
|
+
|
|
19
|
+
- `./schemeresource-observable-docs/schemeresource.context.md`
|
|
20
|
+
|
|
21
|
+
## 前端文件
|
|
22
|
+
|
|
23
|
+
- `src/main/webapp/perpage/schemeresource/schemeresourcelist.html`
|
|
24
|
+
- `src/main/webapp/perpage/schemeresource/schemeresourceadd.html`
|
|
25
|
+
- `src/main/webapp/perpage/schemeresource/schemeresourceedit.html`
|
|
26
|
+
- `src/main/webapp/perpage/schemeresource/schemeresourcedetail.html`
|
|
27
|
+
|
|
28
|
+
## 后端文件
|
|
29
|
+
|
|
30
|
+
- `src/main/java/com/epoint/schemeresource/action/SchemeResourceListAction.java`
|
|
31
|
+
- `src/main/java/com/epoint/schemeresource/action/SchemeResourceAddAction.java`
|
|
32
|
+
- `src/main/java/com/epoint/schemeresource/action/SchemeResourceEditAction.java`
|
|
33
|
+
- `src/main/java/com/epoint/schemeresource/action/SchemeResourceDetailAction.java`
|
|
34
|
+
|
|
35
|
+
## 提示物料
|
|
36
|
+
|
|
37
|
+
- `./schemeresource.module-hints.json`
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 场所窗口信息管理可观测入口补充说明
|
|
2
|
+
|
|
3
|
+
本文件是 `packages/ep-stage-skill/examples/zwplace.observable.code_list.md` 的配套文档物料,用于模拟
|
|
4
|
+
`stage-glue` 在交互补齐后,为 `code_list.md` 增补的可消费上下文。
|
|
5
|
+
|
|
6
|
+
## 当前确定信息
|
|
7
|
+
|
|
8
|
+
- 模块:场所窗口信息管理(`zwplace`)
|
|
9
|
+
- 菜单:`场所窗口信息管理>场所窗口信息列表`
|
|
10
|
+
- 列表页标题:`场所信息管理列表`
|
|
11
|
+
- 当前一期目标:验证普通 CRUD 场景的可观测链路,不把嵌套 CRUD 写入正式契约
|
|
12
|
+
|
|
13
|
+
## 备注
|
|
14
|
+
|
|
15
|
+
- 上游真实 HTML / Java Action 仍来自 `knowledge-project/epoint-web-v9.5.2`
|
|
16
|
+
- 当前样例的价值在于:让 `--code-list` 默认入口可以只依赖一个可写文件完成物料扎口
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dataKey": {
|
|
3
|
+
"selectedField": "placecategory",
|
|
4
|
+
"generationStrategy": "timestamp_prefix"
|
|
5
|
+
},
|
|
6
|
+
"buttonAliases": {
|
|
7
|
+
"create": ["新增场所信息管理", "新增"],
|
|
8
|
+
"saveAndClose": ["保存并关闭"],
|
|
9
|
+
"search": ["搜索", "查询"],
|
|
10
|
+
"edit": ["修改", "编辑"],
|
|
11
|
+
"delete": ["删除选定"],
|
|
12
|
+
"confirm": ["确定"]
|
|
13
|
+
},
|
|
14
|
+
"autofill": {
|
|
15
|
+
"overrideFields": [
|
|
16
|
+
{
|
|
17
|
+
"field": "placecategory",
|
|
18
|
+
"strategy": "timestamp_prefix",
|
|
19
|
+
"value": "自动化测试场所分类"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"deletePolicy": "blocked_by_business_rule",
|
|
24
|
+
"assertionPolicy": {
|
|
25
|
+
"afterCreate": "record_exists",
|
|
26
|
+
"afterUpdate": "record_exists",
|
|
27
|
+
"afterDelete": "toast_message"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dataKey": {
|
|
3
|
+
"selectedField": "placename",
|
|
4
|
+
"generationStrategy": "timestamp_prefix"
|
|
5
|
+
},
|
|
6
|
+
"searchConditions": [
|
|
7
|
+
{
|
|
8
|
+
"field": "placename",
|
|
9
|
+
"component": "input",
|
|
10
|
+
"seedValue": "自动化测试名称",
|
|
11
|
+
"strategy": "timestamp_prefix",
|
|
12
|
+
"updatePrefix": "修改"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"field": "placecategory",
|
|
16
|
+
"component": "listbox",
|
|
17
|
+
"value": "条线大厅",
|
|
18
|
+
"createSelections": [
|
|
19
|
+
{
|
|
20
|
+
"field": "placecategory",
|
|
21
|
+
"value": "条线大厅"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"field": "status",
|
|
27
|
+
"component": "listbox",
|
|
28
|
+
"value": "在用",
|
|
29
|
+
"createSelections": [
|
|
30
|
+
{
|
|
31
|
+
"field": "placecategory",
|
|
32
|
+
"value": "条线大厅"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"buttonAliases": {
|
|
38
|
+
"create": ["新增场所信息管理", "新增"],
|
|
39
|
+
"saveAndClose": ["保存并关闭"],
|
|
40
|
+
"search": ["搜索", "查询"],
|
|
41
|
+
"edit": ["修改", "编辑"],
|
|
42
|
+
"delete": ["删除选定"],
|
|
43
|
+
"confirm": ["确定"]
|
|
44
|
+
},
|
|
45
|
+
"autofill": {
|
|
46
|
+
"overrideFields": [
|
|
47
|
+
{
|
|
48
|
+
"field": "placename",
|
|
49
|
+
"strategy": "timestamp_prefix",
|
|
50
|
+
"value": "自动化测试场所名称"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"deletePolicy": "blocked_by_business_rule",
|
|
55
|
+
"assertionPolicy": {
|
|
56
|
+
"afterCreate": "record_exists",
|
|
57
|
+
"afterUpdate": "record_exists",
|
|
58
|
+
"afterDelete": "toast_message"
|
|
59
|
+
},
|
|
60
|
+
"customWorkflows": [
|
|
61
|
+
{
|
|
62
|
+
"label": "同步窗口管理系统",
|
|
63
|
+
"actionAlias": ["同步窗口管理系统"],
|
|
64
|
+
"expectedIntent": "同步窗口管理系统数据",
|
|
65
|
+
"expectedAssertion": "同步完成",
|
|
66
|
+
"include": true
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# 场所窗口信息管理代码清单
|
|
2
|
+
|
|
3
|
+
> 此文件是 `knowledge-project/epoint-web-v9.5.2/_docs/code_list.md` 的**可写镜像**。
|
|
4
|
+
> 真实上游 `knowledge-project/.../_docs/code_list.md` 是当前唯一真相源;本文件只用于开发期模拟交互补齐后的回写结果,以及只读真相源无法落盘时的 e2e 入口验证。
|
|
5
|
+
|
|
6
|
+
knowledgeRoot: ../../../knowledge-project/epoint-web-v9.5.2
|
|
7
|
+
menu: 场所窗口信息管理>场所窗口信息列表
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 已补齐入口字段
|
|
12
|
+
|
|
13
|
+
- `knowledgeRoot`:用于把 `code_list.md` 中的相对物料路径统一解析到真实上游物料根目录。
|
|
14
|
+
- `menu`:用于默认入口直达菜单导航,避免链路停在菜单候选 gate。
|
|
15
|
+
- `./zwplace.module-hints.json`:用于补齐 `ModuleHints`,避免 custom workflow 只停留在 candidate。
|
|
16
|
+
|
|
17
|
+
## 文档物料(模拟交互补齐后的可消费 docsDir)
|
|
18
|
+
|
|
19
|
+
- `./zwplace-observable-docs/zwplace.context.md`
|
|
20
|
+
|
|
21
|
+
## 前端文件
|
|
22
|
+
|
|
23
|
+
- `src/main/webapp/perpage/zwplace/gxhzwplacelist.html`
|
|
24
|
+
- `src/main/webapp/perpage/zwplace/gxhzwplaceadd.html`
|
|
25
|
+
- `src/main/webapp/perpage/zwplace/gxhzwplaceedit.html`
|
|
26
|
+
- `src/main/webapp/perpage/zwplace/gxhzwplacedetail.html`
|
|
27
|
+
|
|
28
|
+
## 后端文件
|
|
29
|
+
|
|
30
|
+
- `src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java`
|
|
31
|
+
- `src/main/java/com/epoint/zwplace/action/GxhZwPlaceAddAction.java`
|
|
32
|
+
- `src/main/java/com/epoint/zwplace/action/GxhZwPlaceEditAction.java`
|
|
33
|
+
- `src/main/java/com/epoint/zwplace/action/GxhZwPlaceDetailAction.java`
|
|
34
|
+
|
|
35
|
+
## 提示物料
|
|
36
|
+
|
|
37
|
+
- `./zwplace.module-hints.json`
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@epoint-testtech/ep-stage-skill",
|
|
3
|
+
"version": "0.0.3-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"codex-skill",
|
|
10
|
+
"docs",
|
|
11
|
+
"examples",
|
|
12
|
+
"SKILL.md"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"registry": "https://registry.npmjs.org/"
|
|
17
|
+
},
|
|
18
|
+
"description": "Agent skills and TypeScript tools for ep-stage glue-code workflows.",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"cheerio": "^1.0.0",
|
|
21
|
+
"json5": "^2.2.3",
|
|
22
|
+
"yaml": "^2.8.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^25.9.1",
|
|
26
|
+
"tsx": "^4.20.0",
|
|
27
|
+
"typescript": "^6.0.3",
|
|
28
|
+
"vitest": "^4.0.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"generate:crud-contract": "node --import tsx src/cli/generate-crud-contract.ts",
|
|
35
|
+
"generate:playwright-tests": "node --import tsx src/cli/generate-playwright-tests.ts",
|
|
36
|
+
"run:gap-pipeline": "node --import tsx src/cli/run-gap-pipeline.ts"
|
|
37
|
+
}
|
|
38
|
+
}
|