@epoint-testtech/ep-stage-skill 0.0.3-alpha.2 → 0.0.4-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 +2 -2
- package/codex-skill/ep-stage/.omc/state/sessions/d636ad35-5fc9-4d5e-85b0-2bcad7d86ee5/pre-tool-advisory-throttle.json +10 -0
- package/codex-skill/ep-stage/glue-create-project/SKILL.md +206 -0
- package/codex-skill/ep-stage/glue-generate-testcase/SKILL.md +274 -0
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-schema.md +112 -0
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md +72 -0
- package/codex-skill/ep-stage/glue-run-test/SKILL.md +289 -0
- package/codex-skill/ep-stage/glue-run-test/references/crud-pipeline.md +145 -0
- package/codex-skill/ep-stage/{glue-test → glue-run-test}/scripts/generate-crud-spec.mjs +3 -3
- package/codex-skill/ep-stage/recording-to-glue/SKILL.md +1 -0
- package/codex-skill/ep-stage/scripts/validate-skill.mjs +29 -7
- package/dist/src/cli/dev/extract-contract.d.ts +14 -0
- package/dist/src/cli/dev/extract-contract.d.ts.map +1 -0
- package/dist/src/cli/dev/extract-contract.js +114 -0
- package/dist/src/cli/generate-crud-contract.js +7 -77
- package/dist/src/cli/generate-playwright-tests.d.ts +0 -28
- package/dist/src/cli/generate-playwright-tests.d.ts.map +1 -1
- package/dist/src/cli/generate-playwright-tests.js +4 -81
- package/dist/src/cli/generate-testcase.d.ts +84 -0
- package/dist/src/cli/generate-testcase.d.ts.map +1 -0
- package/dist/src/cli/generate-testcase.js +300 -0
- package/dist/src/cli/index.d.ts +26 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +75 -0
- package/dist/src/cli/probe.d.ts +46 -0
- package/dist/src/cli/probe.d.ts.map +1 -0
- package/dist/src/cli/probe.js +447 -0
- package/dist/src/cli/run-gap-pipeline.js +4 -0
- package/dist/src/cli/run.d.ts +63 -0
- package/dist/src/cli/run.d.ts.map +1 -0
- package/dist/src/cli/run.js +116 -0
- package/dist/src/cli/spec.d.ts +48 -0
- package/dist/src/cli/spec.d.ts.map +1 -0
- package/dist/src/cli/spec.js +102 -0
- package/dist/src/context/stage-context.d.ts +72 -8
- package/dist/src/context/stage-context.d.ts.map +1 -1
- package/dist/src/context/stage-context.js +61 -15
- package/dist/src/contracts/inference-trace.d.ts +223 -0
- package/dist/src/contracts/inference-trace.d.ts.map +1 -0
- package/dist/src/contracts/inference-trace.js +12 -0
- package/dist/src/extractors/code-list.d.ts +3 -3
- package/dist/src/extractors/code-list.d.ts.map +1 -1
- package/dist/src/extractors/code-list.js +46 -11
- package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -1
- package/dist/src/generators/stage-skeleton-script.js +9 -0
- package/dist/src/index.d.ts +7 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/inference/module-hints-inference.d.ts +30 -0
- package/dist/src/inference/module-hints-inference.d.ts.map +1 -0
- package/dist/src/inference/module-hints-inference.js +363 -0
- package/dist/src/inference/source-analysis.d.ts +26 -0
- package/dist/src/inference/source-analysis.d.ts.map +1 -0
- package/dist/src/inference/source-analysis.js +258 -0
- package/dist/src/testcase/testcase-generator.d.ts.map +1 -1
- package/dist/src/testcase/testcase-generator.js +4 -0
- package/dist/src/testcase/testcase-v2.d.ts +50 -0
- package/dist/src/testcase/testcase-v2.d.ts.map +1 -0
- package/dist/src/testcase/testcase-v2.js +1 -0
- package/dist/src/util/credentials.d.ts +12 -0
- package/dist/src/util/credentials.d.ts.map +1 -0
- package/dist/src/util/credentials.js +19 -0
- package/dist/src/util/i18n-testcase.d.ts +8 -0
- package/dist/src/util/i18n-testcase.d.ts.map +1 -0
- package/dist/src/util/i18n-testcase.js +55 -0
- package/dist/src/util/softlink.d.ts +33 -0
- package/dist/src/util/softlink.d.ts.map +1 -0
- package/dist/src/util/softlink.js +43 -0
- package/dist/src/validation/credentials.d.ts +19 -0
- package/dist/src/validation/credentials.d.ts.map +1 -0
- package/dist/src/validation/credentials.js +38 -0
- package/dist/src/validation/index.d.ts +6 -0
- package/dist/src/validation/index.d.ts.map +1 -0
- package/dist/src/validation/index.js +4 -0
- package/dist/src/validation/inference-trace.d.ts +13 -0
- package/dist/src/validation/inference-trace.d.ts.map +1 -0
- package/dist/src/validation/inference-trace.js +31 -0
- package/dist/src/validation/projects-index.d.ts +13 -0
- package/dist/src/validation/projects-index.d.ts.map +1 -0
- package/dist/src/validation/projects-index.js +37 -0
- package/dist/src/validation/testcase.d.ts +13 -0
- package/dist/src/validation/testcase.d.ts.map +1 -0
- package/dist/src/validation/testcase.js +53 -0
- package/dist/test/cli/extract-contract.test.d.ts +2 -0
- package/dist/test/cli/extract-contract.test.d.ts.map +1 -0
- package/dist/test/cli/extract-contract.test.js +32 -0
- package/dist/test/cli/generate-testcase-inference.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-inference.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-inference.test.js +63 -0
- package/dist/test/cli/generate-testcase-paths.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-paths.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-paths.test.js +165 -0
- package/dist/test/cli/generate-testcase-requirements.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-requirements.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-requirements.test.js +229 -0
- package/dist/test/cli/generate-testcase.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase.test.js +130 -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 +113 -0
- package/dist/test/cli/probe.test.d.ts +2 -0
- package/dist/test/cli/probe.test.d.ts.map +1 -0
- package/dist/test/cli/probe.test.js +31 -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 +149 -0
- package/dist/test/cli/spec-boundary.test.d.ts +2 -0
- package/dist/test/cli/spec-boundary.test.d.ts.map +1 -0
- package/dist/test/cli/spec-boundary.test.js +198 -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 +196 -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/crud-contract.test.js +12 -32
- package/dist/test/inference/module-hints-inference.test.d.ts +2 -0
- package/dist/test/inference/module-hints-inference.test.d.ts.map +1 -0
- package/dist/test/inference/module-hints-inference.test.js +25 -0
- package/dist/test/inference/source-analysis.test.d.ts +2 -0
- package/dist/test/inference/source-analysis.test.d.ts.map +1 -0
- package/dist/test/inference/source-analysis.test.js +23 -0
- package/dist/test/material-inventory.test.js +13 -0
- package/dist/test/observable-pipeline.test.js +12 -3
- package/dist/test/stage-context.test.js +145 -13
- 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/credentials.test.d.ts +2 -0
- package/dist/test/validation/credentials.test.d.ts.map +1 -0
- package/dist/test/validation/credentials.test.js +72 -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.test.d.ts +2 -0
- package/dist/test/validation/testcase.test.d.ts.map +1 -0
- package/dist/test/validation/testcase.test.js +129 -0
- package/docs/README.md +6 -6
- package/docs/mvp-usage-guide.md +3 -3
- package/package.json +9 -4
- package/codex-skill/ep-stage/create-project/SKILL.md +0 -59
- package/codex-skill/ep-stage/glue-test/SKILL.md +0 -258
- package/codex-skill/ep-stage/glue-test/references/crud-pipeline.md +0 -139
- package/codex-skill/ep-stage/glue-testcase/SKILL.md +0 -31
- package/codex-skill/ep-stage/glue-testcase/references/testcase-schema.md +0 -67
- /package/codex-skill/ep-stage/{glue-testcase → glue-generate-testcase}/examples/observable-testcase.json +0 -0
- /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/gap-review-protocol.md +0 -0
- /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/harness-principles.md +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* 解析 dev/extract-contract.ts 的命令行参数。
|
|
6
|
+
*
|
|
7
|
+
* @param argv - process.argv.slice(2)。
|
|
8
|
+
* @returns 解析后的 ExtractContractArgs。
|
|
9
|
+
* @throws 缺少必填参数或显式使用废弃的 --module 时抛错。
|
|
10
|
+
*/
|
|
11
|
+
function parseExtractContractArgs(argv) {
|
|
12
|
+
const result = {};
|
|
13
|
+
const normalizedArgv = argv.filter((arg) => arg !== '--');
|
|
14
|
+
for (let index = 0; index < normalizedArgv.length; index += 2) {
|
|
15
|
+
const key = normalizedArgv[index];
|
|
16
|
+
const value = normalizedArgv[index + 1];
|
|
17
|
+
if (!key?.startsWith('--') || !value) {
|
|
18
|
+
throw new Error(`Invalid argument pair near ${key ?? '<empty>'}`);
|
|
19
|
+
}
|
|
20
|
+
result[key.slice(2)] = value;
|
|
21
|
+
}
|
|
22
|
+
if (result.module) {
|
|
23
|
+
throw new Error('已废弃 --module,请使用 --module-id。');
|
|
24
|
+
}
|
|
25
|
+
for (const key of ['module-id', 'docs', 'code-list', 'webapp', 'java-actions', 'out']) {
|
|
26
|
+
if (!result[key]) {
|
|
27
|
+
throw new Error(`Missing required argument --${key}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
module: result['module-id'],
|
|
32
|
+
docs: result.docs,
|
|
33
|
+
codeList: result['code-list'],
|
|
34
|
+
webapp: result.webapp,
|
|
35
|
+
javaActions: result['java-actions'],
|
|
36
|
+
hints: result.hints,
|
|
37
|
+
out: result.out,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 列出指定目录下所有 .html 文件并返回排序后的绝对路径。
|
|
42
|
+
*
|
|
43
|
+
* @param dir - HTML 物料目录。
|
|
44
|
+
* @returns 排序后的绝对路径数组。
|
|
45
|
+
*/
|
|
46
|
+
function htmlFiles(dir) {
|
|
47
|
+
return readdirSync(dir)
|
|
48
|
+
.filter((fileName) => fileName.endsWith('.html'))
|
|
49
|
+
.sort()
|
|
50
|
+
.map((fileName) => path.join(dir, fileName));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 列出指定目录下所有 *Action.java 文件并返回排序后的绝对路径。
|
|
54
|
+
*
|
|
55
|
+
* @param dir - Java Action 物料目录。
|
|
56
|
+
* @returns 排序后的绝对路径数组。
|
|
57
|
+
*/
|
|
58
|
+
function javaFiles(dir) {
|
|
59
|
+
return readdirSync(dir)
|
|
60
|
+
.filter((fileName) => fileName.endsWith('Action.java'))
|
|
61
|
+
.sort()
|
|
62
|
+
.map((fileName) => path.join(dir, fileName));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 解析 docs 目录下的 spec.yaml;缺失时返回最小空骨架(保证 contract 构建不阻断)。
|
|
66
|
+
*
|
|
67
|
+
* @param docsDir - 需求文档目录。
|
|
68
|
+
* @param moduleId - 模块 ID。
|
|
69
|
+
* @param codeListSummary - 已解析的 code_list 摘要。
|
|
70
|
+
* @returns ExtractedSpecYaml。
|
|
71
|
+
*/
|
|
72
|
+
function resolveSpec(docsDir, moduleId, codeListSummary) {
|
|
73
|
+
const specPath = path.join(docsDir, 'spec.yaml');
|
|
74
|
+
if (existsSync(specPath))
|
|
75
|
+
return extractSpecYaml(specPath);
|
|
76
|
+
return {
|
|
77
|
+
path: specPath,
|
|
78
|
+
module: { id: moduleId, label: codeListSummary.moduleLabel },
|
|
79
|
+
fields: [],
|
|
80
|
+
businessRules: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 开发期 contract 提取入口(REQ-CLI-03)。被 generate:crud-contract pnpm script 调用,
|
|
85
|
+
* 不在 index.ts 注册为子命令,不出现在任何 SKILL.md。
|
|
86
|
+
*
|
|
87
|
+
* 行为与 0.0.3-alpha.2 的 generate-crud-contract.ts 完全等价;本次重构仅把执行
|
|
88
|
+
* 入口包装成可被 pnpm script 与 generate-testcase 子命令复用的纯函数。
|
|
89
|
+
*
|
|
90
|
+
* @param argv - 命令行参数(--module-id/--docs/--code-list/--webapp/--java-actions/--hints/--out)。
|
|
91
|
+
* @returns 写入的 contract.json 绝对路径。
|
|
92
|
+
*/
|
|
93
|
+
export function runExtractContract(argv) {
|
|
94
|
+
const args = parseExtractContractArgs(argv);
|
|
95
|
+
const hints = args.hints
|
|
96
|
+
? JSON.parse(readFileSync(args.hints, 'utf8'))
|
|
97
|
+
: undefined;
|
|
98
|
+
const codeList = extractCodeListSummary(args.codeList);
|
|
99
|
+
const contract = buildCrudBusinessModuleContract({
|
|
100
|
+
moduleId: args.module,
|
|
101
|
+
spec: resolveSpec(args.docs, args.module, codeList),
|
|
102
|
+
codeList,
|
|
103
|
+
pages: htmlFiles(args.webapp).map(extractHtmlPage),
|
|
104
|
+
actions: javaFiles(args.javaActions).map(extractJavaAction),
|
|
105
|
+
hints,
|
|
106
|
+
});
|
|
107
|
+
mkdirSync(path.dirname(args.out), { recursive: true });
|
|
108
|
+
writeFileSync(args.out, `${JSON.stringify(contract, null, 2)}\n`, 'utf8');
|
|
109
|
+
console.log(`Wrote ${args.out}`);
|
|
110
|
+
return { contractPath: path.resolve(args.out) };
|
|
111
|
+
}
|
|
112
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
113
|
+
runExtractContract(process.argv.slice(2));
|
|
114
|
+
}
|
|
@@ -1,77 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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}`);
|
|
1
|
+
import { runExtractContract } from './dev/extract-contract.js';
|
|
2
|
+
/**
|
|
3
|
+
* 旧 pnpm script 入口薄壳(REQ-CLI-03 修订):所有逻辑搬到 dev/extract-contract.ts。
|
|
4
|
+
* 本文件不删除,保持旧 pnpm script `generate:crud-contract` 零回归;新代码请直接
|
|
5
|
+
* 调用 `runExtractContract`。
|
|
6
|
+
*/
|
|
7
|
+
runExtractContract(process.argv.slice(2));
|
|
@@ -1,30 +1,2 @@
|
|
|
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
1
|
export {};
|
|
30
2
|
//# sourceMappingURL=generate-playwright-tests.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-playwright-tests.d.ts","sourceRoot":"","sources":["../../../src/cli/generate-playwright-tests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-playwright-tests.d.ts","sourceRoot":"","sources":["../../../src/cli/generate-playwright-tests.ts"],"names":[],"mappings":""}
|
|
@@ -1,81 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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}`);
|
|
1
|
+
// 薄壳:保留旧入口零回归,实际逻辑见 ./spec.ts(src/cli/index.ts spec 子命令统一入口)。
|
|
2
|
+
// 新参数:--testcase <p> --out <p>(旧的 --contract / --menu 已迁移到 testcase 子命令 + spec 子命令链路)。
|
|
3
|
+
import { parseSpecArgs, runSpec } from './spec.js';
|
|
4
|
+
runSpec(parseSpecArgs(process.argv.slice(2)));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { TestcaseV2 } from '../testcase/testcase-v2.js';
|
|
2
|
+
/**
|
|
3
|
+
* testcase 子命令解析后的参数(REQ-CHAIN-01 / REQ-SCENE-01)。
|
|
4
|
+
*
|
|
5
|
+
* - codeList:上游 code_list.md 绝对路径(必填);
|
|
6
|
+
* - testsDir:<projectDir>/src/tests/<需求名> 绝对路径(必填);
|
|
7
|
+
* - scenario:①档优先级(显式 CLI 参数);
|
|
8
|
+
* - hints:ModuleHints JSON 路径(可选;推断 scenario 用);
|
|
9
|
+
* - projectDir / requirementDir:可选覆盖,默认从 codeList 路径推断。
|
|
10
|
+
*/
|
|
11
|
+
export type GenerateTestcaseArgs = {
|
|
12
|
+
codeList: string;
|
|
13
|
+
testsDir: string;
|
|
14
|
+
scenario?: string;
|
|
15
|
+
hints?: string;
|
|
16
|
+
projectDir?: string;
|
|
17
|
+
requirementDir?: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* testcase 子命令产物 + 推断结果(供 skill Step 5 交互确认)。
|
|
21
|
+
*/
|
|
22
|
+
export type GenerateTestcaseResult = {
|
|
23
|
+
testcasePath: string;
|
|
24
|
+
testcaseMdPath: string;
|
|
25
|
+
credentialsTemplatePath: string;
|
|
26
|
+
inferenceTracePath: string;
|
|
27
|
+
inference: {
|
|
28
|
+
scenario: string;
|
|
29
|
+
requiredSystems: TestcaseV2['requiredSystems'];
|
|
30
|
+
requiredRoles: TestcaseV2['requiredRoles'];
|
|
31
|
+
credentialsTemplatePath: string;
|
|
32
|
+
credentialsActualPath: string;
|
|
33
|
+
cachedSystemsHit: string[];
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* 解析 testcase 子命令参数。
|
|
38
|
+
*
|
|
39
|
+
* @param argv - 已剥离子命令名的命令行参数。
|
|
40
|
+
* @returns 解析后的 GenerateTestcaseArgs。
|
|
41
|
+
* @throws 缺少 --code-list 或 --tests-dir 时抛错。
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseGenerateTestcaseArgs(argv: string[]): GenerateTestcaseArgs;
|
|
44
|
+
/**
|
|
45
|
+
* scenario 3 档决策(REQ-SCENE-01):
|
|
46
|
+
* 1. --scenario CLI 参数(最高优先级)
|
|
47
|
+
* 2. ModuleHints 文件路径包含 `scenario=<value>` 字串(粗推断)
|
|
48
|
+
* 3. 默认 "crud.single-page"(与 i18n 表 / skeleton scenario 一致)
|
|
49
|
+
*
|
|
50
|
+
* @param args - 解析后的参数。
|
|
51
|
+
* @returns 决策结果。
|
|
52
|
+
*/
|
|
53
|
+
export declare function decideScenario(args: GenerateTestcaseArgs): string;
|
|
54
|
+
/**
|
|
55
|
+
* 把 TestcaseV2 渲染成中文 testcase.md(REQ-UX-03)。
|
|
56
|
+
*
|
|
57
|
+
* 设计:
|
|
58
|
+
* - 字段名 / 状态值通过 i18nTestcase() 翻译;
|
|
59
|
+
* - `unresolved` 字段标题硬编码「未确认项」(i18n 表中 `unresolved` 解析为状态值「未解决」);
|
|
60
|
+
* - 每次重跑覆盖(REQ-DATA-03 由调用方 writeFileSync 触发)。
|
|
61
|
+
*
|
|
62
|
+
* @param testcase - TestcaseV2 顶层结构。
|
|
63
|
+
* @returns Markdown 文本。
|
|
64
|
+
*/
|
|
65
|
+
export declare function renderTestcaseMarkdown(testcase: TestcaseV2): string;
|
|
66
|
+
/**
|
|
67
|
+
* testcase 子命令主体(REQ-CHAIN-01 / REQ-CHAIN-02 / REQ-SCENE-01 / REQ-DATA-02)。
|
|
68
|
+
*
|
|
69
|
+
* 流程:
|
|
70
|
+
* 1. 决定 scenario(3 档优先级,写入 testcase 顶层 scenario 字段);
|
|
71
|
+
* 2. 调 runProbeAndCoverage 钻探上游物料 + 装配 TestcaseV2;
|
|
72
|
+
* 3. 落盘 testcase.json5 + testcase.md(中文 i18n) + credentials.template.json5;
|
|
73
|
+
* 4. 软链上游 code_list.md → <tests-dir>/code_list.md;
|
|
74
|
+
* 5. 返回推断结果(供 skill Step 5 交互确认 systemUrl / credentialsCache 命中)。
|
|
75
|
+
*
|
|
76
|
+
* 注意:contract 提取通过 probe 内部完成,不直接复用 dev/extract-contract.ts 的 CLI 入口
|
|
77
|
+
* (probe + extract-contract 共享同一组 buildCrudBusinessModuleContract + extractor 依赖,
|
|
78
|
+
* 二者各自负责自己的 I/O 边界,保持职责单一)。
|
|
79
|
+
*
|
|
80
|
+
* @param args - 已解析参数。
|
|
81
|
+
* @returns 产物路径 + 推断结果。
|
|
82
|
+
*/
|
|
83
|
+
export declare function runGenerateTestcase(args: GenerateTestcaseArgs): GenerateTestcaseResult;
|
|
84
|
+
//# sourceMappingURL=generate-testcase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-testcase.d.ts","sourceRoot":"","sources":["../../../src/cli/generate-testcase.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;QAC/C,aAAa,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;QAC3C,uBAAuB,EAAE,MAAM,CAAC;QAChC,qBAAqB,EAAE,MAAM,CAAC;QAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAC;KAC5B,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAqB9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAOjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAgDnE;AAkID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,sBAAsB,CA+DtF"}
|