@midscene/core 1.17.3-beta-20261029072240.0 → 1.17.3

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.
Files changed (69) hide show
  1. package/dist/es/agent/task-builder.mjs +1 -2
  2. package/dist/es/agent/task-builder.mjs.map +1 -1
  3. package/dist/es/agent/utils.mjs +1 -1
  4. package/dist/es/dump/execution-recorder.mjs +70 -0
  5. package/dist/es/dump/execution-recorder.mjs.map +1 -0
  6. package/dist/es/dump/html-utils.mjs +51 -1
  7. package/dist/es/dump/html-utils.mjs.map +1 -1
  8. package/dist/es/dump/report-artifact-reader.mjs +85 -0
  9. package/dist/es/dump/report-artifact-reader.mjs.map +1 -0
  10. package/dist/es/dump/report-artifact-store.mjs +164 -0
  11. package/dist/es/dump/report-artifact-store.mjs.map +1 -0
  12. package/dist/es/dump/screenshot-store.mjs +40 -15
  13. package/dist/es/dump/screenshot-store.mjs.map +1 -1
  14. package/dist/es/dump/test-report-images.mjs +120 -0
  15. package/dist/es/dump/test-report-images.mjs.map +1 -0
  16. package/dist/es/report-cli.mjs +8 -7
  17. package/dist/es/report-cli.mjs.map +1 -1
  18. package/dist/es/report-generator.mjs +56 -47
  19. package/dist/es/report-generator.mjs.map +1 -1
  20. package/dist/es/report-html-template.mjs +1 -1
  21. package/dist/es/report.mjs +29 -55
  22. package/dist/es/report.mjs.map +1 -1
  23. package/dist/es/test-run-report.mjs.map +1 -1
  24. package/dist/es/utils.mjs +1 -1
  25. package/dist/lib/agent/task-builder.js +1 -2
  26. package/dist/lib/agent/task-builder.js.map +1 -1
  27. package/dist/lib/agent/utils.js +1 -1
  28. package/dist/lib/dump/execution-recorder.js +104 -0
  29. package/dist/lib/dump/execution-recorder.js.map +1 -0
  30. package/dist/lib/dump/html-utils.js +67 -5
  31. package/dist/lib/dump/html-utils.js.map +1 -1
  32. package/dist/lib/dump/report-artifact-reader.js +134 -0
  33. package/dist/lib/dump/report-artifact-reader.js.map +1 -0
  34. package/dist/lib/dump/report-artifact-store.js +204 -0
  35. package/dist/lib/dump/report-artifact-store.js.map +1 -0
  36. package/dist/lib/dump/screenshot-store.js +42 -14
  37. package/dist/lib/dump/screenshot-store.js.map +1 -1
  38. package/dist/lib/dump/test-report-images.js +154 -0
  39. package/dist/lib/dump/test-report-images.js.map +1 -0
  40. package/dist/lib/report-cli.js +8 -7
  41. package/dist/lib/report-cli.js.map +1 -1
  42. package/dist/lib/report-generator.js +54 -45
  43. package/dist/lib/report-generator.js.map +1 -1
  44. package/dist/lib/report-html-template.js +1 -1
  45. package/dist/lib/report.js +54 -56
  46. package/dist/lib/report.js.map +1 -1
  47. package/dist/lib/test-run-report.js.map +1 -1
  48. package/dist/lib/utils.js +1 -1
  49. package/dist/types/agent/task-builder.d.ts.map +1 -1
  50. package/dist/types/dump/execution-recorder.d.ts +23 -0
  51. package/dist/types/dump/execution-recorder.d.ts.map +1 -0
  52. package/dist/types/dump/html-utils.d.ts +9 -0
  53. package/dist/types/dump/html-utils.d.ts.map +1 -1
  54. package/dist/types/dump/report-artifact-reader.d.ts +19 -0
  55. package/dist/types/dump/report-artifact-reader.d.ts.map +1 -0
  56. package/dist/types/dump/report-artifact-store.d.ts +22 -0
  57. package/dist/types/dump/report-artifact-store.d.ts.map +1 -0
  58. package/dist/types/dump/screenshot-store.d.ts +6 -0
  59. package/dist/types/dump/screenshot-store.d.ts.map +1 -1
  60. package/dist/types/dump/test-report-images.d.ts +14 -0
  61. package/dist/types/dump/test-report-images.d.ts.map +1 -0
  62. package/dist/types/report-cli.d.ts.map +1 -1
  63. package/dist/types/report-generator.d.ts +4 -3
  64. package/dist/types/report-generator.d.ts.map +1 -1
  65. package/dist/types/report.d.ts +3 -0
  66. package/dist/types/report.d.ts.map +1 -1
  67. package/dist/types/test-run-report.d.ts +2 -0
  68. package/dist/types/test-run-report.d.ts.map +1 -1
  69. package/package.json +2 -2
@@ -35,8 +35,11 @@ const common_namespaceObject = require("@midscene/shared/common");
35
35
  const env_namespaceObject = require("@midscene/shared/env");
36
36
  const logger_namespaceObject = require("@midscene/shared/logger");
37
37
  const utils_namespaceObject = require("@midscene/shared/utils");
38
+ const execution_recorder_js_namespaceObject = require("./dump/execution-recorder.js");
38
39
  const html_utils_js_namespaceObject = require("./dump/html-utils.js");
39
40
  const image_reference_js_namespaceObject = require("./dump/image-reference.js");
41
+ const report_artifact_reader_js_namespaceObject = require("./dump/report-artifact-reader.js");
42
+ const report_artifact_store_js_namespaceObject = require("./dump/report-artifact-store.js");
40
43
  const report_dump_compactor_js_namespaceObject = require("./dump/report-dump-compactor.js");
41
44
  const screenshot_store_js_namespaceObject = require("./dump/screenshot-store.js");
42
45
  const agent_report_js_namespaceObject = require("./test-runner/reporting/agent-report.js");
