@midscene/core 1.17.4 → 1.17.5
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/agent/agent-report-manager.mjs +28 -5
- package/dist/es/agent/agent-report-manager.mjs.map +1 -1
- package/dist/es/agent/agent.mjs +2 -2
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/dump/html-utils.mjs +51 -68
- package/dist/es/dump/html-utils.mjs.map +1 -1
- package/dist/es/dump/report-artifact-publication.mjs +52 -0
- package/dist/es/dump/report-artifact-publication.mjs.map +1 -0
- package/dist/es/dump/report-artifact-store.mjs +2 -2
- package/dist/es/dump/report-artifact-store.mjs.map +1 -1
- package/dist/es/dump/report-artifact-writer.mjs +129 -0
- package/dist/es/dump/report-artifact-writer.mjs.map +1 -0
- package/dist/es/dump/report-session.mjs +229 -0
- package/dist/es/dump/report-session.mjs.map +1 -0
- package/dist/es/dump/test-report-images.mjs +68 -42
- package/dist/es/dump/test-report-images.mjs.map +1 -1
- package/dist/es/index.mjs +2 -2
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/report-cli.mjs +38 -11
- package/dist/es/report-cli.mjs.map +1 -1
- package/dist/es/report-generator.mjs +2 -1
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/report.mjs +152 -159
- package/dist/es/report.mjs.map +1 -1
- package/dist/es/test-run-report.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/es/yaml/player.mjs +1 -1
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/lib/agent/agent-report-manager.js +27 -4
- package/dist/lib/agent/agent-report-manager.js.map +1 -1
- package/dist/lib/agent/agent.js +2 -2
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/dump/html-utils.js +59 -70
- package/dist/lib/dump/html-utils.js.map +1 -1
- package/dist/lib/dump/report-artifact-publication.js +89 -0
- package/dist/lib/dump/report-artifact-publication.js.map +1 -0
- package/dist/lib/dump/report-artifact-store.js +2 -2
- package/dist/lib/dump/report-artifact-store.js.map +1 -1
- package/dist/lib/dump/report-artifact-writer.js +163 -0
- package/dist/lib/dump/report-artifact-writer.js.map +1 -0
- package/dist/lib/dump/report-session.js +266 -0
- package/dist/lib/dump/report-session.js.map +1 -0
- package/dist/lib/dump/test-report-images.js +67 -41
- package/dist/lib/dump/test-report-images.js.map +1 -1
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/report-cli.js +37 -10
- package/dist/lib/report-cli.js.map +1 -1
- package/dist/lib/report-generator.js +2 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/report.js +152 -153
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/test-run-report.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/yaml/player.js +1 -1
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/types/agent/agent-report-manager.d.ts +4 -1
- package/dist/types/agent/agent-report-manager.d.ts.map +1 -1
- package/dist/types/agent/agent.d.ts +1 -1
- package/dist/types/agent/agent.d.ts.map +1 -1
- package/dist/types/dump/html-utils.d.ts +7 -1
- package/dist/types/dump/html-utils.d.ts.map +1 -1
- package/dist/types/dump/report-artifact-publication.d.ts +5 -0
- package/dist/types/dump/report-artifact-publication.d.ts.map +1 -0
- package/dist/types/dump/report-artifact-store.d.ts +1 -1
- package/dist/types/dump/report-artifact-store.d.ts.map +1 -1
- package/dist/types/dump/report-artifact-writer.d.ts +21 -0
- package/dist/types/dump/report-artifact-writer.d.ts.map +1 -0
- package/dist/types/dump/report-session.d.ts +48 -0
- package/dist/types/dump/report-session.d.ts.map +1 -0
- package/dist/types/dump/test-report-images.d.ts +5 -2
- package/dist/types/dump/test-report-images.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/report-cli.d.ts +2 -1
- package/dist/types/report-cli.d.ts.map +1 -1
- package/dist/types/report-generator.d.ts.map +1 -1
- package/dist/types/report.d.ts +11 -0
- package/dist/types/report.d.ts.map +1 -1
- package/dist/types/test-run-report.d.ts +2 -2
- package/dist/types/test-run-report.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/lib/report.js
CHANGED
|
@@ -27,8 +27,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27
27
|
readReportArtifactManifestAsync: ()=>report_artifact_reader_js_namespaceObject.readReportArtifactManifestAsync,
|
|
28
28
|
readReportDumpScripts: ()=>report_artifact_reader_js_namespaceObject.readReportDumpScripts,
|
|
29
29
|
ReportMergingTool: ()=>ReportMergingTool,
|
|
30
|
+
ReportSession: ()=>report_session_js_namespaceObject.ReportSession,
|
|
30
31
|
TestRunReportAssembler: ()=>TestRunReportAssembler,
|
|
31
32
|
collectDedupedExecutions: ()=>collectDedupedExecutions,
|
|
33
|
+
exportReportArtifact: ()=>exportReportArtifact,
|
|
32
34
|
splitReportHtmlByExecution: ()=>splitReportHtmlByExecution,
|
|
33
35
|
streamReportDumpScripts: ()=>report_artifact_reader_js_namespaceObject.streamReportDumpScripts,
|
|
34
36
|
isDirectoryModeReport: ()=>isDirectoryModeReport,
|
|
@@ -54,7 +56,9 @@ const report_artifact_reader_js_namespaceObject = require("./dump/report-artifac
|
|
|
54
56
|
const screenshot_store_js_namespaceObject = require("./dump/screenshot-store.js");
|
|
55
57
|
const execution_recorder_js_namespaceObject = require("./dump/execution-recorder.js");
|
|
56
58
|
const report_artifact_store_js_namespaceObject = require("./dump/report-artifact-store.js");
|
|
57
|
-
const
|
|
59
|
+
const report_session_js_namespaceObject = require("./dump/report-session.js");
|
|
60
|
+
const report_artifact_publication_js_namespaceObject = require("./dump/report-artifact-publication.js");
|
|
61
|
+
const report_artifact_writer_js_namespaceObject = require("./dump/report-artifact-writer.js");
|
|
58
62
|
const external_report_stats_js_namespaceObject = require("./report-stats.js");
|
|
59
63
|
const merge_report_js_namespaceObject = require("./test-runner/reporting/merge-report.js");
|
|
60
64
|
const metrics_js_namespaceObject = require("./test-runner/reporting/metrics.js");
|
|
@@ -71,6 +75,64 @@ function _define_property(obj, key, value) {
|
|
|
71
75
|
else obj[key] = value;
|
|
72
76
|
return obj;
|
|
73
77
|
}
|
|
78
|
+
async function exportReportArtifact(options) {
|
|
79
|
+
validateTestRunReportFileName(options.reportFileName);
|
|
80
|
+
const input = external_node_path_namespaceObject.resolve(options.reportPath);
|
|
81
|
+
const output = external_node_path_namespaceObject.resolve(options.outputDir);
|
|
82
|
+
const external = 'html-and-external-assets' === options.outputFormat;
|
|
83
|
+
const artifact = external_node_path_namespaceObject.join(output, options.reportFileName);
|
|
84
|
+
const destination = external ? external_node_path_namespaceObject.join(artifact, 'index.html') : `${artifact}.html`;
|
|
85
|
+
if (input === destination || external && input.startsWith(`${artifact}${external_node_path_namespaceObject.sep}`)) throw new Error('Export destination must differ from the input report.');
|
|
86
|
+
if (!options.overwrite && (0, external_node_fs_namespaceObject.existsSync)(external ? artifact : destination)) throw new Error(`Report artifact already exists: ${artifact}`);
|
|
87
|
+
const manifest = (0, report_artifact_reader_js_namespaceObject.readReportArtifactManifest)(input);
|
|
88
|
+
const runner = (0, report_artifact_reader_js_namespaceObject.readReportRunnerDump)(input);
|
|
89
|
+
const groups = new Map();
|
|
90
|
+
for (const source of (0, report_artifact_reader_js_namespaceObject.readReportDumpScripts)(input)){
|
|
91
|
+
const attributes = Object.fromEntries([
|
|
92
|
+
...source.openTag.matchAll(/([^\s=]+)="([^"]*)"/g)
|
|
93
|
+
].filter(([, key])=>'type' !== key).map(([, key, value])=>[
|
|
94
|
+
key,
|
|
95
|
+
decodeURIComponent(value)
|
|
96
|
+
]));
|
|
97
|
+
const id = attributes['data-group-id'];
|
|
98
|
+
if (!id) throw new Error('Report execution group is missing its ID.');
|
|
99
|
+
const dump = external_types_js_namespaceObject.ReportActionDump.fromSerializedString(manifest ? source.content : (0, utils_namespaceObject.antiEscapeScriptTag)(source.content));
|
|
100
|
+
const previous = groups.get(id);
|
|
101
|
+
dump.executions = dedupeExecutionsKeepLatest([
|
|
102
|
+
...previous?.dump.executions ?? [],
|
|
103
|
+
...dump.executions
|
|
104
|
+
]);
|
|
105
|
+
groups.set(id, {
|
|
106
|
+
dump,
|
|
107
|
+
attributes
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (!groups.size && !runner) throw new Error('No report execution data was found in the input.');
|
|
111
|
+
const hint = [
|
|
112
|
+
...groups.values()
|
|
113
|
+
][0]?.attributes['data-report-kind'];
|
|
114
|
+
const kind = manifest?.kind ?? ('agent' === hint || 'test' === hint ? hint : runner ? 'test' : 'agent');
|
|
115
|
+
await promises_namespaceObject.mkdir(output, {
|
|
116
|
+
recursive: true
|
|
117
|
+
});
|
|
118
|
+
const temporary = await promises_namespaceObject.mkdtemp(external_node_path_namespaceObject.join(output, '.report-export-'));
|
|
119
|
+
const entry = external_node_path_namespaceObject.join(temporary, 'index.html');
|
|
120
|
+
try {
|
|
121
|
+
const writer = new report_artifact_writer_js_namespaceObject.ReportArtifactWriter(entry, external, kind, manifest?.reportId ?? runner?.runId);
|
|
122
|
+
await writer.initialize();
|
|
123
|
+
for (const [id, group] of groups)await writer.addGroup(id, group.dump.serialize(), input, group.attributes);
|
|
124
|
+
await writer.finish(runner, mergedAgentReportComment([
|
|
125
|
+
...groups.values()
|
|
126
|
+
].map((group)=>group.dump)));
|
|
127
|
+
await (0, report_artifact_publication_js_namespaceObject.publishReportArtifact)(external ? temporary : entry, external ? artifact : destination, external, options.overwrite);
|
|
128
|
+
return destination;
|
|
129
|
+
} finally{
|
|
130
|
+
await promises_namespaceObject.rm(temporary, {
|
|
131
|
+
recursive: true,
|
|
132
|
+
force: true
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
74
136
|
const screenshotModeAttrRegExp = new RegExp(`${html_utils_js_namespaceObject.DATA_SCREENSHOT_MODE_ATTR}="(inline|directory)"`);
|
|
75
137
|
function readDeclaredScreenshotMode(reportFilePath) {
|
|
76
138
|
let mode;
|
|
@@ -174,8 +236,8 @@ class ReportMergingTool {
|
|
|
174
236
|
clear() {
|
|
175
237
|
this.reportInfos = [];
|
|
176
238
|
}
|
|
177
|
-
mergeDumpScripts(contents) {
|
|
178
|
-
const unescaped = contents.map((c)=>(0, utils_namespaceObject.antiEscapeScriptTag)(c)).filter((c)=>c.length > 0);
|
|
239
|
+
mergeDumpScripts(contents, external) {
|
|
240
|
+
const unescaped = contents.map((c)=>external ? c : (0, utils_namespaceObject.antiEscapeScriptTag)(c)).filter((c)=>c.length > 0);
|
|
179
241
|
if (0 === unescaped.length) return '';
|
|
180
242
|
if (1 === unescaped.length) return unescaped[0];
|
|
181
243
|
const base = external_types_js_namespaceObject.ReportActionDump.fromSerializedString(unescaped[0]);
|
|
@@ -189,99 +251,67 @@ class ReportMergingTool {
|
|
|
189
251
|
base.executions = dedupeExecutionsKeepLatest(allExecutions);
|
|
190
252
|
return base.serialize();
|
|
191
253
|
}
|
|
192
|
-
mergeReports(reportFileName = 'AUTO', opts) {
|
|
193
|
-
const { rmOriginalReports = false, overwrite = false, outputDir } = opts
|
|
194
|
-
if (
|
|
254
|
+
mergeReports(reportFileName = 'AUTO', opts = {}) {
|
|
255
|
+
const { rmOriginalReports = false, overwrite = false, outputDir, outputFormat } = opts;
|
|
256
|
+
if (!this.reportInfos.length) {
|
|
195
257
|
(0, utils_namespaceObject.logMsg)('No reports to merge');
|
|
196
258
|
return null;
|
|
197
259
|
}
|
|
198
260
|
const runnerDumps = this.reportInfos.map((info)=>info.reportFilePath ? (0, report_artifact_reader_js_namespaceObject.readReportRunnerDump)(info.reportFilePath) : void 0);
|
|
199
261
|
const hasRunnerDump = runnerDumps.some(Boolean);
|
|
262
|
+
const external = 'html-and-external-assets' === outputFormat;
|
|
263
|
+
const name = 'AUTO' === reportFileName ? (0, report_file_name_js_namespaceObject.getReportFileName)('merged-report') : reportFileName;
|
|
264
|
+
validateTestRunReportFileName(name);
|
|
200
265
|
const targetDir = outputDir ? external_node_path_namespaceObject.resolve(outputDir) : (0, common_namespaceObject.getMidsceneRunSubDir)('report');
|
|
201
|
-
|
|
202
|
-
recursive: true
|
|
203
|
-
});
|
|
204
|
-
const isDirModeByIndex = this.reportInfos.map((info)=>Boolean(info.reportFilePath && isDirectoryModeReport(info.reportFilePath)));
|
|
205
|
-
const hasDirectoryModeReport = isDirModeByIndex.some(Boolean);
|
|
206
|
-
const resolvedName = 'AUTO' === reportFileName ? (0, report_file_name_js_namespaceObject.getReportFileName)('merged-report') : reportFileName;
|
|
207
|
-
const outputFilePath = hasDirectoryModeReport ? external_node_path_namespaceObject.resolve(targetDir, resolvedName, 'index.html') : external_node_path_namespaceObject.resolve(targetDir, `${resolvedName}.html`);
|
|
208
|
-
if ('AUTO' !== reportFileName && (0, external_node_fs_namespaceObject.existsSync)(outputFilePath)) {
|
|
209
|
-
if (!overwrite) throw new Error(`Report file already exists: ${outputFilePath}\nSet overwrite to true to overwrite this file.`);
|
|
210
|
-
if (hasDirectoryModeReport) (0, external_node_fs_namespaceObject.rmSync)(external_node_path_namespaceObject.dirname(outputFilePath), {
|
|
211
|
-
recursive: true,
|
|
212
|
-
force: true
|
|
213
|
-
});
|
|
214
|
-
else (0, external_node_fs_namespaceObject.unlinkSync)(outputFilePath);
|
|
215
|
-
}
|
|
216
|
-
if (hasDirectoryModeReport) (0, external_node_fs_namespaceObject.mkdirSync)(external_node_path_namespaceObject.dirname(outputFilePath), {
|
|
266
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(targetDir, {
|
|
217
267
|
recursive: true
|
|
218
268
|
});
|
|
219
|
-
|
|
269
|
+
const artifact = external_node_path_namespaceObject.join(targetDir, name);
|
|
270
|
+
const outputFilePath = external ? external_node_path_namespaceObject.join(artifact, 'index.html') : `${artifact}.html`;
|
|
271
|
+
if (!overwrite && (0, external_node_fs_namespaceObject.existsSync)(external ? artifact : outputFilePath)) throw new Error(`Report file already exists: ${outputFilePath}\nSet overwrite to true to overwrite this file.`);
|
|
272
|
+
if (rmOriginalReports && this.reportInfos.some((info)=>info.reportFilePath && isDirectoryBasedReport(info.reportFilePath) && outputFilePath.startsWith(`${external_node_path_namespaceObject.dirname(external_node_path_namespaceObject.resolve(info.reportFilePath))}${external_node_path_namespaceObject.sep}`))) throw new Error('Merged output must be outside source report directories when removing originals.');
|
|
273
|
+
const temporary = (0, external_node_fs_namespaceObject.mkdtempSync)(external_node_path_namespaceObject.join(targetDir, '.merged-report-'));
|
|
274
|
+
const entry = external_node_path_namespaceObject.join(temporary, 'index.html');
|
|
220
275
|
try {
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
const htmlEndIdx = tpl.lastIndexOf(htmlEndTag);
|
|
224
|
-
const tplWithoutClose = -1 !== htmlEndIdx ? tpl.slice(0, htmlEndIdx) : tpl;
|
|
225
|
-
(0, external_node_fs_namespaceObject.appendFileSync)(outputFilePath, tplWithoutClose);
|
|
226
|
-
if (hasDirectoryModeReport) (0, external_node_fs_namespaceObject.appendFileSync)(outputFilePath, (0, html_utils_js_namespaceObject.getBaseUrlFixScript)());
|
|
276
|
+
const writer = new report_artifact_writer_js_namespaceObject.ReportArtifactWriter(entry, external, hasRunnerDump ? 'test' : 'agent');
|
|
277
|
+
writer.initializeSync();
|
|
227
278
|
const agentReports = [];
|
|
228
279
|
const runnerSources = [];
|
|
229
|
-
const
|
|
230
|
-
for(
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
const screenshotsDir = external_node_path_namespaceObject.join(reportDir, 'screenshots');
|
|
240
|
-
if ((0, external_node_fs_namespaceObject.existsSync)(screenshotsDir)) {
|
|
241
|
-
const mergedScreenshotsDir = external_node_path_namespaceObject.join(external_node_path_namespaceObject.dirname(outputFilePath), 'screenshots');
|
|
242
|
-
(0, external_node_fs_namespaceObject.mkdirSync)(mergedScreenshotsDir, {
|
|
243
|
-
recursive: true
|
|
244
|
-
});
|
|
245
|
-
for (const file of (0, external_node_fs_namespaceObject.readdirSync)(screenshotsDir)){
|
|
246
|
-
const src = external_node_path_namespaceObject.join(screenshotsDir, file);
|
|
247
|
-
const dest = external_node_path_namespaceObject.join(mergedScreenshotsDir, file);
|
|
248
|
-
(0, external_node_fs_namespaceObject.copyFileSync)(src, dest);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
} else (0, html_utils_js_namespaceObject.streamImageScriptsToFile)(reportInfo.reportFilePath, outputFilePath, writtenInlineImageIds);
|
|
252
|
-
const allDumps = (0, report_artifact_reader_js_namespaceObject.readReportDumpScripts)(reportInfo.reportFilePath).filter((d)=>d.openTag.includes('data-group-id'));
|
|
253
|
-
const groupIdMatch = allDumps[0]?.openTag.match(/data-group-id="([^"]+)"/);
|
|
254
|
-
if (groupIdMatch && !hasRunnerDump) mergedGroupId = decodeURIComponent(groupIdMatch[1]);
|
|
255
|
-
const extractedDumpString = allDumps.length > 0 ? this.mergeDumpScripts(allDumps.map((d)=>d.content)) : (0, html_utils_js_namespaceObject.extractLastDumpScriptSync)(reportInfo.reportFilePath);
|
|
256
|
-
if (extractedDumpString) dumpString = extractedDumpString;
|
|
280
|
+
const groupIds = new Set();
|
|
281
|
+
for (const [index, info] of this.reportInfos.entries()){
|
|
282
|
+
const attributes = info.reportAttributes;
|
|
283
|
+
let serialized = this.createEmptyDumpString(attributes.testTitle, attributes.testDescription);
|
|
284
|
+
let groupId = `merged-group-${index}`;
|
|
285
|
+
if (info.reportFilePath) {
|
|
286
|
+
const dumps = (0, report_artifact_reader_js_namespaceObject.readReportDumpScripts)(info.reportFilePath);
|
|
287
|
+
const originalId = dumps[0]?.openTag.match(/data-group-id="([^"]+)"/)?.[1];
|
|
288
|
+
if (originalId && !hasRunnerDump && !groupIds.has(decodeURIComponent(originalId))) groupId = decodeURIComponent(originalId);
|
|
289
|
+
serialized = dumps.length ? this.mergeDumpScripts(dumps.map((dump)=>dump.content), Boolean((0, report_artifact_reader_js_namespaceObject.readReportArtifactManifest)(info.reportFilePath))) : (0, html_utils_js_namespaceObject.extractLastDumpScriptSync)(info.reportFilePath) ?? serialized;
|
|
257
290
|
}
|
|
258
|
-
|
|
291
|
+
if (groupIds.has(groupId)) groupId = `merged-group-${(0, utils_namespaceObject.uuid)()}`;
|
|
292
|
+
groupIds.add(groupId);
|
|
293
|
+
const agentReport = tryParseAgentReportDump(serialized);
|
|
259
294
|
if (agentReport) agentReports.push(agentReport);
|
|
260
295
|
if (hasRunnerDump) runnerSources.push({
|
|
261
|
-
reportId:
|
|
262
|
-
sourcePath:
|
|
263
|
-
attributes
|
|
264
|
-
dump: runnerDumps[
|
|
265
|
-
timing: agentReport ? agentReportTiming(agentReport,
|
|
296
|
+
reportId: groupId,
|
|
297
|
+
sourcePath: info.reportFilePath ?? '<skipped-agent-report>',
|
|
298
|
+
attributes,
|
|
299
|
+
dump: runnerDumps[index],
|
|
300
|
+
timing: agentReport ? agentReportTiming(agentReport, attributes.testDuration) : void 0
|
|
301
|
+
});
|
|
302
|
+
writer.addGroupSync(groupId, serialized, info.reportFilePath ?? entry, {
|
|
303
|
+
...hasRunnerDump ? {
|
|
304
|
+
'data-report-id': groupId
|
|
305
|
+
} : {},
|
|
306
|
+
playwright_test_duration: attributes.testDuration,
|
|
307
|
+
playwright_test_status: attributes.testStatus,
|
|
308
|
+
playwright_test_title: attributes.testTitle,
|
|
309
|
+
playwright_test_id: attributes.testId,
|
|
310
|
+
playwright_test_description: attributes.testDescription,
|
|
311
|
+
is_merged: true
|
|
266
312
|
});
|
|
267
|
-
const reportHtmlStr = `${(0, external_utils_js_namespaceObject.reportHTMLContent)({
|
|
268
|
-
dumpString,
|
|
269
|
-
attributes: {
|
|
270
|
-
'data-group-id': mergedGroupId,
|
|
271
|
-
...hasRunnerDump ? {
|
|
272
|
-
'data-report-id': mergedGroupId
|
|
273
|
-
} : {},
|
|
274
|
-
[html_utils_js_namespaceObject.DATA_SCREENSHOT_MODE_ATTR]: hasDirectoryModeReport ? 'directory' : 'inline',
|
|
275
|
-
playwright_test_duration: reportAttributes.testDuration,
|
|
276
|
-
playwright_test_status: reportAttributes.testStatus,
|
|
277
|
-
playwright_test_title: reportAttributes.testTitle,
|
|
278
|
-
playwright_test_id: reportAttributes.testId,
|
|
279
|
-
playwright_test_description: reportAttributes.testDescription,
|
|
280
|
-
is_merged: true
|
|
281
|
-
}
|
|
282
|
-
}, void 0, void 0, false)}\n`;
|
|
283
|
-
(0, external_node_fs_namespaceObject.appendFileSync)(outputFilePath, reportHtmlStr);
|
|
284
313
|
}
|
|
314
|
+
let runner;
|
|
285
315
|
if (hasRunnerDump) {
|
|
286
316
|
const executions = dedupeExecutionsKeepLatest(agentReports.flatMap((report)=>report.executions));
|
|
287
317
|
const metrics = (0, metrics_js_namespaceObject.collectTestRunReportMetrics)({
|
|
@@ -297,30 +327,22 @@ class ReportMergingTool {
|
|
|
297
327
|
})
|
|
298
328
|
]
|
|
299
329
|
] : []));
|
|
300
|
-
|
|
330
|
+
runner = (0, merge_report_js_namespaceObject.mergeTestRunReportDumps)(runnerSources, metrics, (0, utils_namespaceObject.uuid)(), executionMetrics);
|
|
301
331
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
(0, external_node_fs_namespaceObject.appendFileSync)(outputFilePath, `${htmlEndTag}\n`);
|
|
305
|
-
(0, utils_namespaceObject.logMsg)(`Successfully merged new report: ${outputFilePath}`);
|
|
332
|
+
writer.finishSync(runner, mergedAgentReportComment(agentReports));
|
|
333
|
+
(0, report_artifact_publication_js_namespaceObject.publishReportArtifactSync)(external ? temporary : entry, external ? artifact : outputFilePath, external, overwrite);
|
|
306
334
|
if (rmOriginalReports) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
reportCountWithFilePath += 1;
|
|
311
|
-
try {
|
|
312
|
-
removeReportArtifact(info.reportFilePath);
|
|
313
|
-
removedReportCount += 1;
|
|
314
|
-
} catch (error) {
|
|
315
|
-
(0, utils_namespaceObject.logMsg)(`Error deleting report ${info.reportFilePath}: ${error}`);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
(0, utils_namespaceObject.logMsg)(`Removed ${removedReportCount}/${reportCountWithFilePath} original reports`);
|
|
335
|
+
for (const sourcePath of new Set(this.reportInfos.flatMap((info)=>info.reportFilePath ? [
|
|
336
|
+
external_node_path_namespaceObject.resolve(info.reportFilePath)
|
|
337
|
+
] : [])))if (sourcePath !== outputFilePath) removeReportArtifact(sourcePath);
|
|
319
338
|
}
|
|
339
|
+
(0, utils_namespaceObject.logMsg)(`Successfully merged new report: ${outputFilePath}`);
|
|
320
340
|
return outputFilePath;
|
|
321
|
-
}
|
|
322
|
-
(0,
|
|
323
|
-
|
|
341
|
+
} finally{
|
|
342
|
+
(0, external_node_fs_namespaceObject.rmSync)(temporary, {
|
|
343
|
+
recursive: true,
|
|
344
|
+
force: true
|
|
345
|
+
});
|
|
324
346
|
}
|
|
325
347
|
}
|
|
326
348
|
constructor(){
|
|
@@ -395,8 +417,15 @@ const prepareTestRunReportSources = (sources, loadedDumps)=>{
|
|
|
395
417
|
continue;
|
|
396
418
|
}
|
|
397
419
|
const sourceKey = source.sourcePath;
|
|
420
|
+
const imageOrigins = new Map();
|
|
421
|
+
JSON.parse(baseDump.serialize(), (_key, value)=>{
|
|
422
|
+
const ref = (0, image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
|
|
423
|
+
if (ref) imageOrigins.set(ref.id, 'file' === ref.storage ? source.dumpPath ?? source.sourcePath : source.sourcePath);
|
|
424
|
+
return value;
|
|
425
|
+
});
|
|
398
426
|
const shared = preparedByPath.get(sourceKey);
|
|
399
427
|
if (shared) {
|
|
428
|
+
for (const [id, origin] of imageOrigins)shared.imageOrigins.set(id, origin);
|
|
400
429
|
if (source.dumpPath) shared.dump.executions = dedupeExecutionsKeepLatest([
|
|
401
430
|
...shared.dump.executions,
|
|
402
431
|
...baseDump.executions
|
|
@@ -456,6 +485,7 @@ const prepareTestRunReportSources = (sources, loadedDumps)=>{
|
|
|
456
485
|
executionIds,
|
|
457
486
|
collection: source.collection,
|
|
458
487
|
dump,
|
|
488
|
+
imageOrigins,
|
|
459
489
|
...source.dumpPath ? {
|
|
460
490
|
dumpPath: source.dumpPath
|
|
461
491
|
} : {}
|
|
@@ -530,41 +560,25 @@ class TestRunReportAssembler {
|
|
|
530
560
|
});
|
|
531
561
|
const artifact = external_node_path_namespaceObject.join(outputDir, options.reportFileName);
|
|
532
562
|
const finalPath = directoryMode ? external_node_path_namespaceObject.join(artifact, 'index.html') : `${artifact}.html`;
|
|
533
|
-
if (!options.overwrite && (
|
|
563
|
+
if (!options.overwrite && (0, external_node_fs_namespaceObject.existsSync)(directoryMode ? artifact : finalPath)) throw new Error(`Report artifact already exists: ${artifact}`);
|
|
534
564
|
const temporary = await promises_namespaceObject.mkdtemp(external_node_path_namespaceObject.join(outputDir, '.test-run-report-'));
|
|
535
565
|
const htmlPath = external_node_path_namespaceObject.join(temporary, 'index.html');
|
|
536
566
|
try {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const images = new test_report_images_js_namespaceObject.TestReportImages(htmlPath, directoryMode);
|
|
567
|
+
const writer = new report_artifact_writer_js_namespaceObject.ReportArtifactWriter(htmlPath, directoryMode, 'test', dump.runId);
|
|
568
|
+
await writer.initialize();
|
|
540
569
|
const reports = [];
|
|
541
570
|
for (const source of new Map(prepared.sources.map((source)=>[
|
|
542
571
|
source.reportId,
|
|
543
572
|
source
|
|
544
573
|
])).values()){
|
|
545
|
-
const serialized = await images.rewriteAsync(source.dump.serialize(), source.dumpPath ?? source.sourcePath);
|
|
546
574
|
reports.push(source.dump);
|
|
547
|
-
await
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
'data-report-id': source.reportId,
|
|
552
|
-
'data-runner-scope-id': source.scopeId,
|
|
553
|
-
[html_utils_js_namespaceObject.DATA_SCREENSHOT_MODE_ATTR]: directoryMode ? 'directory' : 'inline'
|
|
554
|
-
}
|
|
555
|
-
}, void 0, void 0, false));
|
|
556
|
-
}
|
|
557
|
-
await promises_namespaceObject.appendFile(htmlPath, (0, html_utils_js_namespaceObject.generateTestRunReportScriptTag)(dump) + mergedAgentReportComment(reports));
|
|
558
|
-
if (options.overwrite) {
|
|
559
|
-
await promises_namespaceObject.rm(artifact, {
|
|
560
|
-
recursive: true,
|
|
561
|
-
force: true
|
|
562
|
-
});
|
|
563
|
-
await promises_namespaceObject.rm(`${artifact}.html`, {
|
|
564
|
-
force: true
|
|
565
|
-
});
|
|
575
|
+
await writer.addGroup(source.reportId, source.dump.serialize(), source.dumpPath ?? source.sourcePath, {
|
|
576
|
+
'data-report-id': source.reportId,
|
|
577
|
+
'data-runner-scope-id': source.scopeId
|
|
578
|
+
}, source.imageOrigins);
|
|
566
579
|
}
|
|
567
|
-
await
|
|
580
|
+
await writer.finish(dump, mergedAgentReportComment(reports));
|
|
581
|
+
await (0, report_artifact_publication_js_namespaceObject.publishReportArtifact)(directoryMode ? temporary : htmlPath, directoryMode ? artifact : finalPath, directoryMode, options.overwrite);
|
|
568
582
|
return finalPath;
|
|
569
583
|
} finally{
|
|
570
584
|
await promises_namespaceObject.rm(temporary, {
|
|
@@ -602,8 +616,7 @@ class TestRunReportAssembler {
|
|
|
602
616
|
const standaloneReportPath = `${finalArtifactPath}.html`;
|
|
603
617
|
const finalReportPath = directoryMode ? directoryReportPath : standaloneReportPath;
|
|
604
618
|
const existingArtifacts = [
|
|
605
|
-
finalArtifactPath
|
|
606
|
-
standaloneReportPath
|
|
619
|
+
directoryMode ? finalArtifactPath : standaloneReportPath
|
|
607
620
|
].filter(external_node_fs_namespaceObject.existsSync);
|
|
608
621
|
if (existingArtifacts.length > 0 && !options.overwrite) throw new Error(`Report artifact already exists: ${existingArtifacts[0]}\nSet overwrite to true to overwrite this report.`);
|
|
609
622
|
const temporaryRoot = (0, external_node_fs_namespaceObject.mkdtempSync)(external_node_path_namespaceObject.join(outputDir, '.test-run-report-'));
|
|
@@ -613,39 +626,21 @@ class TestRunReportAssembler {
|
|
|
613
626
|
if (directoryMode) (0, external_node_fs_namespaceObject.mkdirSync)(temporaryArtifactPath, {
|
|
614
627
|
recursive: true
|
|
615
628
|
});
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
const htmlEndIndex = template.lastIndexOf(htmlEndTag);
|
|
619
|
-
(0, external_node_fs_namespaceObject.appendFileSync)(temporaryReportPath, -1 === htmlEndIndex ? template : template.slice(0, htmlEndIndex));
|
|
620
|
-
if (directoryMode) (0, external_node_fs_namespaceObject.appendFileSync)(temporaryReportPath, (0, html_utils_js_namespaceObject.getBaseUrlFixScript)());
|
|
621
|
-
const images = new test_report_images_js_namespaceObject.TestReportImages(temporaryReportPath, directoryMode);
|
|
629
|
+
const writer = new report_artifact_writer_js_namespaceObject.ReportArtifactWriter(temporaryReportPath, directoryMode, 'test', runnerDump.runId);
|
|
630
|
+
writer.initializeSync();
|
|
622
631
|
const agentReports = [];
|
|
623
632
|
for (const source of new Map(prepared.sources.map((source)=>[
|
|
624
633
|
source.reportId,
|
|
625
634
|
source
|
|
626
635
|
])).values()){
|
|
627
|
-
const serialized = images.rewriteSync(source.dump.serialize(), source.dumpPath ?? source.sourcePath);
|
|
628
636
|
agentReports.push(source.dump);
|
|
629
|
-
(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
'data-report-id': source.reportId,
|
|
634
|
-
'data-runner-scope-id': source.scopeId,
|
|
635
|
-
[html_utils_js_namespaceObject.DATA_SCREENSHOT_MODE_ATTR]: directoryMode ? 'directory' : 'inline'
|
|
636
|
-
}
|
|
637
|
-
}, void 0, void 0, false)}\n`);
|
|
637
|
+
writer.addGroupSync(source.reportId, source.dump.serialize(), source.dumpPath ?? source.sourcePath, {
|
|
638
|
+
'data-report-id': source.reportId,
|
|
639
|
+
'data-runner-scope-id': source.scopeId
|
|
640
|
+
}, source.imageOrigins);
|
|
638
641
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
if (agentComment) (0, external_node_fs_namespaceObject.appendFileSync)(temporaryReportPath, agentComment);
|
|
642
|
-
(0, external_node_fs_namespaceObject.appendFileSync)(temporaryReportPath, `${htmlEndTag}\n`);
|
|
643
|
-
if ((0, external_node_fs_namespaceObject.existsSync)(finalArtifactPath)) (0, external_node_fs_namespaceObject.rmSync)(finalArtifactPath, {
|
|
644
|
-
recursive: true,
|
|
645
|
-
force: true
|
|
646
|
-
});
|
|
647
|
-
if ((0, external_node_fs_namespaceObject.existsSync)(standaloneReportPath)) (0, external_node_fs_namespaceObject.unlinkSync)(standaloneReportPath);
|
|
648
|
-
(0, external_node_fs_namespaceObject.renameSync)(directoryMode ? temporaryArtifactPath : temporaryReportPath, directoryMode ? finalArtifactPath : standaloneReportPath);
|
|
642
|
+
writer.finishSync(runnerDump, mergedAgentReportComment(agentReports));
|
|
643
|
+
(0, report_artifact_publication_js_namespaceObject.publishReportArtifactSync)(directoryMode ? temporaryArtifactPath : temporaryReportPath, directoryMode ? finalArtifactPath : standaloneReportPath, directoryMode, options.overwrite);
|
|
649
644
|
(0, external_node_fs_namespaceObject.rmSync)(temporaryRoot, {
|
|
650
645
|
recursive: true,
|
|
651
646
|
force: true
|
|
@@ -764,11 +759,13 @@ function splitReportHtmlByExecution(options) {
|
|
|
764
759
|
exports.ExecutionRecorder = __webpack_exports__.ExecutionRecorder;
|
|
765
760
|
exports.ReportArtifactStore = __webpack_exports__.ReportArtifactStore;
|
|
766
761
|
exports.ReportMergingTool = __webpack_exports__.ReportMergingTool;
|
|
762
|
+
exports.ReportSession = __webpack_exports__.ReportSession;
|
|
767
763
|
exports.TestRunReportAssembler = __webpack_exports__.TestRunReportAssembler;
|
|
768
764
|
exports.calculateTestRunHealth = __webpack_exports__.calculateTestRunHealth;
|
|
769
765
|
exports.classifyTestRunCase = __webpack_exports__.classifyTestRunCase;
|
|
770
766
|
exports.collectDedupedExecutions = __webpack_exports__.collectDedupedExecutions;
|
|
771
767
|
exports.dedupeExecutionsKeepLatest = __webpack_exports__.dedupeExecutionsKeepLatest;
|
|
768
|
+
exports.exportReportArtifact = __webpack_exports__.exportReportArtifact;
|
|
772
769
|
exports.isDirectoryModeReport = __webpack_exports__.isDirectoryModeReport;
|
|
773
770
|
exports.readReportActionDump = __webpack_exports__.readReportActionDump;
|
|
774
771
|
exports.readReportArtifactManifest = __webpack_exports__.readReportArtifactManifest;
|
|
@@ -782,11 +779,13 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
782
779
|
"ExecutionRecorder",
|
|
783
780
|
"ReportArtifactStore",
|
|
784
781
|
"ReportMergingTool",
|
|
782
|
+
"ReportSession",
|
|
785
783
|
"TestRunReportAssembler",
|
|
786
784
|
"calculateTestRunHealth",
|
|
787
785
|
"classifyTestRunCase",
|
|
788
786
|
"collectDedupedExecutions",
|
|
789
787
|
"dedupeExecutionsKeepLatest",
|
|
788
|
+
"exportReportArtifact",
|
|
790
789
|
"isDirectoryModeReport",
|
|
791
790
|
"readReportActionDump",
|
|
792
791
|
"readReportArtifactManifest",
|