@midscene/test 1.17.6 → 1.17.7
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/cli/index.mjs +68 -39
- package/dist/es/cli/index.mjs.map +1 -1
- package/dist/es/test-cli.mjs +69 -40
- package/dist/es/test-cli.mjs.map +1 -1
- package/dist/lib/cli/index.js +68 -39
- package/dist/lib/cli/index.js.map +1 -1
- package/dist/lib/test-cli.js +69 -40
- package/dist/lib/test-cli.js.map +1 -1
- package/dist/templates/test/android/README.md +1 -1
- package/dist/templates/test/android/README.zh.md +1 -1
- package/dist/templates/test/android/gitignore +0 -1
- package/dist/templates/test/computer/README.md +1 -1
- package/dist/templates/test/computer/README.zh.md +1 -1
- package/dist/templates/test/computer/gitignore +0 -1
- package/dist/templates/test/harmony/README.md +1 -1
- package/dist/templates/test/harmony/README.zh.md +1 -1
- package/dist/templates/test/harmony/gitignore +0 -1
- package/dist/templates/test/ios/README.md +1 -1
- package/dist/templates/test/ios/README.zh.md +1 -1
- package/dist/templates/test/ios/gitignore +0 -1
- package/dist/templates/test/web/README.md +1 -1
- package/dist/templates/test/web/README.zh.md +1 -1
- package/dist/templates/test/web/gitignore +0 -1
- package/dist/types/cli/index.d.ts +2 -1
- package/package.json +13 -13
package/dist/es/test-cli.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { globSync } from "tinyglobby";
|
|
|
13
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
14
14
|
import { JSON_SCHEMA, load } from "js-yaml";
|
|
15
15
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
16
|
+
import { resolveMidsceneRunDir, runWithMidsceneRunDir } from "@midscene/shared/common";
|
|
16
17
|
import { setMaxListeners } from "node:events";
|
|
17
18
|
import { ReportSession, TestRunReportAssembler, calculateTestRunHealth } from "@midscene/core/report";
|
|
18
19
|
var __webpack_modules__ = {
|
|
@@ -30,7 +31,7 @@ var __webpack_modules__ = {
|
|
|
30
31
|
},
|
|
31
32
|
"./package.json" (module) {
|
|
32
33
|
module.exports = {
|
|
33
|
-
rE: "1.17.
|
|
34
|
+
rE: "1.17.7"
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
};
|
|
@@ -1519,8 +1520,7 @@ const validateTestOptions = (value, hasExplicitProjects)=>{
|
|
|
1519
1520
|
testTimeout: validatePositiveInteger(candidate.testTimeout, 120000, 'test.testTimeout')
|
|
1520
1521
|
});
|
|
1521
1522
|
};
|
|
1522
|
-
const validateOutputPath = (value,
|
|
1523
|
-
if (void 0 === value) return fallback;
|
|
1523
|
+
const validateOutputPath = (value, label)=>{
|
|
1524
1524
|
if ('string' != typeof value || 0 === value.trim().length) throw new TypeError(`Midscene config ${label} must be non-empty.`);
|
|
1525
1525
|
return value;
|
|
1526
1526
|
};
|
|
@@ -1534,7 +1534,9 @@ const validateOutput = (value)=>{
|
|
|
1534
1534
|
if (void 0 !== candidate.reportFormat && 'single-html' !== candidate.reportFormat && 'html-and-external-assets' !== candidate.reportFormat) throw new TypeError('Midscene config output.reportFormat must be single-html or html-and-external-assets.');
|
|
1535
1535
|
return Object.freeze({
|
|
1536
1536
|
reportFormat: candidate.reportFormat ?? 'single-html',
|
|
1537
|
-
|
|
1537
|
+
...void 0 === candidate.reportDir ? {} : {
|
|
1538
|
+
reportDir: validateOutputPath(candidate.reportDir, 'output.reportDir')
|
|
1539
|
+
}
|
|
1538
1540
|
});
|
|
1539
1541
|
};
|
|
1540
1542
|
const validateTestProjectDefinition = (definition)=>{
|
|
@@ -2122,8 +2124,16 @@ const DEFAULT_TEST_FILE_SELECTION = {
|
|
|
2122
2124
|
]
|
|
2123
2125
|
};
|
|
2124
2126
|
const project_preparation_toPosix = (value)=>value.split(external_node_path_.sep).join('/');
|
|
2125
|
-
const discoverResolvedTestFiles = (projectRoot, selection)=>{
|
|
2127
|
+
const discoverResolvedTestFiles = (projectRoot, selection, excludedDirectories = [])=>{
|
|
2126
2128
|
const root = (0, external_node_path_.resolve)(projectRoot);
|
|
2129
|
+
const outputPatterns = excludedDirectories.flatMap((directory)=>{
|
|
2130
|
+
const withinRoot = (0, external_node_path_.relative)(root, directory);
|
|
2131
|
+
if (!withinRoot || (0, external_node_path_.isAbsolute)(withinRoot) || '..' === withinRoot || withinRoot.startsWith(`..${external_node_path_.sep}`)) return [];
|
|
2132
|
+
const literal = project_preparation_toPosix(withinRoot).replace(/([*?{}[\]()!])/g, '\\$1');
|
|
2133
|
+
return [
|
|
2134
|
+
`${literal}/**`
|
|
2135
|
+
];
|
|
2136
|
+
});
|
|
2127
2137
|
const match = (patterns)=>globSync(patterns, {
|
|
2128
2138
|
absolute: true,
|
|
2129
2139
|
caseSensitiveMatch: false,
|
|
@@ -2133,6 +2143,7 @@ const discoverResolvedTestFiles = (projectRoot, selection)=>{
|
|
|
2133
2143
|
followSymbolicLinks: false,
|
|
2134
2144
|
ignore: [
|
|
2135
2145
|
...ALWAYS_IGNORED_PATTERNS,
|
|
2146
|
+
...outputPatterns,
|
|
2136
2147
|
...selection.exclude ?? []
|
|
2137
2148
|
],
|
|
2138
2149
|
onlyFiles: true
|
|
@@ -2202,7 +2213,7 @@ async function prepareProject(project, projectRoot, runDir, defaultTimeoutMs, op
|
|
|
2202
2213
|
const platform = options.platform?.trim();
|
|
2203
2214
|
const fileSelection = project.files ?? DEFAULT_TEST_FILE_SELECTION;
|
|
2204
2215
|
const prerequisiteFile = options.prerequisiteFile ? (0, external_node_path_.resolve)(options.prerequisiteFile) : void 0;
|
|
2205
|
-
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection);
|
|
2216
|
+
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection, options.excludedDirectories);
|
|
2206
2217
|
const files = [
|
|
2207
2218
|
...prerequisiteFile ? [
|
|
2208
2219
|
prerequisiteFile
|
|
@@ -2367,40 +2378,58 @@ async function prepareTestRun(options) {
|
|
|
2367
2378
|
if (options.configPath && /\.ya?ml$/i.test(configPath)) throw new Error(`midscene-test --config only accepts a native TypeScript or JavaScript project config: ${configPath}. Run legacy batch YAML with \`midscene --config ${options.configPath}\`.`);
|
|
2368
2379
|
if (options.configPath && !(0, external_node_fs_.existsSync)(configPath)) throw new Error(`Midscene config does not exist: ${configPath}`);
|
|
2369
2380
|
const definition = await loadTestProject(configPath);
|
|
2370
|
-
const
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2381
|
+
const artifactDir = resolveMidsceneRunDir(input.projectRoot);
|
|
2382
|
+
return runWithMidsceneRunDir(artifactDir, async ()=>{
|
|
2383
|
+
const resultDir = options.resultDir ? (0, external_node_path_.resolve)(input.cwd, options.resultDir) : (0, external_node_path_.join)(artifactDir, 'test-results');
|
|
2384
|
+
const runDir = (0, external_node_path_.join)(resultDir, runId);
|
|
2385
|
+
const summaryPath = (0, external_node_path_.join)(runDir, 'summary.json');
|
|
2386
|
+
const reportDir = definition.output.reportDir ? (0, external_node_path_.resolve)(input.projectRoot, definition.output.reportDir) : (0, external_node_path_.join)(artifactDir, 'report');
|
|
2387
|
+
(0, external_node_fs_.mkdirSync)(resultDir, {
|
|
2388
|
+
recursive: true
|
|
2389
|
+
});
|
|
2390
|
+
(0, external_node_fs_.mkdirSync)(runDir);
|
|
2391
|
+
const projects = [];
|
|
2392
|
+
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, {
|
|
2393
|
+
...input.singleFile ? {
|
|
2394
|
+
files: [
|
|
2395
|
+
input.singleFile
|
|
2396
|
+
]
|
|
2397
|
+
} : {},
|
|
2398
|
+
excludedDirectories: [
|
|
2399
|
+
artifactDir,
|
|
2400
|
+
resultDir,
|
|
2401
|
+
reportDir,
|
|
2402
|
+
...[
|
|
2403
|
+
'cache',
|
|
2404
|
+
'log',
|
|
2405
|
+
'output',
|
|
2406
|
+
'tmp',
|
|
2407
|
+
'dump'
|
|
2408
|
+
].map((name)=>(0, external_node_path_.join)(artifactDir, name))
|
|
2409
|
+
]
|
|
2410
|
+
}));
|
|
2411
|
+
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
2412
|
+
return {
|
|
2413
|
+
startedAt,
|
|
2414
|
+
runId,
|
|
2415
|
+
projectRoot: input.projectRoot,
|
|
2416
|
+
artifactDir,
|
|
2417
|
+
...configPath ? {
|
|
2418
|
+
configPath
|
|
2419
|
+
} : {},
|
|
2420
|
+
resultDir,
|
|
2421
|
+
runDir,
|
|
2422
|
+
summaryPath,
|
|
2423
|
+
reportDir,
|
|
2424
|
+
definition,
|
|
2425
|
+
projects,
|
|
2426
|
+
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
2427
|
+
reportEnabled: true,
|
|
2428
|
+
publications: [],
|
|
2429
|
+
onProgress: options.onProgress ?? (()=>{}),
|
|
2430
|
+
onEvent: options.onEvent
|
|
2431
|
+
};
|
|
2376
2432
|
});
|
|
2377
|
-
(0, external_node_fs_.mkdirSync)(runDir);
|
|
2378
|
-
const projects = [];
|
|
2379
|
-
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, input.singleFile ? {
|
|
2380
|
-
files: [
|
|
2381
|
-
input.singleFile
|
|
2382
|
-
]
|
|
2383
|
-
} : void 0));
|
|
2384
|
-
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
2385
|
-
return {
|
|
2386
|
-
startedAt,
|
|
2387
|
-
runId,
|
|
2388
|
-
projectRoot: input.projectRoot,
|
|
2389
|
-
...configPath ? {
|
|
2390
|
-
configPath
|
|
2391
|
-
} : {},
|
|
2392
|
-
resultDir,
|
|
2393
|
-
runDir,
|
|
2394
|
-
summaryPath,
|
|
2395
|
-
reportDir,
|
|
2396
|
-
definition,
|
|
2397
|
-
projects,
|
|
2398
|
-
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
2399
|
-
reportEnabled: true,
|
|
2400
|
-
publications: [],
|
|
2401
|
-
onProgress: options.onProgress ?? (()=>{}),
|
|
2402
|
-
onEvent: options.onEvent
|
|
2403
|
-
};
|
|
2404
2433
|
}
|
|
2405
2434
|
const result_markdown_text = (value)=>value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll('|', '|').replaceAll('[', '[').replaceAll(']', ']').replaceAll('*', '*').replaceAll('_', '_').replaceAll('`', '`').replaceAll('\\', '\').replace(/[\r\n]+/g, ' ');
|
|
2406
2435
|
const result_markdown_duration = (ms)=>{
|
|
@@ -3118,7 +3147,7 @@ const latestById = (items, id)=>[
|
|
|
3118
3147
|
const notRunSuite = (prepared, reason)=>prepared.documents.flatMap((document)=>document.cases.map((item)=>asNotRun(document.documentId, item, prepared.project.name, reason)));
|
|
3119
3148
|
async function runPreparedTestProject(plan) {
|
|
3120
3149
|
const reports = new ReportSession((0, external_node_path_.join)(plan.runDir, 'records'));
|
|
3121
|
-
return reports.run(()=>runWithReportSession(plan, reports));
|
|
3150
|
+
return runWithMidsceneRunDir(plan.artifactDir, ()=>reports.run(()=>runWithReportSession(plan, reports)));
|
|
3122
3151
|
}
|
|
3123
3152
|
async function runWithReportSession(plan, reports) {
|
|
3124
3153
|
const { startedAt, runId, projectRoot, configPath, resultDir, runDir, summaryPath, reportDir, definition, projects: preparedProjects } = plan;
|