@midscene/test 1.13.2-beta-20260923035443.0 → 1.13.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/dist/es/1~214.mjs +15 -15
- package/dist/es/1~214.mjs.map +1 -1
- package/dist/es/cli/index.mjs +6 -25
- package/dist/es/cli/index.mjs.map +1 -1
- package/dist/es/test-cli.mjs +53 -49
- package/dist/es/test-cli.mjs.map +1 -1
- package/dist/lib/0~160.js +15 -15
- package/dist/lib/0~160.js.map +1 -1
- package/dist/lib/cli/index.js +5 -24
- package/dist/lib/cli/index.js.map +1 -1
- package/dist/lib/test-cli.js +52 -48
- package/dist/lib/test-cli.js.map +1 -1
- package/dist/types/cli/index.d.ts +0 -3
- package/package.json +13 -13
package/dist/lib/test-cli.js
CHANGED
|
@@ -16,7 +16,9 @@ var __webpack_modules__ = {
|
|
|
16
16
|
module.exports = require("yargs/yargs");
|
|
17
17
|
},
|
|
18
18
|
"./package.json" (module) {
|
|
19
|
-
module.exports =
|
|
19
|
+
module.exports = {
|
|
20
|
+
rE: "1.13.2"
|
|
21
|
+
};
|
|
20
22
|
}
|
|
21
23
|
};
|
|
22
24
|
var __webpack_module_cache__ = {};
|
|
@@ -81,7 +83,7 @@ var __webpack_exports__ = {};
|
|
|
81
83
|
var package_0 = __webpack_require__("./package.json");
|
|
82
84
|
const v4_namespaceObject = require("zod/v4");
|
|
83
85
|
const GENERATED_COMMENT = '<!-- Generated by `midscene-test nodes`. Do not edit directly. -->';
|
|
84
|
-
const
|
|
86
|
+
const sortNodesForSpec = (nodes)=>{
|
|
85
87
|
const priority = (name)=>'aiAct' === name ? 0 : 'aiAssert' === name ? 1 : 2;
|
|
86
88
|
return [
|
|
87
89
|
...nodes
|
|
@@ -101,7 +103,7 @@ var __webpack_exports__ = {};
|
|
|
101
103
|
const renderWorkflowLocations = (location)=>{
|
|
102
104
|
const sections = [
|
|
103
105
|
'## Where to use these Nodes',
|
|
104
|
-
'Use these Nodes in Workflow Documents (`.yaml` or `.yml` files) selected by an Execution Project. Case file patterns and the config file path below are relative to this
|
|
106
|
+
'Use these Nodes in Workflow Documents (`.yaml` or `.yml` files) selected by an Execution Project. Case file patterns and the config file path below are relative to this spec file. Case file patterns use glob syntax. A custom `--config` path does not change where case files are selected.',
|
|
105
107
|
'Projects created by `midscene-test create` select `cases/**/*.{yaml,yml}` by default, so you can write test cases in `cases/example.yaml` or subdirectories of `cases/`. If an Execution Project has no `files` configuration, Midscene Test searches `**/*.{yaml,yml}` recursively instead. Check `projects[].files` in your configuration before choosing a file location.'
|
|
106
108
|
];
|
|
107
109
|
if (location) {
|
|
@@ -191,13 +193,14 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
191
193
|
}
|
|
192
194
|
return sections.join('\n\n');
|
|
193
195
|
};
|
|
194
|
-
const
|
|
196
|
+
const renderNodeSpec = (nodes, location)=>{
|
|
195
197
|
const warnings = [];
|
|
196
|
-
const sortedNodes =
|
|
198
|
+
const sortedNodes = sortNodesForSpec(nodes);
|
|
197
199
|
const sections = [
|
|
198
200
|
GENERATED_COMMENT,
|
|
199
|
-
'# Midscene Test Node
|
|
200
|
-
'This document describes the
|
|
201
|
+
'# Midscene Test Node Spec',
|
|
202
|
+
'This document describes the Nodes available in YAML test files (`.yaml` or `.yml`) for the Midscene Test framework (`@midscene/test`). It lists the Nodes registered by the current Test Project, their inputs, and how to call them in test steps and lifecycle hooks.',
|
|
203
|
+
"Learn about the framework and YAML test authoring:\n\n- [Midscene Test overview](https://midscenejs.com/midscene-test/overview): framework concepts and the role of Nodes.\n- [Create and use test projects](https://midscenejs.com/midscene-test/use): write YAML cases, run tests, and inspect results.\n- [Configure test projects](https://midscenejs.com/midscene-test/configuration): register Nodes, select case files, and manage runtime resources.",
|
|
201
204
|
renderNodeOverview(sortedNodes),
|
|
202
205
|
renderWorkflowLocations(location),
|
|
203
206
|
WORKFLOW_STEP_CONTRACT
|
|
@@ -1214,32 +1217,13 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
1214
1217
|
notRunReason: reason
|
|
1215
1218
|
});
|
|
1216
1219
|
const summarize = (projects)=>{
|
|
1217
|
-
const
|
|
1218
|
-
const documentAttemptByRunId = new Map(project.documents.map((document)=>[
|
|
1219
|
-
document.documentRunId,
|
|
1220
|
-
document.attemptIndex ?? 0
|
|
1221
|
-
]));
|
|
1222
|
-
return latestById(project.cases, (item)=>item.caseId).map((item)=>({
|
|
1223
|
-
status: item.status,
|
|
1224
|
-
...item.run ? {
|
|
1225
|
-
run: item.run
|
|
1226
|
-
} : {},
|
|
1227
|
-
...item.attempts ? {
|
|
1228
|
-
attempts: item.attempts
|
|
1229
|
-
} : {},
|
|
1230
|
-
retryCount: item.documentRunId ? documentAttemptByRunId.get(item.documentRunId) ?? 0 : 0
|
|
1231
|
-
}));
|
|
1232
|
-
});
|
|
1220
|
+
const cases = projects.flatMap((project)=>latestById(project.cases, (item)=>item.caseId));
|
|
1233
1221
|
const documents = projects.flatMap((project)=>latestById(project.documents, (item)=>item.documentId));
|
|
1234
|
-
const health = (0, report_namespaceObject.calculateTestRunHealth)(healthCases);
|
|
1235
1222
|
return {
|
|
1236
|
-
total:
|
|
1237
|
-
passed:
|
|
1238
|
-
failed:
|
|
1239
|
-
notRun:
|
|
1240
|
-
passedAfterRetry: health.passedAfterRetry,
|
|
1241
|
-
finalPassRate: health.finalPassRate,
|
|
1242
|
-
firstPassRate: health.firstPassRate,
|
|
1223
|
+
total: cases.length,
|
|
1224
|
+
passed: cases.filter((item)=>'success' === item.status).length,
|
|
1225
|
+
failed: cases.filter((item)=>'failed' === item.status).length,
|
|
1226
|
+
notRun: cases.filter((item)=>'not-run' === item.status).length,
|
|
1243
1227
|
filtered: projects.reduce((total, project)=>total + project.filteredCaseCount, 0),
|
|
1244
1228
|
collectionErrors: projects.reduce((total, project)=>total + project.collectionErrors.length, 0),
|
|
1245
1229
|
documentFailures: documents.filter((document)=>'failed' === document.status).length,
|
|
@@ -1599,24 +1583,44 @@ Legacy tasks/flow YAML and its CLI options belong to the midscene command.
|
|
|
1599
1583
|
const projectName = options.projectNames?.[0];
|
|
1600
1584
|
const selectedProjects = projectName ? project.projects.filter((candidate)=>candidate.name === projectName) : project.projects;
|
|
1601
1585
|
if (0 === selectedProjects.length) throw new Error(`Unknown Midscene project: ${projectName}`);
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
const
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1586
|
+
const filenames = new Map();
|
|
1587
|
+
const owners = new Map();
|
|
1588
|
+
for (const executionProject of project.projects){
|
|
1589
|
+
const safeName = executionProject.name.normalize('NFC').replace(/[<>:"/\\|?*\u0000-\u001f]/g, '-').replace(/[. ]+$/g, '-');
|
|
1590
|
+
const filename = project.hasExplicitProjects ? `midscene-node-spec.${safeName}.md` : 'midscene-node-spec.md';
|
|
1591
|
+
const key = filename.toLowerCase();
|
|
1592
|
+
const owner = owners.get(key);
|
|
1593
|
+
if (void 0 !== owner) throw new Error(`Projects "${owner}" and "${executionProject.name}" generate the same Node Spec filename: ${filename}`);
|
|
1594
|
+
owners.set(key, executionProject.name);
|
|
1595
|
+
filenames.set(executionProject.name, filename);
|
|
1596
|
+
}
|
|
1597
|
+
const specs = selectedProjects.map((executionProject)=>{
|
|
1598
|
+
const nodes = sortNodesForSpec(executionProject.nodes.definitions());
|
|
1599
|
+
const document = renderNodeSpec(nodes, {
|
|
1600
|
+
configPath: configPath ? (0, external_node_path_.relative)(configSearchRoot, configPath).split(external_node_path_.sep).join('/') : void 0,
|
|
1601
|
+
projects: [
|
|
1602
|
+
{
|
|
1603
|
+
name: executionProject.name,
|
|
1604
|
+
files: executionProject.files ?? DEFAULT_TEST_FILE_SELECTION
|
|
1605
|
+
}
|
|
1606
|
+
]
|
|
1607
|
+
});
|
|
1608
|
+
return {
|
|
1609
|
+
executionProject,
|
|
1610
|
+
nodes,
|
|
1611
|
+
document
|
|
1612
|
+
};
|
|
1611
1613
|
});
|
|
1612
|
-
for (const
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1614
|
+
for (const { executionProject, nodes, document } of specs){
|
|
1615
|
+
for (const warning of document.warnings)io.error(`midscene-test nodes: ${warning}`);
|
|
1616
|
+
const specPath = (0, external_node_path_.resolve)(configSearchRoot, filenames.get(executionProject.name));
|
|
1617
|
+
(0, external_node_fs_.writeFileSync)(specPath, document.markdown);
|
|
1618
|
+
if (project.hasExplicitProjects || projectName) io.log(`Execution Project: ${executionProject.name}`);
|
|
1619
|
+
io.log(`Registered Nodes (${nodes.length}):`);
|
|
1620
|
+
if (0 === nodes.length) io.log('No nodes are registered by the current Test Project.');
|
|
1621
|
+
for (const node of nodes)io.log(`- ${node.name}: ${node.description?.trim() || "Description not declared."}`);
|
|
1622
|
+
io.log(`\nNode Spec generated: ${specPath}`);
|
|
1623
|
+
}
|
|
1620
1624
|
};
|
|
1621
1625
|
async function runTestCli(args, io = defaultCliIO) {
|
|
1622
1626
|
try {
|