@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/cli/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { globSync } from "tinyglobby";
|
|
|
7
7
|
import { createHash, randomUUID } from "node:crypto";
|
|
8
8
|
import { JSON_SCHEMA, load } from "js-yaml";
|
|
9
9
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
10
|
+
import { resolveMidsceneRunDir, runWithMidsceneRunDir } from "@midscene/shared/common";
|
|
10
11
|
import { setMaxListeners } from "node:events";
|
|
11
12
|
import { ReportSession, TestRunReportAssembler, calculateTestRunHealth } from "@midscene/core/report";
|
|
12
13
|
import { getDebug, runWithConsoleLogScope } from "@midscene/shared/logger";
|
|
@@ -249,8 +250,7 @@ const validateTestOptions = (value, hasExplicitProjects)=>{
|
|
|
249
250
|
testTimeout: validatePositiveInteger(candidate.testTimeout, 120000, 'test.testTimeout')
|
|
250
251
|
});
|
|
251
252
|
};
|
|
252
|
-
const validateOutputPath = (value,
|
|
253
|
-
if (void 0 === value) return fallback;
|
|
253
|
+
const validateOutputPath = (value, label)=>{
|
|
254
254
|
if ('string' != typeof value || 0 === value.trim().length) throw new TypeError(`Midscene config ${label} must be non-empty.`);
|
|
255
255
|
return value;
|
|
256
256
|
};
|
|
@@ -264,7 +264,9 @@ const validateOutput = (value)=>{
|
|
|
264
264
|
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.');
|
|
265
265
|
return Object.freeze({
|
|
266
266
|
reportFormat: candidate.reportFormat ?? 'single-html',
|
|
267
|
-
|
|
267
|
+
...void 0 === candidate.reportDir ? {} : {
|
|
268
|
+
reportDir: validateOutputPath(candidate.reportDir, 'output.reportDir')
|
|
269
|
+
}
|
|
268
270
|
});
|
|
269
271
|
};
|
|
270
272
|
const validateTestProjectDefinition = (definition)=>{
|
|
@@ -852,8 +854,16 @@ const DEFAULT_TEST_FILE_SELECTION = {
|
|
|
852
854
|
]
|
|
853
855
|
};
|
|
854
856
|
const project_preparation_toPosix = (value)=>value.split(sep).join('/');
|
|
855
|
-
const discoverResolvedTestFiles = (projectRoot, selection)=>{
|
|
857
|
+
const discoverResolvedTestFiles = (projectRoot, selection, excludedDirectories = [])=>{
|
|
856
858
|
const root = external_node_path_resolve(projectRoot);
|
|
859
|
+
const outputPatterns = excludedDirectories.flatMap((directory)=>{
|
|
860
|
+
const withinRoot = relative(root, directory);
|
|
861
|
+
if (!withinRoot || isAbsolute(withinRoot) || '..' === withinRoot || withinRoot.startsWith(`..${sep}`)) return [];
|
|
862
|
+
const literal = project_preparation_toPosix(withinRoot).replace(/([*?{}[\]()!])/g, '\\$1');
|
|
863
|
+
return [
|
|
864
|
+
`${literal}/**`
|
|
865
|
+
];
|
|
866
|
+
});
|
|
857
867
|
const match = (patterns)=>globSync(patterns, {
|
|
858
868
|
absolute: true,
|
|
859
869
|
caseSensitiveMatch: false,
|
|
@@ -863,6 +873,7 @@ const discoverResolvedTestFiles = (projectRoot, selection)=>{
|
|
|
863
873
|
followSymbolicLinks: false,
|
|
864
874
|
ignore: [
|
|
865
875
|
...ALWAYS_IGNORED_PATTERNS,
|
|
876
|
+
...outputPatterns,
|
|
866
877
|
...selection.exclude ?? []
|
|
867
878
|
],
|
|
868
879
|
onlyFiles: true
|
|
@@ -937,7 +948,7 @@ async function prepareProject(project, projectRoot, runDir, defaultTimeoutMs, op
|
|
|
937
948
|
const platform = options.platform?.trim();
|
|
938
949
|
const fileSelection = project.files ?? DEFAULT_TEST_FILE_SELECTION;
|
|
939
950
|
const prerequisiteFile = options.prerequisiteFile ? external_node_path_resolve(options.prerequisiteFile) : void 0;
|
|
940
|
-
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection);
|
|
951
|
+
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection, options.excludedDirectories);
|
|
941
952
|
const files = [
|
|
942
953
|
...prerequisiteFile ? [
|
|
943
954
|
prerequisiteFile
|
|
@@ -1102,40 +1113,58 @@ async function prepareTestRun(options) {
|
|
|
1102
1113
|
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}\`.`);
|
|
1103
1114
|
if (options.configPath && !existsSync(configPath)) throw new Error(`Midscene config does not exist: ${configPath}`);
|
|
1104
1115
|
const definition = await loadTestProject(configPath);
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1116
|
+
const artifactDir = resolveMidsceneRunDir(input.projectRoot);
|
|
1117
|
+
return runWithMidsceneRunDir(artifactDir, async ()=>{
|
|
1118
|
+
const resultDir = options.resultDir ? external_node_path_resolve(input.cwd, options.resultDir) : join(artifactDir, 'test-results');
|
|
1119
|
+
const runDir = join(resultDir, runId);
|
|
1120
|
+
const summaryPath = join(runDir, 'summary.json');
|
|
1121
|
+
const reportDir = definition.output.reportDir ? external_node_path_resolve(input.projectRoot, definition.output.reportDir) : join(artifactDir, 'report');
|
|
1122
|
+
mkdirSync(resultDir, {
|
|
1123
|
+
recursive: true
|
|
1124
|
+
});
|
|
1125
|
+
mkdirSync(runDir);
|
|
1126
|
+
const projects = [];
|
|
1127
|
+
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, {
|
|
1128
|
+
...input.singleFile ? {
|
|
1129
|
+
files: [
|
|
1130
|
+
input.singleFile
|
|
1131
|
+
]
|
|
1132
|
+
} : {},
|
|
1133
|
+
excludedDirectories: [
|
|
1134
|
+
artifactDir,
|
|
1135
|
+
resultDir,
|
|
1136
|
+
reportDir,
|
|
1137
|
+
...[
|
|
1138
|
+
'cache',
|
|
1139
|
+
'log',
|
|
1140
|
+
'output',
|
|
1141
|
+
'tmp',
|
|
1142
|
+
'dump'
|
|
1143
|
+
].map((name)=>join(artifactDir, name))
|
|
1144
|
+
]
|
|
1145
|
+
}));
|
|
1146
|
+
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
1147
|
+
return {
|
|
1148
|
+
startedAt,
|
|
1149
|
+
runId,
|
|
1150
|
+
projectRoot: input.projectRoot,
|
|
1151
|
+
artifactDir,
|
|
1152
|
+
...configPath ? {
|
|
1153
|
+
configPath
|
|
1154
|
+
} : {},
|
|
1155
|
+
resultDir,
|
|
1156
|
+
runDir,
|
|
1157
|
+
summaryPath,
|
|
1158
|
+
reportDir,
|
|
1159
|
+
definition,
|
|
1160
|
+
projects,
|
|
1161
|
+
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
1162
|
+
reportEnabled: true,
|
|
1163
|
+
publications: [],
|
|
1164
|
+
onProgress: options.onProgress ?? (()=>{}),
|
|
1165
|
+
onEvent: options.onEvent
|
|
1166
|
+
};
|
|
1111
1167
|
});
|
|
1112
|
-
mkdirSync(runDir);
|
|
1113
|
-
const projects = [];
|
|
1114
|
-
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, input.singleFile ? {
|
|
1115
|
-
files: [
|
|
1116
|
-
input.singleFile
|
|
1117
|
-
]
|
|
1118
|
-
} : void 0));
|
|
1119
|
-
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
1120
|
-
return {
|
|
1121
|
-
startedAt,
|
|
1122
|
-
runId,
|
|
1123
|
-
projectRoot: input.projectRoot,
|
|
1124
|
-
...configPath ? {
|
|
1125
|
-
configPath
|
|
1126
|
-
} : {},
|
|
1127
|
-
resultDir,
|
|
1128
|
-
runDir,
|
|
1129
|
-
summaryPath,
|
|
1130
|
-
reportDir,
|
|
1131
|
-
definition,
|
|
1132
|
-
projects,
|
|
1133
|
-
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
1134
|
-
reportEnabled: true,
|
|
1135
|
-
publications: [],
|
|
1136
|
-
onProgress: options.onProgress ?? (()=>{}),
|
|
1137
|
-
onEvent: options.onEvent
|
|
1138
|
-
};
|
|
1139
1168
|
}
|
|
1140
1169
|
function renderTestBadge(summary) {
|
|
1141
1170
|
return ``;
|
|
@@ -1886,7 +1915,7 @@ const latestById = (items, id)=>[
|
|
|
1886
1915
|
const notRunSuite = (prepared, reason)=>prepared.documents.flatMap((document)=>document.cases.map((item)=>asNotRun(document.documentId, item, prepared.project.name, reason)));
|
|
1887
1916
|
async function runPreparedTestProject(plan) {
|
|
1888
1917
|
const reports = new ReportSession(join(plan.runDir, 'records'));
|
|
1889
|
-
return reports.run(()=>runWithReportSession(plan, reports));
|
|
1918
|
+
return runWithMidsceneRunDir(plan.artifactDir, ()=>reports.run(()=>runWithReportSession(plan, reports)));
|
|
1890
1919
|
}
|
|
1891
1920
|
async function runWithReportSession(plan, reports) {
|
|
1892
1921
|
const { startedAt, runId, projectRoot, configPath, resultDir, runDir, summaryPath, reportDir, definition, projects: preparedProjects } = plan;
|