@@ -87,7 +90,7 @@ class ReportGenerator {
87
90
  this.assertOpen();
88
91
  this.lastExecution = execution;
89
92
  this.lastReportMeta = reportMeta;
90
- this.executionsByKey.set(this.getExecutionCommentKey(execution), execution);
93
+ this.recorder.record(execution, reportMeta);
91
94
  this.mergeReportAttributes(attributes);
92
95
  this.writeQueue = this.writeQueue.then(async ()=>{
93
96
  await this.doWriteExecution(execution, reportMeta);
@@ -108,7 +111,8 @@ class ReportGenerator {
108
111
  this.flush(),
109
112
  ...this.sourcePublications
110
113
  ]);
111
- if (this.initialized) {
114
+ if (this.initialized) if (this.artifactStore) await this.artifactStore.finalize();
115
+ else {
112
116
  await this.appendAgentReportComment();
113
117
  try {
114
118
  await (0, report_dump_compactor_js_namespaceObject.compactReportDumps)(this.reportPath);
@@ -116,7 +120,7 @@ class ReportGenerator {
116
120
  warnReport(`Failed to compact report ${this.reportPath}; keeping the uncompressed report: ${String(error)}`);
117
121
  }
118
122
  }
119
- this.executionsByKey.clear();
123
+ this.recorder.clear();
120
124
  this.lastExecution = void 0;
121
125
  this.lastReportMeta = void 0;
122
126
  this.executionCommentKeyByObject = new WeakMap();
@@ -133,9 +137,7 @@ class ReportGenerator {
133
137
  this.assertOpen();
134
138
  this.writeQueue = this.writeQueue.then(async ()=>{
135
139
  const reportMeta = this.lastReportMeta ?? meta;
136
- const executions = [
137
- ...this.executionsByKey.values()
138
- ];
140
+ const executions = this.recorder.executions;
139
141
  const agentDump = new external_types_js_namespaceObject.ReportActionDump({
140
142
  ...reportMeta,
141
143
  executions
@@ -153,6 +155,23 @@ class ReportGenerator {
153
155
  const bytes = await (0, promises_namespaceObject.readFile)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), ref.path));
154
156
  images.push((0, html_utils_js_namespaceObject.generateImageScriptTag)(ref.id, `data:${ref.mimeType};base64,${bytes.toString('base64')}`));
155
157
  }
158
+ if (this.artifactStore) {
159
+ for (const execution of executions)await this.writeExecution(execution, this.wrapAsReportDump(execution, reportMeta));
160
+ if (!executions.length) {
161
+ await this.artifactStore.writeExecution('empty', sourceDump.serialized, this.getDumpScriptAttributes());
162
+ if (!this.initialized) {
163
+ const marker = (0, html_utils_js_namespaceObject.generateReportArtifactScriptTag)('report.json');
164
+ await (0, promises_namespaceObject.writeFile)(this.reportPath, `${(0, external_utils_js_namespaceObject.getReportTpl)()}${(0, html_utils_js_namespaceObject.getBaseUrlFixScript)()}\n${marker}`);
165
+ this.initialized = true;
166
+ }
167
+ }
168
+ await this.artifactStore.writeRunner(JSON.stringify(dump));
169
+ if (!this.firstWriteDone) {
170
+ this.firstWriteDone = true;
171
+ this.printReportPath();
172
+ }
173
+ return;
174
+ }
156
175
  const renderedDump = 'inline' === this.screenshotMode ? JSON.stringify(JSON.parse(sourceDump.serialized), (_key, value)=>{
157
176
  const ref = (0, image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
158
177
  return ref ? {
@@ -190,30 +209,24 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
190
209
  enableSourceSnapshots() {
191
210
  this.screenshotStore.enableFileCopies();
192
211
  }
193
- async serializeSourceDump(frozenDump, screenshots) {
212
+ async serializeSourceDump(snapshot) {
194
213
  this.enableSourceSnapshots();
195
- const executions = frozenDump?.executions ?? [
196
- ...this.executionsByKey.values()
197
- ];
198
- const references = new Map();
199
- for (const screenshot of screenshots ?? executions.flatMap((execution)=>execution.collectScreenshots()))await this.screenshotStore.persist(screenshot);
200
- for (const execution of executions)for (const [url, ref] of (await this.persistReferenceImages(execution)))references.set(url, ref);
201
- const dump = frozenDump ?? new external_types_js_namespaceObject.ReportActionDump({
202
- ...this.lastReportMeta ?? {
203
- sdkVersion: '',
204
- groupName: 'YAML execution',
205
- modelBriefs: []
206
- },
207
- executions
214
+ const captured = snapshot ?? this.recorder.capture(void 0, this.lastReportMeta ?? {
215
+ sdkVersion: '',
216
+ groupName: 'YAML execution',
217
+ modelBriefs: []
208
218
  });
219
+ for (const screenshot of captured.screenshots)await this.screenshotStore.persist(screenshot);
220
+ const references = new Map();
221
+ for (const url of captured.referenceImageUrls)references.set(url, await this.screenshotStore.persistReferenceImage(url));
209
222
  const images = new Map();
210
- const serialized = JSON.stringify(JSON.parse(dump.serializeWithReferenceImages(references)), (_key, value)=>{
223
+ const serialized = JSON.stringify(JSON.parse(captured.dump.serializeWithReferenceImages(references)), (_key, value)=>{
211
224
  const ref = (0, image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
212
225
  if (!ref) return value;
213
226
  const stored = {
214
227
  ...ref,
215
228
  storage: 'file',
216
- path: `./screenshots/${ref.id}.${(0, image_reference_js_namespaceObject.imageRefFileExtension)(ref)}`
229
+ path: 'file' === ref.storage ? ref.path : this.screenshotStore.getFilePath(ref.id)
217
230
  };
218
231
  images.set(ref.id, stored);
219
232
  return stored;
@@ -226,22 +239,13 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
226
239
  async createSourceSnapshot(scopeId, executionIds) {
227
240
  this.assertOpen();
228
241
  if (!scopeId || (0, external_node_path_namespaceObject.basename)(scopeId) !== scopeId) throw new Error('Invalid report scope ID');
229
- const capturedAt = new Date().toISOString();
230
- const selectedIds = executionIds ? new Set(executionIds) : void 0;
231
- const executions = [
232
- ...this.executionsByKey.values()
233
- ].filter((execution)=>!selectedIds || execution.id && selectedIds.has(execution.id));
234
- const screenshots = executions.flatMap((execution)=>execution.collectScreenshots());
235
- const frozen = external_types_js_namespaceObject.ReportActionDump.fromSerializedString(new external_types_js_namespaceObject.ReportActionDump({
236
- ...this.lastReportMeta ?? {
237
- sdkVersion: '',
238
- groupName: 'YAML execution',
239
- modelBriefs: []
240
- },
241
- executions
242
- }).serialize());
242
+ const snapshot = this.recorder.capture(executionIds, this.lastReportMeta ?? {
243
+ sdkVersion: '',
244
+ groupName: 'YAML execution',
245
+ modelBriefs: []
246
+ });
243
247
  const publication = (async ()=>{
244
- const { serialized } = await this.serializeSourceDump(frozen, screenshots);
248
+ const { serialized } = await this.serializeSourceDump(snapshot);
245
249
  const dumpPath = `${this.reportPath}.${scopeId}.${(0, utils_namespaceObject.uuid)()}.json`;
246
250
  (0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(dumpPath), {
247
251
  recursive: true
@@ -254,7 +258,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
254
258
  dumpPath,
255
259
  collection: {
256
260
  status: 'complete',
257
- capturedAt
261
+ capturedAt: snapshot.capturedAt
258
262
  }
259
263
  };
260
264
  })();
@@ -274,7 +278,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
274
278
  async doWriteExecution(execution, reportMeta) {
275
279
  const singleDump = this.wrapAsReportDump(execution, reportMeta);
276
280
  const referenceImageRefs = await this.writeExecution(execution, singleDump);
277
- if (this.shouldPersistExecutionDump) await this.persistExecutionDumpToFile(execution, singleDump, referenceImageRefs);
281
+ if (this.shouldPersistExecutionDump && !this.artifactStore) await this.persistExecutionDumpToFile(execution, singleDump, referenceImageRefs);
278
282
  if (!this.firstWriteDone) {
279
283
  this.firstWriteDone = true;
280
284
  this.printReportPath();
@@ -286,6 +290,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
286
290
  }
287
291
  hydrateStateFromExistingReport() {
288
292
  if (!(0, external_node_fs_namespaceObject.existsSync)(this.reportPath)) return;
293
+ if (this.artifactStore && !(0, report_artifact_reader_js_namespaceObject.readReportArtifactManifest)(this.reportPath)) throw new Error('Cannot reuse an incompatible directory report. Choose a new reportFileName or regenerate the report.');
289
294
  this.initialized = true;
290
295
  if (!this.shouldPersistExecutionDump) return;
291
296
  if (!(0, external_node_fs_namespaceObject.existsSync)(this.executionDumpDir)) return;
@@ -318,13 +323,15 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
318
323
  });
319
324
  if (!this.initialized) {
320
325
  const baseUrlFix = 'directory' === this.screenshotMode ? (0, html_utils_js_namespaceObject.getBaseUrlFixScript)() : '';
321
- await (0, promises_namespaceObject.writeFile)(this.reportPath, `${(0, external_utils_js_namespaceObject.getReportTpl)()}${baseUrlFix}`);
326
+ const marker = this.artifactStore ? `\n${(0, html_utils_js_namespaceObject.generateReportArtifactScriptTag)('report.json')}` : '';
327
+ await (0, promises_namespaceObject.writeFile)(this.reportPath, `${(0, external_utils_js_namespaceObject.getReportTpl)()}${baseUrlFix}${marker}`);
322
328
  this.initialized = true;
323
329
  }
324
330
  for (const screenshot of execution.collectScreenshots())await this.screenshotStore.persist(screenshot);
325
331
  const referenceImageRefs = await this.persistReferenceImages(execution);
326
332
  const serialized = singleDump.serializeWithReferenceImages(referenceImageRefs);
327
- await (0, promises_namespaceObject.appendFile)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateDumpScriptTag)(serialized, this.getDumpScriptAttributes())}`);
333
+ if (this.artifactStore) await this.artifactStore.writeExecution(this.getExecutionCommentKey(execution), serialized, this.getDumpScriptAttributes());
334
+ else await (0, promises_namespaceObject.appendFile)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateDumpScriptTag)(serialized, this.getDumpScriptAttributes())}`);
328
335
  return referenceImageRefs;
329
336
  }
330
337
  async persistReferenceImages(execution) {
@@ -336,14 +343,14 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
336
343
  return refs;
337
344
  }
338
345
  async appendAgentReportComment() {
339
- if (this.agentCommentWritten || !this.lastReportMeta || 0 === this.executionsByKey.size) return;
346
+ if (this.agentCommentWritten || !this.lastReportMeta || 0 === this.recorder.executions.length) return;
340
347
  const reportDump = new external_types_js_namespaceObject.ReportActionDump({
341
348
  sdkVersion: this.lastReportMeta.sdkVersion,
342
349
  groupName: this.lastReportMeta.groupName,
343
350
  groupDescription: this.lastReportMeta.groupDescription,
344
351
  modelBriefs: this.lastReportMeta.modelBriefs,
345
352
  deviceType: this.lastReportMeta.deviceType,
346
- executions: Array.from(this.executionsByKey.values())
353
+ executions: this.recorder.executions
347
354
  });
348
355
  await (0, promises_namespaceObject.appendFile)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateAgentReportComment)(reportDump)}`);
349
356
  this.agentCommentWritten = true;
@@ -383,7 +390,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
383
390
  return ref ? {
384
391
  ...ref,
385
392
  storage: 'file',
386
- path: `../../screenshots/${ref.id}.${(0, image_reference_js_namespaceObject.imageRefFileExtension)(ref)}`
393
+ path: `../../${this.screenshotStore.getFilePath(ref.id).replace(/^\.\//, '')}`
387
394
  } : value;
388
395
  }, 2);
389
396
  await (0, promises_namespaceObject.writeFile)(filePath, serialized, 'utf-8');
@@ -401,7 +408,8 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
401
408
  _define_property(this, "initialized", false);
402
409
  _define_property(this, "lastExecution", void 0);
403
410
  _define_property(this, "lastReportMeta", void 0);
404
- _define_property(this, "executionsByKey", new Map());
411
+ _define_property(this, "recorder", new execution_recorder_js_namespaceObject.ExecutionRecorder());
412
+ _define_property(this, "artifactStore", void 0);
405
413
  _define_property(this, "executionCommentKeyByObject", new WeakMap());
406
414
  _define_property(this, "executionCommentKeyIndex", 0);
407
415
  _define_property(this, "reportAttributes", {});
@@ -414,6 +422,7 @@ ${(0, html_utils_js_namespaceObject.generateAgentReportComment)(agentDump)}`;
414
422
  this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;
415
423
  this.autoPrint = options.autoPrint ?? true;
416
424
  this.reportStreamId = (0, utils_namespaceObject.uuid)();
425
+ if ('directory' === this.screenshotMode) this.artifactStore = new report_artifact_store_js_namespaceObject.ReportArtifactStore((0, external_node_path_namespaceObject.dirname)(this.reportPath), this.reportStreamId, 'agent', options.reuseExistingReport, (0, external_node_path_namespaceObject.basename)(this.reportPath));
417
426
  this.screenshotStore = new screenshot_store_js_namespaceObject.ReportImageStore({
418
427
  mode: 'inline' === this.screenshotMode ? 'inline' : 'directory',
419
428
  reportPath: this.reportPath,
@@ -1 +1 @@
1
- {"version":3,"file":"report-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-generator.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/*\n * PERF INVARIANT — DO NOT reintroduce sync fs APIs (writeFileSync /\n * appendFileSync) in this file's write paths. `ReportGenerator` runs on\n * the Electron main event loop during agent execution, and a single\n * progress tick appends a multi-MB ExecutionDump payload. Sync I/O here\n * blocked the loop for 20+ seconds per run, freezing IPC, scrcpy and\n * every renderer round-trip. Always use `fs/promises`. See commit\n * 6a25e05c and `report-generator-async-contract.test.ts`.\n */\nimport { existsSync, mkdirSync, readdirSync } from 'node:fs';\nimport {\n appendFile as appendFileAsync,\n readFile as readFileAsync,\n rename as renameAsync,\n unlink as unlinkAsync,\n writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug, logReport } from '@midscene/shared/logger';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport {\n DATA_SCREENSHOT_MODE_ATTR,\n generateAgentReportComment,\n generateDumpScriptTag,\n generateImageScriptTag,\n generateTestRunReportScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport {\n imageRefFileExtension,\n normalizeStoredImageRef,\n} from './dump/image-reference';\nimport { compactReportDumps } from './dump/report-dump-compactor';\nimport { type ImageUrlRef, ReportImageStore } from './dump/screenshot-store';\nimport type { WorkflowReportSource } from './test-runner/engine/types';\nimport { buildAgentTestRunReportDump } from './test-runner/reporting/agent-report';\nimport type { RunReportInput } from './test-runner/reporting/types';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n type ScreenshotMode,\n} from './types';\nimport { getReportTpl } from './utils';\n\nconst warnReport = getDebug('report-generator', { console: true });\nconst maxReportFilenameBytes = 255;\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Each call appends a new dump script tag. The frontend deduplicates\n * executions with the same id/name, keeping only the last one.\n *\n * @param execution Current execution's full data\n * @param reportMeta Report-level metadata (groupName, sdkVersion, etc.)\n */\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void;\n\n /**\n * @deprecated Use onExecutionUpdate instead. Kept for backward compatibility.\n */\n onDumpUpdate?(dump: ReportActionDump): void;\n\n /**\n * Wait for all queued write operations to complete.\n */\n flush(): Promise<void>;\n enableSourceSnapshots?(): void;\n createSourceSnapshot?(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource | undefined>;\n\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n /** Publish a single root Runner snapshot into this Agent's existing report. */\n writeRunnerReport?(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string | undefined>;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => undefined,\n writeRunnerReport: async () => undefined,\n};\n\nexport function assertReportGenerationOptions(opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n}): void {\n if (opts.generateReport === false && opts.persistExecutionDump === true) {\n throw new Error(\n 'persistExecutionDump cannot be true when generateReport is false',\n );\n }\n}\n\nexport class ReportGenerator implements IReportGenerator {\n private reportPath: string;\n private screenshotMode: ScreenshotMode;\n private shouldPersistExecutionDump: boolean;\n private autoPrint: boolean;\n private firstWriteDone = false;\n private executionLogIndex = 0;\n private executionLogFileIndexByExecutionKey = new Map<string, number>();\n\n // Unique identifier for this report stream — used as data-group-id\n private readonly reportStreamId: string;\n\n // Tracks screenshots already written to disk (by id) to avoid duplicates\n private screenshotStore: ReportImageStore;\n private initialized = false;\n\n // Tracks the last execution + groupMeta for re-writing on finalize\n private lastExecution?: ExecutionDump;\n private lastReportMeta?: ReportMeta;\n private executionsByKey = new Map<string, ExecutionDump>();\n private executionCommentKeyByObject = new WeakMap<ExecutionDump, string>();\n private executionCommentKeyIndex = 0;\n private reportAttributes: Record<string, string> = {};\n private agentCommentWritten = false;\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private finalization?: Promise<string | undefined>;\n private sourcePublications = new Set<Promise<unknown>>();\n\n constructor(options: {\n reportPath: string;\n screenshotMode: ScreenshotMode;\n persistExecutionDump?: boolean;\n autoPrint?: boolean;\n reuseExistingReport?: boolean;\n }) {\n this.reportPath = options.reportPath;\n this.screenshotMode = options.screenshotMode;\n this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;\n this.autoPrint = options.autoPrint ?? true;\n this.reportStreamId = uuid();\n this.screenshotStore = new ReportImageStore({\n mode: this.screenshotMode === 'inline' ? 'inline' : 'directory',\n reportPath: this.reportPath,\n screenshotsDir: join(dirname(this.reportPath), 'screenshots'),\n writeInlineImage: async (id, base64) => {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateImageScriptTag(id, base64)}`,\n );\n },\n alsoWriteFileCopy: this.shouldPersistExecutionDump,\n reuseExistingReport: options.reuseExistingReport,\n });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n }\n\n static create(\n reportFileName: string,\n opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n autoPrintReportMsg?: boolean;\n reuseExistingReport?: boolean;\n },\n ): IReportGenerator {\n assertReportGenerationOptions(opts);\n validateReportFileName(reportFileName, opts.outputFormat);\n if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n\n const reportRootDir = getMidsceneRunSubDir('report');\n const outputDir = join(reportRootDir, reportFileName);\n const reportPath =\n opts.outputFormat === 'html-and-external-assets'\n ? join(outputDir, 'index.html')\n : join(reportRootDir, ensureHtmlFileName(reportFileName));\n return new ReportGenerator({\n reportPath,\n screenshotMode:\n opts.outputFormat === 'html-and-external-assets'\n ? 'directory'\n : 'inline',\n persistExecutionDump: opts.persistExecutionDump,\n autoPrint: opts.autoPrintReportMsg,\n reuseExistingReport: opts.reuseExistingReport,\n });\n }\n\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void {\n this.assertOpen();\n this.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.executionsByKey.set(this.getExecutionCommentKey(execution), execution);\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n await this.doWriteExecution(execution, reportMeta);\n });\n }\n\n async flush(): Promise<void> {\n await this.writeQueue;\n }\n\n async finalize(): Promise<string | undefined> {\n if (!this.finalization) {\n // Enqueue the final state before sealing the generator to new writes.\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n this.finalization = this.finishPublication();\n }\n return this.finalization;\n }\n\n private async finishPublication(): Promise<string | undefined> {\n // Snapshots freeze independently of the HTML queue, but both must be on\n // disk before their backing executions and diagnostic data are released.\n await Promise.all([this.flush(), ...this.sourcePublications]);\n if (this.initialized) {\n await this.appendAgentReportComment();\n try {\n await compactReportDumps(this.reportPath);\n } catch (error) {\n warnReport(\n `Failed to compact report ${this.reportPath}; keeping the uncompressed report: ${String(error)}`,\n );\n }\n }\n this.executionsByKey.clear();\n this.lastExecution = undefined;\n this.lastReportMeta = undefined;\n this.executionCommentKeyByObject = new WeakMap();\n this.executionLogFileIndexByExecutionKey.clear();\n return this.initialized ? this.reportPath : undefined;\n }\n\n private assertOpen(): void {\n if (this.finalization) throw new Error('The report has been finalized.');\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n async writeRunnerReport(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string> {\n this.assertOpen();\n this.writeQueue = this.writeQueue.then(async () => {\n // This runs at YAML invocation completion, never on progress ticks. Keep\n // all file I/O asynchronous and publish atomically for an open viewer.\n const reportMeta = this.lastReportMeta ?? meta;\n const executions = [...this.executionsByKey.values()];\n const agentDump = new ReportActionDump({ ...reportMeta, executions });\n const reportId =\n this.reportAttributes['data-report-id'] ??\n this.reportAttributes['data-group-id'] ??\n this.reportStreamId;\n const dump = buildAgentTestRunReportDump(input, agentDump, {\n reportId,\n scopeId,\n sourcePath: this.reportPath,\n });\n for (const diagnostic of dump.diagnostics ?? [])\n warnReport(diagnostic.message);\n const sourceDump = await this.serializeSourceDump();\n const images: string[] = [];\n if (this.screenshotMode === 'inline') {\n for (const ref of sourceDump.images.values()) {\n const bytes = await readFileAsync(\n join(dirname(this.reportPath), ref.path!),\n );\n images.push(\n generateImageScriptTag(\n ref.id,\n `data:${ref.mimeType};base64,${bytes.toString('base64')}`,\n ),\n );\n }\n }\n // Rebuild from the owned dump and image index, never parse this HTML back.\n const renderedDump =\n this.screenshotMode === 'inline'\n ? JSON.stringify(JSON.parse(sourceDump.serialized), (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? { ...ref, storage: 'inline', path: undefined }\n : value;\n })\n : sourceDump.serialized;\n const contents = `${getReportTpl()}${this.screenshotMode === 'directory' ? getBaseUrlFixScript() : ''}\n${generateDumpScriptTag(renderedDump, this.getDumpScriptAttributes())}\n${images.join('\\n')}\n${generateTestRunReportScriptTag(dump)}\n${generateAgentReportComment(agentDump)}`;\n mkdirSync(dirname(this.reportPath), { recursive: true });\n const temporaryPath = `${this.reportPath}.runner-${uuid()}.tmp`;\n try {\n await writeFileAsync(temporaryPath, contents);\n await renameAsync(temporaryPath, this.reportPath);\n } finally {\n await unlinkAsync(temporaryPath).catch((error) => {\n if (error.code !== 'ENOENT') throw error;\n });\n }\n this.initialized = true;\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n });\n await this.flush();\n return this.reportPath;\n }\n\n enableSourceSnapshots(): void {\n this.screenshotStore.enableFileCopies();\n }\n\n private async serializeSourceDump(\n frozenDump?: ReportActionDump,\n screenshots?: ReturnType<ExecutionDump['collectScreenshots']>,\n ) {\n this.enableSourceSnapshots();\n const executions = frozenDump?.executions ?? [\n ...this.executionsByKey.values(),\n ];\n const references = new Map<string, ImageUrlRef>();\n for (const screenshot of screenshots ??\n executions.flatMap((execution) => execution.collectScreenshots()))\n await this.screenshotStore.persist(screenshot);\n for (const execution of executions) {\n for (const [url, ref] of await this.persistReferenceImages(execution))\n references.set(url, ref);\n }\n const dump =\n frozenDump ??\n new ReportActionDump({\n ...(this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n }),\n executions,\n });\n const images = new Map<\n string,\n ReturnType<typeof normalizeStoredImageRef> & {}\n >();\n const serialized = JSON.stringify(\n JSON.parse(dump.serializeWithReferenceImages(references)),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (!ref) return value;\n const stored = {\n ...ref,\n storage: 'file' as const,\n path: `./screenshots/${ref.id}.${imageRefFileExtension(ref)}`,\n };\n images.set(ref.id, stored);\n return stored;\n },\n );\n return { serialized, images };\n }\n\n async createSourceSnapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource & { dumpPath: string }> {\n this.assertOpen();\n // Scope IDs originate in the kernel; never allow a filename to escape the report directory.\n if (!scopeId || basename(scopeId) !== scopeId)\n throw new Error('Invalid report scope ID');\n // Freeze before the first await. HTML writes and the live action can still\n // be pending; neither is a prerequisite for publishing this cutoff.\n const capturedAt = new Date().toISOString();\n const selectedIds = executionIds ? new Set(executionIds) : undefined;\n const executions = [...this.executionsByKey.values()].filter(\n (execution) =>\n !selectedIds || (execution.id && selectedIds.has(execution.id)),\n );\n const screenshots = executions.flatMap((execution) =>\n execution.collectScreenshots(),\n );\n const frozen = ReportActionDump.fromSerializedString(\n new ReportActionDump({\n ...(this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n }),\n executions,\n }).serialize(),\n );\n const publication = (async () => {\n const { serialized } = await this.serializeSourceDump(\n frozen,\n screenshots,\n );\n const dumpPath = `${this.reportPath}.${scopeId}.${uuid()}.json`;\n mkdirSync(dirname(dumpPath), { recursive: true });\n await writeFileAsync(dumpPath, serialized, { flag: 'wx' });\n return {\n sourcePath: this.reportPath,\n dumpPath,\n collection: { status: 'complete' as const, capturedAt },\n };\n })();\n this.sourcePublications.add(publication);\n try {\n return await publication;\n } finally {\n this.sourcePublications.delete(publication);\n }\n }\n\n private printReportPath(): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logReport(\n `Midscene - report file updated: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logReport(`Midscene - report file updated: ${this.reportPath}`);\n }\n }\n\n private async doWriteExecution(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): Promise<void> {\n const singleDump = this.wrapAsReportDump(execution, reportMeta);\n\n const referenceImageRefs = await this.writeExecution(execution, singleDump);\n\n if (this.shouldPersistExecutionDump) {\n await this.persistExecutionDumpToFile(\n execution,\n singleDump,\n referenceImageRefs,\n );\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n }\n\n private mergeReportAttributes(attributes?: ReportAttributes): void {\n if (!attributes) {\n return;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) {\n continue;\n }\n this.reportAttributes[key] = String(value);\n }\n }\n\n private hydrateStateFromExistingReport(): void {\n if (!existsSync(this.reportPath)) {\n return;\n }\n\n // Reuse existing report file and append new updates instead of rewriting.\n this.initialized = true;\n\n if (!this.shouldPersistExecutionDump) {\n return;\n }\n\n if (!existsSync(this.executionDumpDir)) return;\n const existingExecutionIndices = readdirSync(this.executionDumpDir)\n .map((name) => /^(\\d+)\\.execution\\.json$/.exec(name)?.[1])\n .filter((index): index is string => Boolean(index))\n .map((index) => Number.parseInt(index, 10))\n .filter((index) => Number.isFinite(index));\n\n if (existingExecutionIndices.length > 0) {\n this.executionLogIndex = Math.max(...existingExecutionIndices);\n }\n }\n\n private getDumpScriptAttributes(): Record<string, string> {\n return {\n 'data-group-id': this.reportStreamId,\n // Self-describe how this report file stores screenshots so consumers\n // (merge/delete) never have to guess the mode from the filesystem.\n [DATA_SCREENSHOT_MODE_ATTR]: this.screenshotMode,\n ...this.reportAttributes,\n };\n }\n\n /**\n * Wrap an ExecutionDump + ReportMeta into a single-execution ReportActionDump.\n */\n private wrapAsReportDump(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): ReportActionDump {\n return new ReportActionDump({\n sdkVersion: reportMeta.sdkVersion,\n groupName: reportMeta.groupName,\n groupDescription: reportMeta.groupDescription,\n modelBriefs: reportMeta.modelBriefs,\n deviceType: reportMeta.deviceType,\n executions: [execution],\n });\n }\n\n /**\n * Append assets and a dump tag without duplicating mode-specific workflows.\n * The frontend deduplicates executions with the same id/name (keeps last).\n * Duplicate dump JSON is acceptable; only screenshots are deduplicated.\n *\n * All writes go through `fs/promises` so they run on libuv's thread pool\n * rather than blocking the Node event loop. A long agent run previously\n * appended multi-MB dumps (screenshots + serialized tasks) per progress\n * tick on the main thread, starving IPC and UI for >10s per stall.\n */\n private async writeExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Initialize: write HTML template once\n if (!this.initialized) {\n const baseUrlFix =\n this.screenshotMode === 'directory' ? getBaseUrlFixScript() : '';\n await writeFileAsync(this.reportPath, `${getReportTpl()}${baseUrlFix}`);\n this.initialized = true;\n }\n\n // Append new screenshots (skip already-written ones)\n for (const screenshot of execution.collectScreenshots()) {\n await this.screenshotStore.persist(screenshot);\n }\n const referenceImageRefs = await this.persistReferenceImages(execution);\n\n // Append dump tag (always — frontend keeps only last per execution id)\n const serialized =\n singleDump.serializeWithReferenceImages(referenceImageRefs);\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n return referenceImageRefs;\n }\n\n private async persistReferenceImages(\n execution: ExecutionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const refs = new Map<string, ImageUrlRef>();\n for (const imageUrl of execution.getReferenceImageUrls()) {\n const ref = await this.screenshotStore.persistReferenceImage(imageUrl);\n refs.set(imageUrl, ref);\n }\n return refs;\n }\n\n private async appendAgentReportComment(): Promise<void> {\n if (\n this.agentCommentWritten ||\n !this.lastReportMeta ||\n this.executionsByKey.size === 0\n ) {\n return;\n }\n\n const reportDump = new ReportActionDump({\n sdkVersion: this.lastReportMeta.sdkVersion,\n groupName: this.lastReportMeta.groupName,\n groupDescription: this.lastReportMeta.groupDescription,\n modelBriefs: this.lastReportMeta.modelBriefs,\n deviceType: this.lastReportMeta.deviceType,\n executions: Array.from(this.executionsByKey.values()),\n });\n await appendFileAsync(\n this.reportPath,\n `\\n${generateAgentReportComment(reportDump)}`,\n );\n this.agentCommentWritten = true;\n }\n\n private getExecutionLogKey(execution: ExecutionDump): string {\n if (!execution.id) {\n throw new Error(\n 'ReportGenerator: execution.id is required for persisting execution dumps',\n );\n }\n return `id:${execution.id}`;\n }\n\n private getExecutionCommentKey(execution: ExecutionDump): string {\n if (execution.id) {\n return `id:${execution.id}`;\n }\n\n const existingKey = this.executionCommentKeyByObject.get(execution);\n if (existingKey) {\n return existingKey;\n }\n\n const key = `no-id:${this.executionCommentKeyIndex++}`;\n this.executionCommentKeyByObject.set(execution, key);\n return key;\n }\n\n private get executionDumpDir(): string {\n // Inline HTML files share their parent directory. Each needs its own\n // numbered JSON namespace; external-asset reports already have one.\n return this.screenshotMode === 'inline'\n ? join(\n dirname(this.reportPath),\n '.execution-dumps',\n basename(this.reportPath),\n )\n : dirname(this.reportPath);\n }\n\n private async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n referenceImageRefs: ReadonlyMap<string, ImageUrlRef>,\n ): Promise<void> {\n const dir = this.executionDumpDir;\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const executionLogKey = this.getExecutionLogKey(execution);\n let fileIndex =\n this.executionLogFileIndexByExecutionKey.get(executionLogKey);\n if (!fileIndex) {\n this.executionLogIndex += 1;\n fileIndex = this.executionLogIndex;\n this.executionLogFileIndexByExecutionKey.set(executionLogKey, fileIndex);\n }\n\n const fileName = `${fileIndex}.execution.json`;\n const filePath = join(dir, fileName);\n let serialized = singleDump.serializeWithReferenceImages(\n referenceImageRefs,\n 2,\n );\n if (this.screenshotMode === 'inline') {\n // JSON is two directories below the HTML. Point to the existing file\n // copies so it can be consumed without resolving inline HTML assets.\n serialized = JSON.stringify(\n JSON.parse(serialized),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? {\n ...ref,\n storage: 'file',\n path: `../../screenshots/${ref.id}.${imageRefFileExtension(ref)}`,\n }\n : value;\n },\n 2,\n );\n }\n await writeFileAsync(filePath, serialized, 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(\n reportFileName: string,\n outputFormat?: 'single-html' | 'html-and-external-assets',\n): void {\n if (!reportFileName?.trim()) {\n throw new Error('reportFileName must be a non-empty string');\n }\n\n if (/[\\\\/]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName must not contain path separators (`/` or `\\\\\\\\`)',\n );\n }\n\n if (/[:*?\"<>|]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName contains illegal filename characters: : * ? \" < > |',\n );\n }\n\n const filenameComponent =\n outputFormat === 'html-and-external-assets'\n ? reportFileName\n : ensureHtmlFileName(reportFileName);\n const filenameBytes = new TextEncoder().encode(filenameComponent).byteLength;\n if (filenameBytes > maxReportFilenameBytes) {\n throw new Error(\n `reportFileName produces a filename component of ${filenameBytes} UTF-8 bytes; maximum is ${maxReportFilenameBytes}`,\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","warnReport","getDebug","maxReportFilenameBytes","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","validateReportFileName","ifInBrowser","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","Promise","compactReportDumps","error","String","WeakMap","input","scopeId","meta","executions","agentDump","ReportActionDump","reportId","dump","buildAgentTestRunReportDump","diagnostic","sourceDump","images","ref","bytes","readFileAsync","dirname","generateImageScriptTag","renderedDump","JSON","_key","value","normalizeStoredImageRef","contents","getReportTpl","getBaseUrlFixScript","generateDumpScriptTag","generateTestRunReportScriptTag","generateAgentReportComment","mkdirSync","temporaryPath","uuid","writeFileAsync","renameAsync","unlinkAsync","frozenDump","screenshots","references","Map","screenshot","url","serialized","stored","imageRefFileExtension","executionIds","basename","capturedAt","Date","selectedIds","Set","frozen","publication","dumpPath","globalConfigManager","MIDSCENE_REPORT_QUIET","logReport","singleDump","referenceImageRefs","existsSync","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","DATA_SCREENSHOT_MODE_ATTR","dir","baseUrlFix","appendFileAsync","refs","imageUrl","reportDump","Array","existingKey","executionLogKey","fileIndex","fileName","filePath","options","ReportImageStore","id","base64","outputFormat","filenameComponent","filenameBytes","TextEncoder"],"mappings":"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"}
1
+ {"version":3,"file":"report-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/report-generator.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/*\n * PERF INVARIANT — DO NOT reintroduce sync fs APIs (writeFileSync /\n * appendFileSync) in this file's write paths. `ReportGenerator` runs on\n * the Electron main event loop during agent execution, and a single\n * progress tick appends a multi-MB ExecutionDump payload. Sync I/O here\n * blocked the loop for 20+ seconds per run, freezing IPC, scrcpy and\n * every renderer round-trip. Always use `fs/promises`. See commit\n * 6a25e05c and `report-generator-async-contract.test.ts`.\n */\nimport { existsSync, mkdirSync, readdirSync } from 'node:fs';\nimport {\n appendFile as appendFileAsync,\n readFile as readFileAsync,\n rename as renameAsync,\n unlink as unlinkAsync,\n writeFile as writeFileAsync,\n} from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_REPORT_QUIET,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug, logReport } from '@midscene/shared/logger';\nimport { ifInBrowser, uuid } from '@midscene/shared/utils';\nimport {\n type ExecutionRecordSnapshot,\n ExecutionRecorder,\n} from './dump/execution-recorder';\nimport {\n DATA_SCREENSHOT_MODE_ATTR,\n generateAgentReportComment,\n generateDumpScriptTag,\n generateImageScriptTag,\n generateReportArtifactScriptTag,\n generateTestRunReportScriptTag,\n getBaseUrlFixScript,\n} from './dump/html-utils';\nimport { normalizeStoredImageRef } from './dump/image-reference';\nimport { readReportArtifactManifest } from './dump/report-artifact-reader';\nimport { ReportArtifactStore } from './dump/report-artifact-store';\nimport { compactReportDumps } from './dump/report-dump-compactor';\nimport { type ImageUrlRef, ReportImageStore } from './dump/screenshot-store';\nimport type { WorkflowReportSource } from './test-runner/engine/types';\nimport { buildAgentTestRunReportDump } from './test-runner/reporting/agent-report';\nimport type { RunReportInput } from './test-runner/reporting/types';\nimport {\n type ExecutionDump,\n ReportActionDump,\n type ReportAttributes,\n type ReportMeta,\n type ScreenshotMode,\n} from './types';\nimport { getReportTpl } from './utils';\n\nconst warnReport = getDebug('report-generator', { console: true });\nconst maxReportFilenameBytes = 255;\n\nexport interface IReportGenerator {\n /**\n * Write or update a single execution.\n * Inline reports append dump tags; directory reports replace the execution's\n * data file. Both retain the latest state for each stable execution ID.\n *\n * @param execution Current execution's full data\n * @param reportMeta Report-level metadata (groupName, sdkVersion, etc.)\n */\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void;\n\n /**\n * @deprecated Use onExecutionUpdate instead. Kept for backward compatibility.\n */\n onDumpUpdate?(dump: ReportActionDump): void;\n\n /**\n * Wait for all queued write operations to complete.\n */\n flush(): Promise<void>;\n enableSourceSnapshots?(): void;\n createSourceSnapshot?(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource | undefined>;\n\n /**\n * Finalize the report. Calls flush() internally.\n */\n finalize(): Promise<string | undefined>;\n\n getReportPath(): string | undefined;\n /** Publish a single root Runner snapshot into this Agent's existing report. */\n writeRunnerReport?(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string | undefined>;\n}\n\nexport const nullReportGenerator: IReportGenerator = {\n onExecutionUpdate: () => {},\n flush: async () => {},\n finalize: async () => undefined,\n getReportPath: () => undefined,\n writeRunnerReport: async () => undefined,\n};\n\nexport function assertReportGenerationOptions(opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n}): void {\n if (opts.generateReport === false && opts.persistExecutionDump === true) {\n throw new Error(\n 'persistExecutionDump cannot be true when generateReport is false',\n );\n }\n}\n\nexport class ReportGenerator implements IReportGenerator {\n private reportPath: string;\n private screenshotMode: ScreenshotMode;\n private shouldPersistExecutionDump: boolean;\n private autoPrint: boolean;\n private firstWriteDone = false;\n private executionLogIndex = 0;\n private executionLogFileIndexByExecutionKey = new Map<string, number>();\n\n // Unique identifier for this report stream — used as data-group-id\n private readonly reportStreamId: string;\n\n // Tracks screenshots already written to disk (by id) to avoid duplicates\n private screenshotStore: ReportImageStore;\n private initialized = false;\n\n // Tracks the last execution + groupMeta for re-writing on finalize\n private lastExecution?: ExecutionDump;\n private lastReportMeta?: ReportMeta;\n private readonly recorder = new ExecutionRecorder();\n private readonly artifactStore?: ReportArtifactStore;\n private executionCommentKeyByObject = new WeakMap<ExecutionDump, string>();\n private executionCommentKeyIndex = 0;\n private reportAttributes: Record<string, string> = {};\n private agentCommentWritten = false;\n\n // write queue for serial execution\n private writeQueue: Promise<void> = Promise.resolve();\n private finalization?: Promise<string | undefined>;\n private sourcePublications = new Set<Promise<unknown>>();\n\n constructor(options: {\n reportPath: string;\n screenshotMode: ScreenshotMode;\n persistExecutionDump?: boolean;\n autoPrint?: boolean;\n reuseExistingReport?: boolean;\n }) {\n this.reportPath = options.reportPath;\n this.screenshotMode = options.screenshotMode;\n this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;\n this.autoPrint = options.autoPrint ?? true;\n this.reportStreamId = uuid();\n if (this.screenshotMode === 'directory') {\n this.artifactStore = new ReportArtifactStore(\n dirname(this.reportPath),\n this.reportStreamId,\n 'agent',\n options.reuseExistingReport,\n basename(this.reportPath),\n );\n }\n this.screenshotStore = new ReportImageStore({\n mode: this.screenshotMode === 'inline' ? 'inline' : 'directory',\n reportPath: this.reportPath,\n screenshotsDir: join(dirname(this.reportPath), 'screenshots'),\n writeInlineImage: async (id, base64) => {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateImageScriptTag(id, base64)}`,\n );\n },\n alsoWriteFileCopy: this.shouldPersistExecutionDump,\n reuseExistingReport: options.reuseExistingReport,\n });\n if (options.reuseExistingReport) {\n this.hydrateStateFromExistingReport();\n }\n }\n\n static create(\n reportFileName: string,\n opts: {\n generateReport?: boolean;\n persistExecutionDump?: boolean;\n outputFormat?: 'single-html' | 'html-and-external-assets';\n autoPrintReportMsg?: boolean;\n reuseExistingReport?: boolean;\n },\n ): IReportGenerator {\n assertReportGenerationOptions(opts);\n validateReportFileName(reportFileName, opts.outputFormat);\n if (opts.generateReport === false) return nullReportGenerator;\n\n // In browser environment, file system is not available\n if (ifInBrowser) return nullReportGenerator;\n\n const reportRootDir = getMidsceneRunSubDir('report');\n const outputDir = join(reportRootDir, reportFileName);\n const reportPath =\n opts.outputFormat === 'html-and-external-assets'\n ? join(outputDir, 'index.html')\n : join(reportRootDir, ensureHtmlFileName(reportFileName));\n return new ReportGenerator({\n reportPath,\n screenshotMode:\n opts.outputFormat === 'html-and-external-assets'\n ? 'directory'\n : 'inline',\n persistExecutionDump: opts.persistExecutionDump,\n autoPrint: opts.autoPrintReportMsg,\n reuseExistingReport: opts.reuseExistingReport,\n });\n }\n\n onExecutionUpdate(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n attributes?: ReportAttributes,\n ): void {\n this.assertOpen();\n this.lastExecution = execution;\n this.lastReportMeta = reportMeta;\n this.recorder.record(execution, reportMeta);\n this.mergeReportAttributes(attributes);\n this.writeQueue = this.writeQueue.then(async () => {\n await this.doWriteExecution(execution, reportMeta);\n });\n }\n\n async flush(): Promise<void> {\n await this.writeQueue;\n }\n\n async finalize(): Promise<string | undefined> {\n if (!this.finalization) {\n // Enqueue the final state before sealing the generator to new writes.\n if (this.lastExecution && this.lastReportMeta) {\n this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);\n }\n this.finalization = this.finishPublication();\n }\n return this.finalization;\n }\n\n private async finishPublication(): Promise<string | undefined> {\n // Snapshots freeze independently of the HTML queue, but both must be on\n // disk before their backing executions and diagnostic data are released.\n await Promise.all([this.flush(), ...this.sourcePublications]);\n if (this.initialized) {\n if (this.artifactStore) {\n await this.artifactStore.finalize();\n } else {\n await this.appendAgentReportComment();\n try {\n await compactReportDumps(this.reportPath);\n } catch (error) {\n warnReport(\n `Failed to compact report ${this.reportPath}; keeping the uncompressed report: ${String(error)}`,\n );\n }\n }\n }\n this.recorder.clear();\n this.lastExecution = undefined;\n this.lastReportMeta = undefined;\n this.executionCommentKeyByObject = new WeakMap();\n this.executionLogFileIndexByExecutionKey.clear();\n return this.initialized ? this.reportPath : undefined;\n }\n\n private assertOpen(): void {\n if (this.finalization) throw new Error('The report has been finalized.');\n }\n\n getReportPath(): string | undefined {\n return this.reportPath;\n }\n\n async writeRunnerReport(\n input: RunReportInput,\n scopeId: string,\n meta: ReportMeta,\n ): Promise<string> {\n this.assertOpen();\n this.writeQueue = this.writeQueue.then(async () => {\n // This runs at YAML invocation completion, never on progress ticks. Keep\n // all file I/O asynchronous and publish atomically for an open viewer.\n const reportMeta = this.lastReportMeta ?? meta;\n const executions = this.recorder.executions;\n const agentDump = new ReportActionDump({ ...reportMeta, executions });\n const reportId =\n this.reportAttributes['data-report-id'] ??\n this.reportAttributes['data-group-id'] ??\n this.reportStreamId;\n const dump = buildAgentTestRunReportDump(input, agentDump, {\n reportId,\n scopeId,\n sourcePath: this.reportPath,\n });\n for (const diagnostic of dump.diagnostics ?? [])\n warnReport(diagnostic.message);\n const sourceDump = await this.serializeSourceDump();\n const images: string[] = [];\n if (this.screenshotMode === 'inline') {\n for (const ref of sourceDump.images.values()) {\n const bytes = await readFileAsync(\n join(dirname(this.reportPath), ref.path!),\n );\n images.push(\n generateImageScriptTag(\n ref.id,\n `data:${ref.mimeType};base64,${bytes.toString('base64')}`,\n ),\n );\n }\n }\n if (this.artifactStore) {\n for (const execution of executions) {\n await this.writeExecution(\n execution,\n this.wrapAsReportDump(execution, reportMeta),\n );\n }\n if (!executions.length) {\n // An empty execution group still carries setup/collection diagnostics.\n await this.artifactStore.writeExecution(\n 'empty',\n sourceDump.serialized,\n this.getDumpScriptAttributes(),\n );\n if (!this.initialized) {\n const marker = generateReportArtifactScriptTag('report.json');\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${getBaseUrlFixScript()}\\n${marker}`,\n );\n this.initialized = true;\n }\n }\n await this.artifactStore.writeRunner(JSON.stringify(dump));\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n return;\n }\n // Rebuild from the owned dump and image index, never parse this HTML back.\n const renderedDump =\n this.screenshotMode === 'inline'\n ? JSON.stringify(JSON.parse(sourceDump.serialized), (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? { ...ref, storage: 'inline', path: undefined }\n : value;\n })\n : sourceDump.serialized;\n const contents = `${getReportTpl()}${this.screenshotMode === 'directory' ? getBaseUrlFixScript() : ''}\n${generateDumpScriptTag(renderedDump, this.getDumpScriptAttributes())}\n${images.join('\\n')}\n${generateTestRunReportScriptTag(dump)}\n${generateAgentReportComment(agentDump)}`;\n mkdirSync(dirname(this.reportPath), { recursive: true });\n const temporaryPath = `${this.reportPath}.runner-${uuid()}.tmp`;\n try {\n await writeFileAsync(temporaryPath, contents);\n await renameAsync(temporaryPath, this.reportPath);\n } finally {\n await unlinkAsync(temporaryPath).catch((error) => {\n if (error.code !== 'ENOENT') throw error;\n });\n }\n this.initialized = true;\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n });\n await this.flush();\n return this.reportPath;\n }\n\n enableSourceSnapshots(): void {\n this.screenshotStore.enableFileCopies();\n }\n\n private async serializeSourceDump(snapshot?: ExecutionRecordSnapshot) {\n this.enableSourceSnapshots();\n const captured =\n snapshot ??\n this.recorder.capture(\n undefined,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n for (const screenshot of captured.screenshots)\n await this.screenshotStore.persist(screenshot);\n const references = new Map<string, ImageUrlRef>();\n for (const url of captured.referenceImageUrls) {\n references.set(\n url,\n await this.screenshotStore.persistReferenceImage(url),\n );\n }\n const images = new Map<\n string,\n ReturnType<typeof normalizeStoredImageRef> & {}\n >();\n const serialized = JSON.stringify(\n JSON.parse(captured.dump.serializeWithReferenceImages(references)),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (!ref) return value;\n const stored = {\n ...ref,\n storage: 'file' as const,\n path:\n ref.storage === 'file'\n ? ref.path\n : this.screenshotStore.getFilePath(ref.id),\n };\n images.set(ref.id, stored);\n return stored;\n },\n );\n return { serialized, images };\n }\n\n async createSourceSnapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource & { dumpPath: string }> {\n this.assertOpen();\n if (!scopeId || basename(scopeId) !== scopeId)\n throw new Error('Invalid report scope ID');\n const snapshot = this.recorder.capture(\n executionIds,\n this.lastReportMeta ?? {\n sdkVersion: '',\n groupName: 'YAML execution',\n modelBriefs: [],\n },\n );\n const publication = (async () => {\n const { serialized } = await this.serializeSourceDump(snapshot);\n const dumpPath = `${this.reportPath}.${scopeId}.${uuid()}.json`;\n mkdirSync(dirname(dumpPath), { recursive: true });\n await writeFileAsync(dumpPath, serialized, { flag: 'wx' });\n return {\n sourcePath: this.reportPath,\n dumpPath,\n collection: {\n status: 'complete' as const,\n capturedAt: snapshot.capturedAt,\n },\n };\n })();\n this.sourcePublications.add(publication);\n try {\n return await publication;\n } finally {\n this.sourcePublications.delete(publication);\n }\n }\n\n private printReportPath(): void {\n if (!this.autoPrint || !this.reportPath) return;\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET))\n return;\n\n if (this.screenshotMode === 'directory') {\n logReport(\n `Midscene - report file updated: npx serve ${dirname(this.reportPath)}`,\n );\n } else {\n logReport(`Midscene - report file updated: ${this.reportPath}`);\n }\n }\n\n private async doWriteExecution(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): Promise<void> {\n const singleDump = this.wrapAsReportDump(execution, reportMeta);\n\n const referenceImageRefs = await this.writeExecution(execution, singleDump);\n\n if (this.shouldPersistExecutionDump && !this.artifactStore) {\n await this.persistExecutionDumpToFile(\n execution,\n singleDump,\n referenceImageRefs,\n );\n }\n\n if (!this.firstWriteDone) {\n this.firstWriteDone = true;\n this.printReportPath();\n }\n }\n\n private mergeReportAttributes(attributes?: ReportAttributes): void {\n if (!attributes) {\n return;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) {\n continue;\n }\n this.reportAttributes[key] = String(value);\n }\n }\n\n private hydrateStateFromExistingReport(): void {\n if (!existsSync(this.reportPath)) {\n return;\n }\n\n if (this.artifactStore && !readReportArtifactManifest(this.reportPath)) {\n throw new Error(\n 'Cannot reuse an incompatible directory report. Choose a new reportFileName or regenerate the report.',\n );\n }\n\n // Reuse existing report file and append new updates instead of rewriting.\n this.initialized = true;\n\n if (!this.shouldPersistExecutionDump) {\n return;\n }\n\n if (!existsSync(this.executionDumpDir)) return;\n const existingExecutionIndices = readdirSync(this.executionDumpDir)\n .map((name) => /^(\\d+)\\.execution\\.json$/.exec(name)?.[1])\n .filter((index): index is string => Boolean(index))\n .map((index) => Number.parseInt(index, 10))\n .filter((index) => Number.isFinite(index));\n\n if (existingExecutionIndices.length > 0) {\n this.executionLogIndex = Math.max(...existingExecutionIndices);\n }\n }\n\n private getDumpScriptAttributes(): Record<string, string> {\n return {\n 'data-group-id': this.reportStreamId,\n // Self-describe how this report file stores screenshots so consumers\n // (merge/delete) never have to guess the mode from the filesystem.\n [DATA_SCREENSHOT_MODE_ATTR]: this.screenshotMode,\n ...this.reportAttributes,\n };\n }\n\n /**\n * Wrap an ExecutionDump + ReportMeta into a single-execution ReportActionDump.\n */\n private wrapAsReportDump(\n execution: ExecutionDump,\n reportMeta: ReportMeta,\n ): ReportActionDump {\n return new ReportActionDump({\n sdkVersion: reportMeta.sdkVersion,\n groupName: reportMeta.groupName,\n groupDescription: reportMeta.groupDescription,\n modelBriefs: reportMeta.modelBriefs,\n deviceType: reportMeta.deviceType,\n executions: [execution],\n });\n }\n\n /**\n * Append assets and a dump tag without duplicating mode-specific workflows.\n * The frontend deduplicates executions with the same id/name (keeps last).\n * Duplicate dump JSON is acceptable; only screenshots are deduplicated.\n *\n * All writes go through `fs/promises` so they run on libuv's thread pool\n * rather than blocking the Node event loop. A long agent run previously\n * appended multi-MB dumps (screenshots + serialized tasks) per progress\n * tick on the main thread, starving IPC and UI for >10s per stall.\n */\n private async writeExecution(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const dir = dirname(this.reportPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Initialize: write HTML template once\n if (!this.initialized) {\n const baseUrlFix =\n this.screenshotMode === 'directory' ? getBaseUrlFixScript() : '';\n const marker = this.artifactStore\n ? `\\n${generateReportArtifactScriptTag('report.json')}`\n : '';\n await writeFileAsync(\n this.reportPath,\n `${getReportTpl()}${baseUrlFix}${marker}`,\n );\n this.initialized = true;\n }\n\n // Append new screenshots (skip already-written ones)\n for (const screenshot of execution.collectScreenshots()) {\n await this.screenshotStore.persist(screenshot);\n }\n const referenceImageRefs = await this.persistReferenceImages(execution);\n\n // Publish the latest facts using the selected storage format.\n const serialized =\n singleDump.serializeWithReferenceImages(referenceImageRefs);\n if (this.artifactStore) {\n await this.artifactStore.writeExecution(\n this.getExecutionCommentKey(execution),\n serialized,\n this.getDumpScriptAttributes(),\n );\n } else {\n await appendFileAsync(\n this.reportPath,\n `\\n${generateDumpScriptTag(serialized, this.getDumpScriptAttributes())}`,\n );\n }\n return referenceImageRefs;\n }\n\n private async persistReferenceImages(\n execution: ExecutionDump,\n ): Promise<Map<string, ImageUrlRef>> {\n const refs = new Map<string, ImageUrlRef>();\n for (const imageUrl of execution.getReferenceImageUrls()) {\n const ref = await this.screenshotStore.persistReferenceImage(imageUrl);\n refs.set(imageUrl, ref);\n }\n return refs;\n }\n\n private async appendAgentReportComment(): Promise<void> {\n if (\n this.agentCommentWritten ||\n !this.lastReportMeta ||\n this.recorder.executions.length === 0\n ) {\n return;\n }\n\n const reportDump = new ReportActionDump({\n sdkVersion: this.lastReportMeta.sdkVersion,\n groupName: this.lastReportMeta.groupName,\n groupDescription: this.lastReportMeta.groupDescription,\n modelBriefs: this.lastReportMeta.modelBriefs,\n deviceType: this.lastReportMeta.deviceType,\n executions: this.recorder.executions,\n });\n await appendFileAsync(\n this.reportPath,\n `\\n${generateAgentReportComment(reportDump)}`,\n );\n this.agentCommentWritten = true;\n }\n\n private getExecutionLogKey(execution: ExecutionDump): string {\n if (!execution.id) {\n throw new Error(\n 'ReportGenerator: execution.id is required for persisting execution dumps',\n );\n }\n return `id:${execution.id}`;\n }\n\n private getExecutionCommentKey(execution: ExecutionDump): string {\n if (execution.id) {\n return `id:${execution.id}`;\n }\n\n const existingKey = this.executionCommentKeyByObject.get(execution);\n if (existingKey) {\n return existingKey;\n }\n\n const key = `no-id:${this.executionCommentKeyIndex++}`;\n this.executionCommentKeyByObject.set(execution, key);\n return key;\n }\n\n private get executionDumpDir(): string {\n // Inline HTML files share their parent directory. Each needs its own\n // numbered JSON namespace; external-asset reports already have one.\n return this.screenshotMode === 'inline'\n ? join(\n dirname(this.reportPath),\n '.execution-dumps',\n basename(this.reportPath),\n )\n : dirname(this.reportPath);\n }\n\n private async persistExecutionDumpToFile(\n execution: ExecutionDump,\n singleDump: ReportActionDump,\n referenceImageRefs: ReadonlyMap<string, ImageUrlRef>,\n ): Promise<void> {\n const dir = this.executionDumpDir;\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const executionLogKey = this.getExecutionLogKey(execution);\n let fileIndex =\n this.executionLogFileIndexByExecutionKey.get(executionLogKey);\n if (!fileIndex) {\n this.executionLogIndex += 1;\n fileIndex = this.executionLogIndex;\n this.executionLogFileIndexByExecutionKey.set(executionLogKey, fileIndex);\n }\n\n const fileName = `${fileIndex}.execution.json`;\n const filePath = join(dir, fileName);\n let serialized = singleDump.serializeWithReferenceImages(\n referenceImageRefs,\n 2,\n );\n if (this.screenshotMode === 'inline') {\n // JSON is two directories below the HTML. Point to the existing file\n // copies so it can be consumed without resolving inline HTML assets.\n serialized = JSON.stringify(\n JSON.parse(serialized),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n return ref\n ? {\n ...ref,\n storage: 'file',\n path: `../../${this.screenshotStore.getFilePath(ref.id).replace(/^\\.\\//, '')}`,\n }\n : value;\n },\n 2,\n );\n }\n await writeFileAsync(filePath, serialized, 'utf-8');\n }\n}\n\nfunction ensureHtmlFileName(reportFileName: string): string {\n return reportFileName.endsWith('.html')\n ? reportFileName\n : `${reportFileName}.html`;\n}\n\nfunction validateReportFileName(\n reportFileName: string,\n outputFormat?: 'single-html' | 'html-and-external-assets',\n): void {\n if (!reportFileName?.trim()) {\n throw new Error('reportFileName must be a non-empty string');\n }\n\n if (/[\\\\/]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName must not contain path separators (`/` or `\\\\\\\\`)',\n );\n }\n\n if (/[:*?\"<>|]/.test(reportFileName)) {\n throw new Error(\n 'reportFileName contains illegal filename characters: : * ? \" < > |',\n );\n }\n\n const filenameComponent =\n outputFormat === 'html-and-external-assets'\n ? reportFileName\n : ensureHtmlFileName(reportFileName);\n const filenameBytes = new TextEncoder().encode(filenameComponent).byteLength;\n if (filenameBytes > maxReportFilenameBytes) {\n throw new Error(\n `reportFileName produces a filename component of ${filenameBytes} UTF-8 bytes; maximum is ${maxReportFilenameBytes}`,\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","warnReport","getDebug","maxReportFilenameBytes","nullReportGenerator","undefined","assertReportGenerationOptions","opts","Error","ReportGenerator","reportFileName","validateReportFileName","ifInBrowser","reportRootDir","getMidsceneRunSubDir","outputDir","join","reportPath","ensureHtmlFileName","execution","reportMeta","attributes","Promise","compactReportDumps","error","String","WeakMap","input","scopeId","meta","executions","agentDump","ReportActionDump","reportId","dump","buildAgentTestRunReportDump","diagnostic","sourceDump","images","ref","bytes","readFileAsync","dirname","generateImageScriptTag","marker","generateReportArtifactScriptTag","writeFileAsync","getReportTpl","getBaseUrlFixScript","JSON","renderedDump","_key","value","normalizeStoredImageRef","contents","generateDumpScriptTag","generateTestRunReportScriptTag","generateAgentReportComment","mkdirSync","temporaryPath","uuid","renameAsync","unlinkAsync","snapshot","captured","screenshot","references","Map","url","serialized","stored","executionIds","basename","publication","dumpPath","globalConfigManager","MIDSCENE_REPORT_QUIET","logReport","singleDump","referenceImageRefs","existsSync","readReportArtifactManifest","existingExecutionIndices","readdirSync","name","index","Boolean","Number","Math","DATA_SCREENSHOT_MODE_ATTR","dir","baseUrlFix","appendFileAsync","refs","imageUrl","reportDump","existingKey","executionLogKey","fileIndex","fileName","filePath","options","ExecutionRecorder","Set","ReportArtifactStore","ReportImageStore","id","base64","outputFormat","filenameComponent","filenameBytes","TextEncoder"],"mappings":"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"}