@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,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 根据页面结构候选与骨架能力,返回该页面命中的 CRUD 能力列表。
|
|
3
|
+
*
|
|
4
|
+
* @param page - 单个页面结构摘要。
|
|
5
|
+
* @param skeletonCapabilities - 骨架能力列表。
|
|
6
|
+
* @returns 命中的 CRUD 能力(crud.create/read/update/delete)。
|
|
7
|
+
*/
|
|
8
|
+
function matchedCrudCapabilities(page, skeletonCapabilities) {
|
|
9
|
+
return [
|
|
10
|
+
...(page.createCandidate && skeletonCapabilities.includes('crud.create') ? ['crud.create'] : []),
|
|
11
|
+
...(page.readSearchCandidate && skeletonCapabilities.includes('crud.read') ? ['crud.read'] : []),
|
|
12
|
+
...(page.updateOrDetailCandidate && skeletonCapabilities.includes('crud.update') ? ['crud.update'] : []),
|
|
13
|
+
...(page.deleteCandidate && skeletonCapabilities.includes('crud.delete') ? ['crud.delete'] : []),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 把场景候选与页面结构证据组装成可审阅推理摘要。
|
|
18
|
+
*
|
|
19
|
+
* @param candidates - 已排好序的场景候选(首个为最高置信)。
|
|
20
|
+
* @param pages - 参与推理的页面结构摘要。
|
|
21
|
+
* @returns 推理摘要,needsHumanReview 恒为 true(场景推理默认需人工 confirm)。
|
|
22
|
+
*/
|
|
23
|
+
function buildReasoningSummary(candidates, pages) {
|
|
24
|
+
const top = candidates[0];
|
|
25
|
+
return {
|
|
26
|
+
conclusion: top ? `当前最高置信场景为 ${top.scenario}。` : '未识别到稳定场景。',
|
|
27
|
+
evidenceChain: pages.flatMap((page) => page.evidenceLabels.map((label) => ({
|
|
28
|
+
source: 'html',
|
|
29
|
+
path: page.pageId,
|
|
30
|
+
text: label,
|
|
31
|
+
}))),
|
|
32
|
+
alternatives: candidates.map((candidate) => candidate.scenario),
|
|
33
|
+
confidence: top?.confidence ?? 'low',
|
|
34
|
+
risks: candidates.flatMap((candidate) => candidate.unresolved),
|
|
35
|
+
needsHumanReview: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 根据页面结构候选生成场景推理结果。
|
|
40
|
+
*
|
|
41
|
+
* 候选优先级:嵌套 CRUD > 单页 CRUD > unknown。嵌套 CRUD 存在时单页 CRUD 降为中置信。
|
|
42
|
+
* 场景推理 gate 恒为 needs_review,需人工 confirm / correct / add-evidence / skip。
|
|
43
|
+
*
|
|
44
|
+
* @param input - 模块 id、页面结构摘要、骨架能力列表。
|
|
45
|
+
* @returns 场景推理 trace,含候选列表、gate 与推理摘要。
|
|
46
|
+
*/
|
|
47
|
+
export function inferPageScenarios(input) {
|
|
48
|
+
const nestedPages = input.pages.filter((page) => page.nestedCrudCandidate);
|
|
49
|
+
const listPages = input.pages.filter((page) => page.readSearchCandidate || page.createCandidate || page.deleteCandidate || page.updateOrDetailCandidate);
|
|
50
|
+
const candidates = [];
|
|
51
|
+
if (nestedPages.length > 0) {
|
|
52
|
+
candidates.push({
|
|
53
|
+
scenario: 'crud.nested',
|
|
54
|
+
confidence: 'medium',
|
|
55
|
+
evidenceRefs: nestedPages.flatMap((page) => page.evidenceLabels),
|
|
56
|
+
matchedSkeletonCapabilities: Array.from(new Set(nestedPages.flatMap((page) => matchedCrudCapabilities(page, input.skeletonCapabilities)))),
|
|
57
|
+
unresolved: Array.from(new Set(nestedPages.flatMap((page) => page.risks))),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (listPages.length > 0) {
|
|
61
|
+
candidates.push({
|
|
62
|
+
scenario: 'crud.single-page',
|
|
63
|
+
confidence: nestedPages.length > 0 ? 'medium' : 'high',
|
|
64
|
+
evidenceRefs: listPages.flatMap((page) => page.evidenceLabels),
|
|
65
|
+
matchedSkeletonCapabilities: Array.from(new Set(listPages.flatMap((page) => matchedCrudCapabilities(page, input.skeletonCapabilities)))),
|
|
66
|
+
unresolved: [],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (candidates.length === 0) {
|
|
70
|
+
candidates.push({
|
|
71
|
+
scenario: 'unknown',
|
|
72
|
+
confidence: 'low',
|
|
73
|
+
evidenceRefs: [],
|
|
74
|
+
matchedSkeletonCapabilities: [],
|
|
75
|
+
unresolved: ['缺少可解释页面结构证据'],
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
moduleId: input.moduleId,
|
|
80
|
+
candidates,
|
|
81
|
+
gate: { status: 'needs_review', reason: '场景推理结果需要人工 confirm / correct / add-evidence / skip。' },
|
|
82
|
+
reasoningSummary: buildReasoningSummary(candidates, input.pages),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 记录人工对场景推理的纠偏,标记需要重新推理。
|
|
87
|
+
*
|
|
88
|
+
* @param input.inference - 原始场景推理 trace。
|
|
89
|
+
* @param input.correction - 人工纠偏文本。
|
|
90
|
+
* @returns 更新后的 trace,gate 为 corrected,推理摘要追加人工证据。
|
|
91
|
+
*/
|
|
92
|
+
export function applyScenarioHumanCorrection(input) {
|
|
93
|
+
return {
|
|
94
|
+
...input.inference,
|
|
95
|
+
conversationReview: {
|
|
96
|
+
status: 'corrected',
|
|
97
|
+
humanCorrection: input.correction,
|
|
98
|
+
rerunRequired: true,
|
|
99
|
+
},
|
|
100
|
+
gate: {
|
|
101
|
+
status: 'corrected',
|
|
102
|
+
reason: '人工纠偏已记录,需要重新执行场景推理。',
|
|
103
|
+
correction: input.correction,
|
|
104
|
+
},
|
|
105
|
+
reasoningSummary: {
|
|
106
|
+
...input.inference.reasoningSummary,
|
|
107
|
+
evidenceChain: [
|
|
108
|
+
...input.inference.reasoningSummary.evidenceChain,
|
|
109
|
+
{ source: 'human', path: 'conversation', text: input.correction },
|
|
110
|
+
],
|
|
111
|
+
needsHumanReview: true,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-crud-contract.d.ts","sourceRoot":"","sources":["../../../src/cli/generate-crud-contract.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { buildCrudBusinessModuleContract, extractCodeListSummary, extractHtmlPage, extractJavaAction, extractSpecYaml } from '../index.js';
|
|
4
|
+
function parseArgs(argv) {
|
|
5
|
+
const result = {};
|
|
6
|
+
const normalizedArgv = argv.filter((arg) => arg !== '--');
|
|
7
|
+
for (let index = 0; index < normalizedArgv.length; index += 2) {
|
|
8
|
+
const key = normalizedArgv[index];
|
|
9
|
+
const value = normalizedArgv[index + 1];
|
|
10
|
+
if (!key?.startsWith('--') || !value) {
|
|
11
|
+
throw new Error(`Invalid argument pair near ${key ?? '<empty>'}`);
|
|
12
|
+
}
|
|
13
|
+
result[key.slice(2)] = value;
|
|
14
|
+
}
|
|
15
|
+
if (result.module) {
|
|
16
|
+
throw new Error('已废弃 --module,请使用 --module-id。' +
|
|
17
|
+
'例: pnpm generate:crud-contract -- --module-id zwplace ...');
|
|
18
|
+
}
|
|
19
|
+
const required = ['module-id', 'docs', 'code-list', 'webapp', 'java-actions', 'out'];
|
|
20
|
+
for (const key of required) {
|
|
21
|
+
if (!result[key]) {
|
|
22
|
+
throw new Error(`Missing required argument --${key}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
module: result['module-id'],
|
|
27
|
+
docs: result.docs,
|
|
28
|
+
codeList: result['code-list'],
|
|
29
|
+
webapp: result.webapp,
|
|
30
|
+
javaActions: result['java-actions'],
|
|
31
|
+
hints: result.hints,
|
|
32
|
+
out: result.out
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function htmlFiles(dir) {
|
|
36
|
+
return readdirSync(dir)
|
|
37
|
+
.filter((fileName) => fileName.endsWith('.html'))
|
|
38
|
+
.sort()
|
|
39
|
+
.map((fileName) => path.join(dir, fileName));
|
|
40
|
+
}
|
|
41
|
+
function javaFiles(dir) {
|
|
42
|
+
return readdirSync(dir)
|
|
43
|
+
.filter((fileName) => fileName.endsWith('Action.java'))
|
|
44
|
+
.sort()
|
|
45
|
+
.map((fileName) => path.join(dir, fileName));
|
|
46
|
+
}
|
|
47
|
+
const args = parseArgs(process.argv.slice(2));
|
|
48
|
+
const hints = args.hints
|
|
49
|
+
? JSON.parse(readFileSync(args.hints, 'utf8'))
|
|
50
|
+
: undefined;
|
|
51
|
+
const codeList = extractCodeListSummary(args.codeList);
|
|
52
|
+
function resolveSpec(docsDir, moduleId, codeListSummary) {
|
|
53
|
+
const specPath = path.join(docsDir, 'spec.yaml');
|
|
54
|
+
if (existsSync(specPath)) {
|
|
55
|
+
return extractSpecYaml(specPath);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
path: specPath,
|
|
59
|
+
module: {
|
|
60
|
+
id: moduleId,
|
|
61
|
+
label: codeListSummary.moduleLabel
|
|
62
|
+
},
|
|
63
|
+
fields: [],
|
|
64
|
+
businessRules: []
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const contract = buildCrudBusinessModuleContract({
|
|
68
|
+
moduleId: args.module,
|
|
69
|
+
spec: resolveSpec(args.docs, args.module, codeList),
|
|
70
|
+
codeList,
|
|
71
|
+
pages: htmlFiles(args.webapp).map(extractHtmlPage),
|
|
72
|
+
actions: javaFiles(args.javaActions).map(extractJavaAction),
|
|
73
|
+
hints
|
|
74
|
+
});
|
|
75
|
+
mkdirSync(path.dirname(args.out), { recursive: true });
|
|
76
|
+
writeFileSync(args.out, `${JSON.stringify(contract, null, 2)}\n`, 'utf8');
|
|
77
|
+
console.log(`Wrote ${args.out}`);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright 测试脚本生成 CLI 入口
|
|
3
|
+
*
|
|
4
|
+
* 从 CRUD 业务模块契约 JSON 文件生成基于 glue 模板骨架的 Playwright 测试脚本。
|
|
5
|
+
*
|
|
6
|
+
* 使用方式:
|
|
7
|
+
* ```bash
|
|
8
|
+
* pnpm generate:playwright-tests -- \
|
|
9
|
+
* --contract <contract-json-path> \
|
|
10
|
+
* --out <output-spec-ts-path> \
|
|
11
|
+
* --menu <menu-path> \
|
|
12
|
+
* --testcase <glue-testcase-json-path>
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 参数说明:
|
|
16
|
+
* - --contract (必填): 契约 JSON 文件路径
|
|
17
|
+
* - --out (必填): 输出的 .spec.ts 文件路径
|
|
18
|
+
* - --menu (必填): 菜单路径,传给 MenuPage.navigateToMenu()
|
|
19
|
+
* - --testcase (可选): 已确认的 glue testcase JSON;传入后会校验用例与 contract 粒度一致。
|
|
20
|
+
*
|
|
21
|
+
* 示例:
|
|
22
|
+
* ```bash
|
|
23
|
+
* pnpm generate:playwright-tests -- \
|
|
24
|
+
* --contract output/zwplace.crud.contract.json \
|
|
25
|
+
* --out ../stage-project/src/tests/generated-zwplace.skeleton.spec.ts \
|
|
26
|
+
* --menu "场所窗口信息管理>场所窗口信息列表"
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=generate-playwright-tests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-playwright-tests.d.ts","sourceRoot":"","sources":["../../../src/cli/generate-playwright-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright 测试脚本生成 CLI 入口
|
|
3
|
+
*
|
|
4
|
+
* 从 CRUD 业务模块契约 JSON 文件生成基于 glue 模板骨架的 Playwright 测试脚本。
|
|
5
|
+
*
|
|
6
|
+
* 使用方式:
|
|
7
|
+
* ```bash
|
|
8
|
+
* pnpm generate:playwright-tests -- \
|
|
9
|
+
* --contract <contract-json-path> \
|
|
10
|
+
* --out <output-spec-ts-path> \
|
|
11
|
+
* --menu <menu-path> \
|
|
12
|
+
* --testcase <glue-testcase-json-path>
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 参数说明:
|
|
16
|
+
* - --contract (必填): 契约 JSON 文件路径
|
|
17
|
+
* - --out (必填): 输出的 .spec.ts 文件路径
|
|
18
|
+
* - --menu (必填): 菜单路径,传给 MenuPage.navigateToMenu()
|
|
19
|
+
* - --testcase (可选): 已确认的 glue testcase JSON;传入后会校验用例与 contract 粒度一致。
|
|
20
|
+
*
|
|
21
|
+
* 示例:
|
|
22
|
+
* ```bash
|
|
23
|
+
* pnpm generate:playwright-tests -- \
|
|
24
|
+
* --contract output/zwplace.crud.contract.json \
|
|
25
|
+
* --out ../stage-project/src/tests/generated-zwplace.skeleton.spec.ts \
|
|
26
|
+
* --menu "场所窗口信息管理>场所窗口信息列表"
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
30
|
+
import { generateStageSkeletonCrudSpec } from '../generators/stage-skeleton-script.js';
|
|
31
|
+
import { validateGlueTestcaseDocumentForSpecAssembly } from '../testcase/testcase-spec-assembly.js';
|
|
32
|
+
/**
|
|
33
|
+
* 解析命令行参数
|
|
34
|
+
*
|
|
35
|
+
* 将 process.argv 转换为结构化的参数对象。
|
|
36
|
+
* 支持 `--key value` 格式的参数对,自动过滤 `--` 分隔符。
|
|
37
|
+
*
|
|
38
|
+
* @param argv - 命令行参数数组(不含 node 和脚本路径)
|
|
39
|
+
* @returns 解析后的参数对象
|
|
40
|
+
* @throws 当参数格式无效或缺少必填参数时抛出错误
|
|
41
|
+
*/
|
|
42
|
+
function parseArgs(argv) {
|
|
43
|
+
const result = {};
|
|
44
|
+
// 过滤 `--` 分隔符
|
|
45
|
+
const normalizedArgv = argv.filter((arg) => arg !== '--');
|
|
46
|
+
// 按键值对解析
|
|
47
|
+
for (let index = 0; index < normalizedArgv.length; index += 2) {
|
|
48
|
+
const key = normalizedArgv[index];
|
|
49
|
+
const value = normalizedArgv[index + 1];
|
|
50
|
+
if (!key?.startsWith('--') || !value) {
|
|
51
|
+
throw new Error(`无效的参数对,靠近 ${key ?? '<empty>'}`);
|
|
52
|
+
}
|
|
53
|
+
result[key.slice(2)] = value;
|
|
54
|
+
}
|
|
55
|
+
// 验证必填参数
|
|
56
|
+
if (!result.contract || !result.out || !result.menu) {
|
|
57
|
+
throw new Error('用法: tsx generate-playwright-tests.ts --contract <path> --out <path> --menu <menu-path>');
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
contract: result.contract,
|
|
61
|
+
out: result.out,
|
|
62
|
+
menu: result.menu,
|
|
63
|
+
testcase: result.testcase,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// 执行主流程
|
|
67
|
+
const args = parseArgs(process.argv.slice(2));
|
|
68
|
+
// 读取契约 JSON 文件
|
|
69
|
+
const contract = JSON.parse(readFileSync(args.contract, 'utf8'));
|
|
70
|
+
if (args.testcase) {
|
|
71
|
+
const testcaseDocument = JSON.parse(readFileSync(args.testcase, 'utf8'));
|
|
72
|
+
validateGlueTestcaseDocumentForSpecAssembly(testcaseDocument, contract);
|
|
73
|
+
}
|
|
74
|
+
// 生成基于 glue 模板骨架的 Playwright 测试脚本
|
|
75
|
+
const script = generateStageSkeletonCrudSpec({
|
|
76
|
+
contract,
|
|
77
|
+
menuNavigation: args.menu
|
|
78
|
+
});
|
|
79
|
+
// 写入输出文件
|
|
80
|
+
writeFileSync(args.out, script, 'utf8');
|
|
81
|
+
console.log(`已生成 ${args.out}`);
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import type { CrudBusinessModuleContract } from '../contracts/crud-business-module.js';
|
|
2
|
+
import type { GlueTestcaseDocument, ObservableStagePayload, RuntimePageStructureSignal } from '../contracts/observable-chain.js';
|
|
3
|
+
import type { ValueResolution } from '../material/material-inventory.js';
|
|
4
|
+
/**
|
|
5
|
+
* 可观测 pipeline 的解析后参数。
|
|
6
|
+
*
|
|
7
|
+
* 默认入口只需 --code-list;--scenario 为场景 gate 的人工确认值(缺省时停在 scenario gate)。
|
|
8
|
+
* 调试覆盖参数 --docs/--webapp/--java-actions/--hints 始终优先于 code_list 钻探。
|
|
9
|
+
*/
|
|
10
|
+
export type ObservablePipelineArgs = {
|
|
11
|
+
codeList: string;
|
|
12
|
+
stageContext?: string;
|
|
13
|
+
projectDir?: string;
|
|
14
|
+
moduleId?: string;
|
|
15
|
+
menu?: string;
|
|
16
|
+
scenario?: string;
|
|
17
|
+
confirmTestcases: boolean;
|
|
18
|
+
contractOut?: string;
|
|
19
|
+
specOut?: string;
|
|
20
|
+
playwrightProject: string;
|
|
21
|
+
headless: boolean;
|
|
22
|
+
debugOverrides: {
|
|
23
|
+
docs?: string;
|
|
24
|
+
webapp?: string;
|
|
25
|
+
javaActions?: string;
|
|
26
|
+
hints?: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 交互补齐后用于本次运行和可选回写 code_list.md 的补充字段。
|
|
31
|
+
*
|
|
32
|
+
* @property knowledgeRoot - 上游物料根目录。
|
|
33
|
+
* @property moduleId - 模块标识。
|
|
34
|
+
* @property menu - 菜单路径。
|
|
35
|
+
* @property webappDir - 前端 HTML 目录。
|
|
36
|
+
* @property javaActionsDir - Java Action 目录。
|
|
37
|
+
* @property hintsPath - ModuleHints 文件路径。
|
|
38
|
+
*/
|
|
39
|
+
export type InteractiveCodeListSupplements = {
|
|
40
|
+
knowledgeRoot?: string;
|
|
41
|
+
moduleId?: string;
|
|
42
|
+
menu?: string;
|
|
43
|
+
webappDir?: string;
|
|
44
|
+
javaActionsDir?: string;
|
|
45
|
+
hintsPath?: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* code_list.md 回写载荷。
|
|
49
|
+
*
|
|
50
|
+
* @property knowledgeRoot - 需要写回的 knowledgeRoot。
|
|
51
|
+
* @property menu - 需要写回的菜单路径。
|
|
52
|
+
* @property materialRefs - 需要追加的物料路径(相对 code_list.md)。
|
|
53
|
+
*/
|
|
54
|
+
export type CodeListWriteBackInput = {
|
|
55
|
+
knowledgeRoot?: string;
|
|
56
|
+
menu?: string;
|
|
57
|
+
materialRefs: string[];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* 一次交互补齐的结果。
|
|
61
|
+
*
|
|
62
|
+
* @property supplements - 本次收集到的补充字段。
|
|
63
|
+
* @property wroteBack - 是否成功写回 code_list.md。
|
|
64
|
+
* @property skippedWriteBackReason - 未写回的原因(如主仓 knowledge-project 只读)。
|
|
65
|
+
*/
|
|
66
|
+
export type InteractiveSupplementResult = {
|
|
67
|
+
supplements: InteractiveCodeListSupplements;
|
|
68
|
+
wroteBack: boolean;
|
|
69
|
+
skippedWriteBackReason?: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* 运行时 gap 推理摘要(runtime runner 产出,Task 9/9A/9B 消费)。
|
|
73
|
+
*/
|
|
74
|
+
export type RuntimeSummary = {
|
|
75
|
+
resolvedWorkflows: string[];
|
|
76
|
+
skippedWorkflows: string[];
|
|
77
|
+
needsReviewWorkflows: string[];
|
|
78
|
+
needsReviewWorkflowReasons?: Array<{
|
|
79
|
+
workflowId: string;
|
|
80
|
+
reason: string;
|
|
81
|
+
}>;
|
|
82
|
+
specPath: string;
|
|
83
|
+
pageStructureSignals?: RuntimePageStructureSignal[];
|
|
84
|
+
runtimeStatus?: 'resolved' | 'failed' | 'environment_unavailable';
|
|
85
|
+
runtimePageStructureStatus?: 'collected' | 'failed' | 'environment_unavailable';
|
|
86
|
+
exitCode?: number;
|
|
87
|
+
stdout?: string;
|
|
88
|
+
stderr?: string;
|
|
89
|
+
errorMessage?: string;
|
|
90
|
+
};
|
|
91
|
+
export declare const runtimeSummaryMarker = "@@EP_STAGE_RUNTIME_SUMMARY@@";
|
|
92
|
+
/**
|
|
93
|
+
* 解析可观测 pipeline 的命令行参数。
|
|
94
|
+
*
|
|
95
|
+
* 默认入口只需 --code-list;--scenario 为场景 gate 的人工确认值(缺省时停在 scenario gate)。
|
|
96
|
+
* 调试覆盖参数 --docs/--webapp/--java-actions/--hints 始终优先于 code_list 钻探。
|
|
97
|
+
*
|
|
98
|
+
* @param argv - process.argv.slice(2)。
|
|
99
|
+
* @returns 解析后的 ObservablePipelineArgs。
|
|
100
|
+
* @throws 缺少 --code-list 或参数对非法时抛错。
|
|
101
|
+
*/
|
|
102
|
+
export declare function parseObservablePipelineArgs(argv: string[]): ObservablePipelineArgs;
|
|
103
|
+
/**
|
|
104
|
+
* 判断目标路径是否位于主仓 knowledge-project 受保护只读区。
|
|
105
|
+
*
|
|
106
|
+
* @param targetPath - 待写入路径。
|
|
107
|
+
* @returns true 表示该路径受主仓 knowledge-project 只读约束保护。
|
|
108
|
+
*/
|
|
109
|
+
export declare function isProtectedKnowledgeProjectPath(targetPath: string): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* 将补齐后的字段和物料引用写回 code_list.md 内容。
|
|
112
|
+
*
|
|
113
|
+
* @param content - 原始 code_list.md 内容。
|
|
114
|
+
* @param input - 待写回字段。
|
|
115
|
+
* @returns 更新后的 code_list.md 内容。
|
|
116
|
+
*/
|
|
117
|
+
export declare function applyCodeListWriteBack(content: string, input: CodeListWriteBackInput): string;
|
|
118
|
+
/**
|
|
119
|
+
* 从用户提供的目录或文件路径中展开可写回的物料引用。
|
|
120
|
+
*
|
|
121
|
+
* HTML 目录会展开为全部 `.html` 文件;Java Action 目录会展开为全部 `*Action.java` 文件;
|
|
122
|
+
* 其余文件按单文件写回。
|
|
123
|
+
*
|
|
124
|
+
* @param codeListPath - code_list.md 路径。
|
|
125
|
+
* @param inputPath - 用户输入的文件或目录路径。
|
|
126
|
+
* @param kind - 物料类别。
|
|
127
|
+
* @returns 可写回 code_list.md 的相对路径列表。
|
|
128
|
+
*/
|
|
129
|
+
export declare function collectCodeListMaterialRefsFromPath(codeListPath: string, inputPath: string, kind: 'html' | 'java_action' | 'module_hints'): string[];
|
|
130
|
+
/**
|
|
131
|
+
* 解析本轮 pipeline 的菜单路由。
|
|
132
|
+
*
|
|
133
|
+
* 优先使用已确认的 menu;缺失时根据 contract 的模块名和列表页标题生成候选,
|
|
134
|
+
* 但候选仍需人工确认,不得直接进入可执行阶段。
|
|
135
|
+
*
|
|
136
|
+
* @param input - menu 槽位与 CRUD 契约。
|
|
137
|
+
* @returns 已确认菜单或候选菜单。
|
|
138
|
+
*/
|
|
139
|
+
export declare function resolveMenuRouteForPipeline(input: {
|
|
140
|
+
menu: ValueResolution;
|
|
141
|
+
contract: CrudBusinessModuleContract;
|
|
142
|
+
}): ValueResolution;
|
|
143
|
+
/**
|
|
144
|
+
* 将 testcase gate 的人工确认结果写回结构化用例文档。
|
|
145
|
+
*
|
|
146
|
+
* @param testcases - 原始用例文档。
|
|
147
|
+
* @returns 所有 case 标记为 confirmed 的新文档。
|
|
148
|
+
*/
|
|
149
|
+
export declare function confirmGlueTestcaseDocument(testcases: GlueTestcaseDocument): GlueTestcaseDocument;
|
|
150
|
+
/**
|
|
151
|
+
* 回写 testcase markdown frontmatter 的 reviewStatus。
|
|
152
|
+
*
|
|
153
|
+
* @param markdown - 原始 testcase markdown。
|
|
154
|
+
* @param reviewStatus - 目标审阅状态。
|
|
155
|
+
* @returns 更新后的 markdown。
|
|
156
|
+
*/
|
|
157
|
+
export declare function applyTestcaseReviewStatusToMarkdown(markdown: string, reviewStatus: 'confirmed' | 'needs_review'): string;
|
|
158
|
+
/**
|
|
159
|
+
* 把 runtime gap 推理摘要转换为可审阅 trace payload。
|
|
160
|
+
*
|
|
161
|
+
* Task 9B 接入 runtime 后写入 runtime-gap-inference.json。
|
|
162
|
+
* 运行时只能补定位和运行态证据,不允许修改业务意图和断言预期。
|
|
163
|
+
*
|
|
164
|
+
* @param runtime - runtime runner 产出的摘要。
|
|
165
|
+
* @returns runtime-gap-inference 阶段 trace payload。
|
|
166
|
+
*/
|
|
167
|
+
export declare function runtimeSummaryToTrace(runtime: RuntimeSummary): ObservableStagePayload;
|
|
168
|
+
/**
|
|
169
|
+
* 胶水测试组装(spec assembly)摘要。
|
|
170
|
+
*/
|
|
171
|
+
export type GlueSpecAssemblySummary = {
|
|
172
|
+
contractPath: string;
|
|
173
|
+
specPath: string;
|
|
174
|
+
menu: string;
|
|
175
|
+
testcasePath: string;
|
|
176
|
+
generated: boolean;
|
|
177
|
+
exitCode?: number;
|
|
178
|
+
stdout?: string;
|
|
179
|
+
stderr?: string;
|
|
180
|
+
errorMessage?: string;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Playwright 执行摘要。
|
|
184
|
+
*/
|
|
185
|
+
export type PlaywrightExecutionSummary = {
|
|
186
|
+
specPath: string;
|
|
187
|
+
project: string;
|
|
188
|
+
status: 'passed' | 'failed' | 'environment_unavailable';
|
|
189
|
+
exitCode: number;
|
|
190
|
+
stdout?: string;
|
|
191
|
+
stderr?: string;
|
|
192
|
+
loginUrl?: string;
|
|
193
|
+
environmentEvidence?: string;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* glue-report 摘要。
|
|
197
|
+
*/
|
|
198
|
+
export type GlueReportSummary = {
|
|
199
|
+
projectDir: string;
|
|
200
|
+
runTimeStamp?: string;
|
|
201
|
+
batchReportDirPath?: string;
|
|
202
|
+
playwrightReportDirPath?: string;
|
|
203
|
+
stageGlueReportHtmlPath?: string;
|
|
204
|
+
stageGlueReportJsonPath?: string;
|
|
205
|
+
failedWorkflowSummaries?: string[];
|
|
206
|
+
gapFindingSummaries?: string[];
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* 从 `.env` 文件中提取登录 URL。
|
|
210
|
+
*
|
|
211
|
+
* @param envFilePath - `.env` 文件路径。
|
|
212
|
+
* @returns `LOGIN_SYSTEM_URL`;不存在时返回 undefined。
|
|
213
|
+
*/
|
|
214
|
+
export declare function extractLoginSystemUrlFromEnvFile(envFilePath: string): string | undefined;
|
|
215
|
+
/**
|
|
216
|
+
* 胶水测试组装阶段 trace 转换。
|
|
217
|
+
*
|
|
218
|
+
* @param summary - spec assembly 摘要。
|
|
219
|
+
* @returns glue-spec-assembly 阶段 trace payload。
|
|
220
|
+
*/
|
|
221
|
+
export declare function glueSpecAssemblyToTrace(summary: GlueSpecAssemblySummary): ObservableStagePayload;
|
|
222
|
+
/**
|
|
223
|
+
* Playwright 执行阶段 trace 转换。
|
|
224
|
+
*
|
|
225
|
+
* @param summary - Playwright 执行摘要。
|
|
226
|
+
* @returns playwright-execution 阶段 trace payload。
|
|
227
|
+
*/
|
|
228
|
+
export declare function playwrightExecutionToTrace(summary: PlaywrightExecutionSummary): ObservableStagePayload;
|
|
229
|
+
/**
|
|
230
|
+
* glue-report 阶段 trace 转换。
|
|
231
|
+
*
|
|
232
|
+
* @param summary - glue-report 摘要。
|
|
233
|
+
* @returns glue-report 阶段 trace payload。
|
|
234
|
+
*/
|
|
235
|
+
export declare function glueReportToTrace(summary: GlueReportSummary): ObservableStagePayload;
|
|
236
|
+
/**
|
|
237
|
+
* 解析 runtime runner 带哨兵的 JSON 输出。
|
|
238
|
+
*
|
|
239
|
+
* @param stdout - runtime runner stdout。
|
|
240
|
+
* @returns RuntimeSummary。
|
|
241
|
+
*/
|
|
242
|
+
export declare function parseRuntimeSummaryOutput(stdout: string): RuntimeSummary;
|
|
243
|
+
/**
|
|
244
|
+
* 将 runtime 子进程失败转成可观测摘要,避免吞掉实现错误。
|
|
245
|
+
*
|
|
246
|
+
* @param input - 子进程失败信息与计划 workflow。
|
|
247
|
+
* @returns RuntimeSummary。
|
|
248
|
+
*/
|
|
249
|
+
export declare function createRuntimeFailureSummary(input: {
|
|
250
|
+
plannedWorkflows: string[];
|
|
251
|
+
specPath: string;
|
|
252
|
+
status: number;
|
|
253
|
+
stdout: string;
|
|
254
|
+
stderr: string;
|
|
255
|
+
}): RuntimeSummary;
|
|
256
|
+
//# sourceMappingURL=run-gap-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-gap-pipeline.d.ts","sourceRoot":"","sources":["../../../src/cli/run-gap-pipeline.ts"],"names":[],"mappings":"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"}
|