@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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
ReportArtifactWriter: ()=>ReportArtifactWriter
|
|
28
|
+
});
|
|
29
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
30
|
+
const promises_namespaceObject = require("node:fs/promises");
|
|
31
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
32
|
+
const report_artifact_namespaceObject = require("@midscene/shared/report-artifact");
|
|
33
|
+
const utils_namespaceObject = require("@midscene/shared/utils");
|
|
34
|
+
const external_utils_js_namespaceObject = require("../utils.js");
|
|
35
|
+
const external_html_utils_js_namespaceObject = require("./html-utils.js");
|
|
36
|
+
const external_report_artifact_store_js_namespaceObject = require("./report-artifact-store.js");
|
|
37
|
+
const external_test_report_images_js_namespaceObject = require("./test-report-images.js");
|
|
38
|
+
function _define_property(obj, key, value) {
|
|
39
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
40
|
+
value: value,
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true
|
|
44
|
+
});
|
|
45
|
+
else obj[key] = value;
|
|
46
|
+
return obj;
|
|
47
|
+
}
|
|
48
|
+
class ReportArtifactWriter {
|
|
49
|
+
get template() {
|
|
50
|
+
const template = (0, external_utils_js_namespaceObject.getReportTpl)();
|
|
51
|
+
const end = template.lastIndexOf('</html>');
|
|
52
|
+
return (end < 0 ? template : template.slice(0, end)) + (this.external ? (0, external_html_utils_js_namespaceObject.getBaseUrlFixScript)() : '');
|
|
53
|
+
}
|
|
54
|
+
async initialize() {
|
|
55
|
+
await (0, promises_namespaceObject.mkdir)((0, external_node_path_namespaceObject.dirname)(this.entry), {
|
|
56
|
+
recursive: true
|
|
57
|
+
});
|
|
58
|
+
await (0, promises_namespaceObject.writeFile)(this.entry, this.template);
|
|
59
|
+
}
|
|
60
|
+
initializeSync() {
|
|
61
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(this.entry), {
|
|
62
|
+
recursive: true
|
|
63
|
+
});
|
|
64
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(this.entry, this.template);
|
|
65
|
+
}
|
|
66
|
+
group(id, attributes) {
|
|
67
|
+
if (this.manifest.groups.some((group)=>group.id === id)) throw new Error(`Duplicate report group: ${id}`);
|
|
68
|
+
const path = `data/group-${this.manifest.groups.length + 1}/1.json`;
|
|
69
|
+
this.manifest.groups.push({
|
|
70
|
+
id,
|
|
71
|
+
status: 'complete',
|
|
72
|
+
attributes: {
|
|
73
|
+
...attributes,
|
|
74
|
+
'data-screenshot-mode': 'directory'
|
|
75
|
+
},
|
|
76
|
+
dumps: [
|
|
77
|
+
path
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
return (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), path);
|
|
81
|
+
}
|
|
82
|
+
inlineGroup(id, attributes, serialized) {
|
|
83
|
+
return (0, external_utils_js_namespaceObject.reportHTMLContent)({
|
|
84
|
+
dumpString: serialized,
|
|
85
|
+
attributes: {
|
|
86
|
+
...attributes,
|
|
87
|
+
'data-group-id': id,
|
|
88
|
+
'data-screenshot-mode': 'inline',
|
|
89
|
+
'data-report-kind': this.manifest.kind
|
|
90
|
+
}
|
|
91
|
+
}, void 0, void 0, false);
|
|
92
|
+
}
|
|
93
|
+
async addGroup(id, serialized, sourcePath, attributes, origins) {
|
|
94
|
+
const rewritten = await this.images.rewriteAsync(serialized, sourcePath, origins);
|
|
95
|
+
if (this.external) await (0, external_report_artifact_store_js_namespaceObject.writeReportArtifactFile)(this.group(id, attributes), rewritten);
|
|
96
|
+
else await (0, promises_namespaceObject.appendFile)(this.entry, this.inlineGroup(id, attributes, rewritten));
|
|
97
|
+
}
|
|
98
|
+
addGroupSync(id, serialized, sourcePath, attributes, origins) {
|
|
99
|
+
const rewritten = this.images.rewriteSync(serialized, sourcePath, origins);
|
|
100
|
+
if (this.external) {
|
|
101
|
+
const file = this.group(id, attributes);
|
|
102
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(file), {
|
|
103
|
+
recursive: true
|
|
104
|
+
});
|
|
105
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(file, rewritten);
|
|
106
|
+
} else (0, external_node_fs_namespaceObject.appendFileSync)(this.entry, this.inlineGroup(id, attributes, rewritten));
|
|
107
|
+
}
|
|
108
|
+
footer(runner, comment) {
|
|
109
|
+
const data = this.external ? (0, external_html_utils_js_namespaceObject.generateReportArtifactScriptTag)('report.json') : runner ? (0, external_html_utils_js_namespaceObject.generateTestRunReportScriptTag)(runner) : '';
|
|
110
|
+
return `${data}${comment}\n</html>\n`;
|
|
111
|
+
}
|
|
112
|
+
async finish(runner, comment = '') {
|
|
113
|
+
if (this.external) {
|
|
114
|
+
if (runner) {
|
|
115
|
+
this.manifest.runner = 'data/runner.json';
|
|
116
|
+
await (0, external_report_artifact_store_js_namespaceObject.writeReportArtifactFile)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), this.manifest.runner), JSON.stringify(runner));
|
|
117
|
+
}
|
|
118
|
+
(0, report_artifact_namespaceObject.parseReportArtifactManifest)(this.manifest);
|
|
119
|
+
await (0, external_report_artifact_store_js_namespaceObject.writeReportArtifactFile)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), 'report.json'), JSON.stringify(this.manifest));
|
|
120
|
+
}
|
|
121
|
+
await (0, promises_namespaceObject.appendFile)(this.entry, this.footer(runner, comment));
|
|
122
|
+
}
|
|
123
|
+
finishSync(runner, comment = '') {
|
|
124
|
+
if (this.external) {
|
|
125
|
+
if (runner) {
|
|
126
|
+
this.manifest.runner = 'data/runner.json';
|
|
127
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), 'data'), {
|
|
128
|
+
recursive: true
|
|
129
|
+
});
|
|
130
|
+
(0, external_node_fs_namespaceObject.writeFileSync)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), this.manifest.runner), JSON.stringify(runner));
|
|
131
|
+
}
|
|
132
|
+
(0, report_artifact_namespaceObject.parseReportArtifactManifest)(this.manifest);
|
|
133
|
+
(0, external_node_fs_namespaceObject.writeFileSync)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.entry), 'report.json'), JSON.stringify(this.manifest));
|
|
134
|
+
}
|
|
135
|
+
(0, external_node_fs_namespaceObject.appendFileSync)(this.entry, this.footer(runner, comment));
|
|
136
|
+
}
|
|
137
|
+
constructor(entry, external, kind, reportId = (0, utils_namespaceObject.uuid)()){
|
|
138
|
+
_define_property(this, "entry", void 0);
|
|
139
|
+
_define_property(this, "external", void 0);
|
|
140
|
+
_define_property(this, "manifest", void 0);
|
|
141
|
+
_define_property(this, "images", void 0);
|
|
142
|
+
this.entry = entry;
|
|
143
|
+
this.external = external;
|
|
144
|
+
this.manifest = {
|
|
145
|
+
schemaVersion: 1,
|
|
146
|
+
kind,
|
|
147
|
+
reportId,
|
|
148
|
+
entry: (0, external_node_path_namespaceObject.basename)(entry),
|
|
149
|
+
status: 'complete',
|
|
150
|
+
groups: []
|
|
151
|
+
};
|
|
152
|
+
this.images = new external_test_report_images_js_namespaceObject.TestReportImages(entry, external);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.ReportArtifactWriter = __webpack_exports__.ReportArtifactWriter;
|
|
156
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
157
|
+
"ReportArtifactWriter"
|
|
158
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
159
|
+
Object.defineProperty(exports, '__esModule', {
|
|
160
|
+
value: true
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=report-artifact-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump/report-artifact-writer.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/report-artifact-writer.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};","import { appendFileSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport {\n type ReportArtifactManifest,\n parseReportArtifactManifest,\n} from '@midscene/shared/report-artifact';\nimport { uuid } from '@midscene/shared/utils';\nimport type { TestRunReportDump } from '../test-run-report';\nimport { getReportTpl, reportHTMLContent } from '../utils';\nimport {\n generateReportArtifactScriptTag,\n generateTestRunReportScriptTag,\n getBaseUrlFixScript,\n} from './html-utils';\nimport { writeReportArtifactFile } from './report-artifact-store';\nimport { TestReportImages } from './test-report-images';\n\nexport type ReportGroupAttributes = Record<string, string | number | boolean>;\n\n/** Final publisher shared by Test, report merging, and format conversion. */\nexport class ReportArtifactWriter {\n private readonly manifest: ReportArtifactManifest;\n private readonly images: TestReportImages;\n\n constructor(\n private readonly entry: string,\n private readonly external: boolean,\n kind: 'agent' | 'test',\n reportId = uuid(),\n ) {\n this.manifest = {\n schemaVersion: 1,\n kind,\n reportId,\n entry: basename(entry),\n status: 'complete',\n groups: [],\n };\n this.images = new TestReportImages(entry, external);\n }\n\n private get template(): string {\n const template = getReportTpl();\n const end = template.lastIndexOf('</html>');\n return (\n (end < 0 ? template : template.slice(0, end)) +\n (this.external ? getBaseUrlFixScript() : '')\n );\n }\n\n async initialize(): Promise<void> {\n await mkdir(dirname(this.entry), { recursive: true });\n await writeFile(this.entry, this.template);\n }\n initializeSync(): void {\n mkdirSync(dirname(this.entry), { recursive: true });\n writeFileSync(this.entry, this.template);\n }\n\n private group(id: string, attributes: ReportGroupAttributes) {\n if (this.manifest.groups.some((group) => group.id === id))\n throw new Error(`Duplicate report group: ${id}`);\n const path = `data/group-${this.manifest.groups.length + 1}/1.json`;\n this.manifest.groups.push({\n id,\n status: 'complete',\n attributes: { ...attributes, 'data-screenshot-mode': 'directory' },\n dumps: [path],\n });\n return join(dirname(this.entry), path);\n }\n\n private inlineGroup(\n id: string,\n attributes: ReportGroupAttributes,\n serialized: string,\n ): string {\n return reportHTMLContent(\n {\n dumpString: serialized,\n attributes: {\n ...attributes,\n 'data-group-id': id,\n 'data-screenshot-mode': 'inline',\n 'data-report-kind': this.manifest.kind,\n },\n },\n undefined,\n undefined,\n false,\n );\n }\n\n async addGroup(\n id: string,\n serialized: string,\n sourcePath: string,\n attributes: ReportGroupAttributes,\n origins?: ReadonlyMap<string, string>,\n ): Promise<void> {\n const rewritten = await this.images.rewriteAsync(\n serialized,\n sourcePath,\n origins,\n );\n if (this.external)\n await writeReportArtifactFile(this.group(id, attributes), rewritten);\n else\n await appendFile(this.entry, this.inlineGroup(id, attributes, rewritten));\n }\n addGroupSync(\n id: string,\n serialized: string,\n sourcePath: string,\n attributes: ReportGroupAttributes,\n origins?: ReadonlyMap<string, string>,\n ): void {\n const rewritten = this.images.rewriteSync(serialized, sourcePath, origins);\n if (this.external) {\n const file = this.group(id, attributes);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, rewritten);\n } else\n appendFileSync(this.entry, this.inlineGroup(id, attributes, rewritten));\n }\n\n private footer(\n runner: TestRunReportDump | undefined,\n comment: string,\n ): string {\n const data = this.external\n ? generateReportArtifactScriptTag('report.json')\n : runner\n ? generateTestRunReportScriptTag(runner)\n : '';\n return `${data}${comment}\\n</html>\\n`;\n }\n\n async finish(runner?: TestRunReportDump, comment = ''): Promise<void> {\n if (this.external) {\n if (runner) {\n this.manifest.runner = 'data/runner.json';\n await writeReportArtifactFile(\n join(dirname(this.entry), this.manifest.runner),\n JSON.stringify(runner),\n );\n }\n parseReportArtifactManifest(this.manifest);\n await writeReportArtifactFile(\n join(dirname(this.entry), 'report.json'),\n JSON.stringify(this.manifest),\n );\n }\n await appendFile(this.entry, this.footer(runner, comment));\n }\n finishSync(runner?: TestRunReportDump, comment = ''): void {\n if (this.external) {\n if (runner) {\n this.manifest.runner = 'data/runner.json';\n mkdirSync(join(dirname(this.entry), 'data'), { recursive: true });\n writeFileSync(\n join(dirname(this.entry), this.manifest.runner),\n JSON.stringify(runner),\n );\n }\n parseReportArtifactManifest(this.manifest);\n writeFileSync(\n join(dirname(this.entry), 'report.json'),\n JSON.stringify(this.manifest),\n );\n }\n appendFileSync(this.entry, this.footer(runner, comment));\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","ReportArtifactWriter","template","getReportTpl","end","getBaseUrlFixScript","mkdir","dirname","writeFile","mkdirSync","writeFileSync","id","attributes","group","Error","path","join","serialized","reportHTMLContent","undefined","sourcePath","origins","rewritten","writeReportArtifactFile","appendFile","file","appendFileSync","runner","comment","data","generateReportArtifactScriptTag","generateTestRunReportScriptTag","JSON","parseReportArtifactManifest","entry","external","kind","reportId","uuid","basename","TestReportImages"],"mappings":"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"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
currentReportSession: ()=>currentReportSession,
|
|
28
|
+
ReportSession: ()=>ReportSession
|
|
29
|
+
});
|
|
30
|
+
const promises_namespaceObject = require("node:fs/promises");
|
|
31
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
32
|
+
const utils_namespaceObject = require("@midscene/shared/utils");
|
|
33
|
+
const external_yaml_execution_context_namespaceObject = require("#yaml-execution-context");
|
|
34
|
+
const external_execution_recorder_js_namespaceObject = require("./execution-recorder.js");
|
|
35
|
+
const external_image_reference_js_namespaceObject = require("./image-reference.js");
|
|
36
|
+
const external_report_artifact_store_js_namespaceObject = require("./report-artifact-store.js");
|
|
37
|
+
const external_screenshot_store_js_namespaceObject = require("./screenshot-store.js");
|
|
38
|
+
function _define_property(obj, key, value) {
|
|
39
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
40
|
+
value: value,
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true
|
|
44
|
+
});
|
|
45
|
+
else obj[key] = value;
|
|
46
|
+
return obj;
|
|
47
|
+
}
|
|
48
|
+
const contextKey = Symbol.for('@midscene/core/report-session/v1');
|
|
49
|
+
const host = globalThis;
|
|
50
|
+
host[contextKey] ??= (0, external_yaml_execution_context_namespaceObject.createExecutionContext)();
|
|
51
|
+
const context = host[contextKey];
|
|
52
|
+
class ReportSession {
|
|
53
|
+
async run(callback) {
|
|
54
|
+
if (this.ended) throw new Error('The report session has ended.');
|
|
55
|
+
this.ownership ??= (async ()=>{
|
|
56
|
+
await (0, promises_namespaceObject.mkdir)((0, external_node_path_namespaceObject.dirname)(this.directory), {
|
|
57
|
+
recursive: true
|
|
58
|
+
});
|
|
59
|
+
await (0, promises_namespaceObject.mkdir)(this.directory);
|
|
60
|
+
})();
|
|
61
|
+
await this.ownership;
|
|
62
|
+
return context.run(this, callback);
|
|
63
|
+
}
|
|
64
|
+
createRecorder(isBusy) {
|
|
65
|
+
if (!this.ownership) throw new Error('Start the report session before creating a writer.');
|
|
66
|
+
if (this.ended) throw new Error('Cannot add a writer to an ended report session.');
|
|
67
|
+
const writer = new ReportSourceRecorder(this.directory, isBusy);
|
|
68
|
+
this.writers.add(writer);
|
|
69
|
+
return writer;
|
|
70
|
+
}
|
|
71
|
+
async finish() {
|
|
72
|
+
this.ended = true;
|
|
73
|
+
this.completion ??= (async ()=>{
|
|
74
|
+
const sources = [];
|
|
75
|
+
for (const writer of this.writers){
|
|
76
|
+
const source = await writer.captureUncollected();
|
|
77
|
+
if (source) sources.push(source);
|
|
78
|
+
if (writer.isBusy()) await writer.flush();
|
|
79
|
+
else await writer.finalize();
|
|
80
|
+
}
|
|
81
|
+
return sources;
|
|
82
|
+
})();
|
|
83
|
+
return this.completion;
|
|
84
|
+
}
|
|
85
|
+
async prune() {
|
|
86
|
+
if (!this.completion) throw new Error('Finish the report session before pruning it.');
|
|
87
|
+
await this.completion;
|
|
88
|
+
if (!this.writers.size) return void await (0, promises_namespaceObject.rm)(this.directory, {
|
|
89
|
+
recursive: true,
|
|
90
|
+
force: true
|
|
91
|
+
});
|
|
92
|
+
if ([
|
|
93
|
+
...this.writers
|
|
94
|
+
].some((writer)=>writer.isBusy())) return;
|
|
95
|
+
await (0, promises_namespaceObject.rm)((0, external_node_path_namespaceObject.join)(this.directory, 'data'), {
|
|
96
|
+
recursive: true,
|
|
97
|
+
force: true
|
|
98
|
+
});
|
|
99
|
+
await (0, promises_namespaceObject.rm)((0, external_node_path_namespaceObject.join)(this.directory, 'report.json'), {
|
|
100
|
+
force: true
|
|
101
|
+
});
|
|
102
|
+
const retained = new Set([
|
|
103
|
+
...this.writers
|
|
104
|
+
].flatMap((writer)=>[
|
|
105
|
+
...writer.snapshotImages
|
|
106
|
+
]));
|
|
107
|
+
const images = (0, external_node_path_namespaceObject.join)(this.directory, 'screenshots');
|
|
108
|
+
const files = await (0, promises_namespaceObject.readdir)(images).catch((error)=>{
|
|
109
|
+
if ('ENOENT' === error.code) return [];
|
|
110
|
+
throw error;
|
|
111
|
+
});
|
|
112
|
+
for (const file of files)if (!retained.has(`./screenshots/${file}`)) await (0, promises_namespaceObject.rm)((0, external_node_path_namespaceObject.join)(images, file));
|
|
113
|
+
}
|
|
114
|
+
constructor(directory){
|
|
115
|
+
_define_property(this, "directory", void 0);
|
|
116
|
+
_define_property(this, "writers", void 0);
|
|
117
|
+
_define_property(this, "ended", void 0);
|
|
118
|
+
_define_property(this, "completion", void 0);
|
|
119
|
+
_define_property(this, "ownership", void 0);
|
|
120
|
+
this.directory = directory;
|
|
121
|
+
this.writers = new Set();
|
|
122
|
+
this.ended = false;
|
|
123
|
+
if (!(0, external_node_path_namespaceObject.isAbsolute)(directory)) throw new Error('Report session directory must be absolute.');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const currentReportSession = ()=>context.getStore();
|
|
127
|
+
class ReportSourceRecorder {
|
|
128
|
+
getReportPath() {}
|
|
129
|
+
enableSourceSnapshots() {}
|
|
130
|
+
isBusy() {
|
|
131
|
+
return this.busy?.() ?? false;
|
|
132
|
+
}
|
|
133
|
+
onExecutionUpdate(execution, meta, attributes = {}) {
|
|
134
|
+
if (this.finalization) throw new Error('The report record stream has been finalized.');
|
|
135
|
+
const key = this.recorder.record(execution, meta);
|
|
136
|
+
const update = new external_execution_recorder_js_namespaceObject.ExecutionRecorder();
|
|
137
|
+
update.record(execution, meta);
|
|
138
|
+
const captured = update.capture();
|
|
139
|
+
this.queue = this.queue.then(async ()=>{
|
|
140
|
+
const serialized = await this.serialize(captured);
|
|
141
|
+
await this.store.writeExecution(key, serialized, Object.fromEntries(Object.entries(attributes).map(([key, value])=>[
|
|
142
|
+
key,
|
|
143
|
+
String(value)
|
|
144
|
+
])));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
async serialize(captured) {
|
|
148
|
+
for (const screenshot of captured.screenshots)await this.images.persist(screenshot);
|
|
149
|
+
const references = new Map();
|
|
150
|
+
for (const url of captured.referenceImageUrls)references.set(url, await this.images.persistReferenceImage(url));
|
|
151
|
+
return JSON.stringify(JSON.parse(captured.dump.serializeWithReferenceImages(references)), (_key, value)=>{
|
|
152
|
+
const ref = (0, external_image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
|
|
153
|
+
if (!ref) return value;
|
|
154
|
+
return {
|
|
155
|
+
...ref,
|
|
156
|
+
storage: 'file',
|
|
157
|
+
path: this.images.getFilePath(ref.id)
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async createSourceSnapshot(scopeId, executionIds) {
|
|
162
|
+
if (this.finalization) throw new Error('The report record stream has been finalized.');
|
|
163
|
+
return this.snapshot(scopeId, executionIds);
|
|
164
|
+
}
|
|
165
|
+
async snapshot(scopeId, executionIds) {
|
|
166
|
+
if ('string' != typeof scopeId || !scopeId.trim()) throw new Error('Invalid report scope ID');
|
|
167
|
+
const busyAtCutoff = this.isBusy();
|
|
168
|
+
const captured = this.recorder.capture(executionIds, this.recorder.reportMeta ?? {
|
|
169
|
+
sdkVersion: '',
|
|
170
|
+
groupName: 'Test execution',
|
|
171
|
+
modelBriefs: []
|
|
172
|
+
});
|
|
173
|
+
const path = (0, external_node_path_namespaceObject.join)(this.directory, `${this.id}.${(0, utils_namespaceObject.uuid)()}.json`);
|
|
174
|
+
const publication = this.queue.then(async ()=>{
|
|
175
|
+
const serialized = await this.serialize(captured);
|
|
176
|
+
await (0, external_report_artifact_store_js_namespaceObject.writeReportArtifactFile)(path, serialized);
|
|
177
|
+
JSON.parse(serialized, (_key, value)=>{
|
|
178
|
+
const ref = (0, external_image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
|
|
179
|
+
if (ref?.path) this.snapshotImages.add(ref.path);
|
|
180
|
+
return value;
|
|
181
|
+
});
|
|
182
|
+
this.sourcePath ??= path;
|
|
183
|
+
for (const execution of captured.dump.executions)if (execution.id) this.collected.add(execution.id);
|
|
184
|
+
});
|
|
185
|
+
this.queue = publication;
|
|
186
|
+
await publication;
|
|
187
|
+
return {
|
|
188
|
+
sourcePath: this.sourcePath,
|
|
189
|
+
dumpPath: path,
|
|
190
|
+
collection: {
|
|
191
|
+
status: busyAtCutoff ? 'partial' : 'complete',
|
|
192
|
+
capturedAt: captured.capturedAt,
|
|
193
|
+
...busyAtCutoff ? {
|
|
194
|
+
reason: 'An Agent operation was still running at the snapshot cutoff.'
|
|
195
|
+
} : {}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
async captureUncollected() {
|
|
200
|
+
if (this.finalization) {
|
|
201
|
+
await this.finalization;
|
|
202
|
+
const source = this.uncollectedSource;
|
|
203
|
+
this.uncollectedSource = void 0;
|
|
204
|
+
return source;
|
|
205
|
+
}
|
|
206
|
+
return this.capturePending();
|
|
207
|
+
}
|
|
208
|
+
async capturePending() {
|
|
209
|
+
const ids = this.recorder.executions.flatMap((execution)=>execution.id && !this.collected.has(execution.id) ? [
|
|
210
|
+
execution.id
|
|
211
|
+
] : []);
|
|
212
|
+
return ids.length ? this.snapshot(this.id, ids) : void 0;
|
|
213
|
+
}
|
|
214
|
+
async flush() {
|
|
215
|
+
await this.queue;
|
|
216
|
+
}
|
|
217
|
+
async finalize() {
|
|
218
|
+
if (!this.finalization) this.finalization = (async ()=>{
|
|
219
|
+
await this.flush();
|
|
220
|
+
this.uncollectedSource = await this.capturePending();
|
|
221
|
+
await this.store.finalize();
|
|
222
|
+
this.recorder.clear();
|
|
223
|
+
this.collected.clear();
|
|
224
|
+
this.busy = void 0;
|
|
225
|
+
})();
|
|
226
|
+
return this.finalization;
|
|
227
|
+
}
|
|
228
|
+
constructor(directory, busy){
|
|
229
|
+
_define_property(this, "directory", void 0);
|
|
230
|
+
_define_property(this, "busy", void 0);
|
|
231
|
+
_define_property(this, "snapshotImages", void 0);
|
|
232
|
+
_define_property(this, "recorder", void 0);
|
|
233
|
+
_define_property(this, "id", void 0);
|
|
234
|
+
_define_property(this, "images", void 0);
|
|
235
|
+
_define_property(this, "store", void 0);
|
|
236
|
+
_define_property(this, "collected", void 0);
|
|
237
|
+
_define_property(this, "sourcePath", void 0);
|
|
238
|
+
_define_property(this, "queue", void 0);
|
|
239
|
+
_define_property(this, "finalization", void 0);
|
|
240
|
+
_define_property(this, "uncollectedSource", void 0);
|
|
241
|
+
this.directory = directory;
|
|
242
|
+
this.busy = busy;
|
|
243
|
+
this.snapshotImages = new Set();
|
|
244
|
+
this.recorder = new external_execution_recorder_js_namespaceObject.ExecutionRecorder();
|
|
245
|
+
this.id = (0, utils_namespaceObject.uuid)();
|
|
246
|
+
this.collected = new Set();
|
|
247
|
+
this.queue = Promise.resolve();
|
|
248
|
+
this.images = new external_screenshot_store_js_namespaceObject.ReportImageStore({
|
|
249
|
+
mode: 'directory',
|
|
250
|
+
reportPath: (0, external_node_path_namespaceObject.join)(directory, `${this.id}.json`),
|
|
251
|
+
screenshotsDir: (0, external_node_path_namespaceObject.join)(directory, 'screenshots')
|
|
252
|
+
});
|
|
253
|
+
this.store = new external_report_artifact_store_js_namespaceObject.ReportArtifactStore(directory, this.id, 'test', true);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.ReportSession = __webpack_exports__.ReportSession;
|
|
257
|
+
exports.currentReportSession = __webpack_exports__.currentReportSession;
|
|
258
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
259
|
+
"ReportSession",
|
|
260
|
+
"currentReportSession"
|
|
261
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
262
|
+
Object.defineProperty(exports, '__esModule', {
|
|
263
|
+
value: true
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
//# sourceMappingURL=report-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump/report-session.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/report-session.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};","import { mkdir, readdir, rm } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport { uuid } from '@midscene/shared/utils';\nimport { createExecutionContext } from '#yaml-execution-context';\nimport type { IReportGenerator } from '../report-generator';\nimport type { WorkflowReportSource } from '../test-runner/engine/types';\nimport type { ExecutionDump, ReportAttributes, ReportMeta } from '../types';\nimport {\n type ExecutionRecordSnapshot,\n ExecutionRecorder,\n} from './execution-recorder';\nimport { normalizeStoredImageRef } from './image-reference';\nimport {\n ReportArtifactStore,\n writeReportArtifactFile,\n} from './report-artifact-store';\nimport { type ImageUrlRef, ReportImageStore } from './screenshot-store';\n\nconst contextKey = Symbol.for('@midscene/core/report-session/v1');\nconst host = globalThis as typeof globalThis & {\n [contextKey]?: ReturnType<typeof createExecutionContext<ReportSession>>;\n};\nhost[contextKey] ??= createExecutionContext<ReportSession>();\nconst context = host[contextKey];\n\n/** The execution host owns the records; Agents do not publish independent pages. */\nexport class ReportSession {\n private readonly writers = new Set<ReportSourceRecorder>();\n private ended = false;\n private completion?: Promise<WorkflowReportSource[]>;\n private ownership?: Promise<void>;\n\n constructor(readonly directory: string) {\n if (!isAbsolute(directory))\n throw new Error('Report session directory must be absolute.');\n }\n\n async run<T>(callback: () => Promise<T>): Promise<T> {\n if (this.ended) throw new Error('The report session has ended.');\n this.ownership ??= (async () => {\n await mkdir(dirname(this.directory), { recursive: true });\n await mkdir(this.directory);\n })();\n await this.ownership;\n return context.run(this, callback);\n }\n\n createRecorder(isBusy: () => boolean): ReportSourceRecorder {\n if (!this.ownership)\n throw new Error('Start the report session before creating a writer.');\n if (this.ended)\n throw new Error('Cannot add a writer to an ended report session.');\n const writer = new ReportSourceRecorder(this.directory, isBusy);\n this.writers.add(writer);\n return writer;\n }\n\n /** Persist untraced setup/teardown evidence too, without waiting on device calls. */\n async finish(): Promise<WorkflowReportSource[]> {\n this.ended = true;\n this.completion ??= (async () => {\n const sources: WorkflowReportSource[] = [];\n for (const writer of this.writers) {\n const source = await writer.captureUncollected();\n if (source) sources.push(source);\n if (!writer.isBusy()) await writer.finalize();\n else await writer.flush();\n }\n return sources;\n })();\n return this.completion;\n }\n\n /** Cutoff records remain authoritative facts; discard replaceable progress only after delivery. */\n async prune(): Promise<void> {\n if (!this.completion)\n throw new Error('Finish the report session before pruning it.');\n await this.completion;\n if (!this.writers.size) {\n await rm(this.directory, { recursive: true, force: true });\n return;\n }\n if ([...this.writers].some((writer) => writer.isBusy())) return;\n await rm(join(this.directory, 'data'), { recursive: true, force: true });\n await rm(join(this.directory, 'report.json'), { force: true });\n const retained = new Set(\n [...this.writers].flatMap((writer) => [...writer.snapshotImages]),\n );\n const images = join(this.directory, 'screenshots');\n const files = await readdir(images).catch((error) => {\n if (error.code === 'ENOENT') return [];\n throw error;\n });\n for (const file of files)\n if (!retained.has(`./screenshots/${file}`)) await rm(join(images, file));\n }\n}\n\nexport const currentReportSession = (): ReportSession | undefined =>\n context.getStore();\n\n/** Structured Agent records and immutable Step cutoffs, with shared image assets. */\nclass ReportSourceRecorder implements IReportGenerator {\n readonly snapshotImages = new Set<string>();\n private readonly recorder = new ExecutionRecorder();\n private readonly id = uuid();\n private readonly images: ReportImageStore;\n private readonly store: ReportArtifactStore;\n private readonly collected = new Set<string>();\n private sourcePath?: string;\n private queue: Promise<void> = Promise.resolve();\n private finalization?: Promise<undefined>;\n private uncollectedSource?: WorkflowReportSource;\n\n constructor(\n private readonly directory: string,\n private busy: (() => boolean) | undefined,\n ) {\n this.images = new ReportImageStore({\n mode: 'directory',\n reportPath: join(directory, `${this.id}.json`),\n screenshotsDir: join(directory, 'screenshots'),\n });\n this.store = new ReportArtifactStore(directory, this.id, 'test', true);\n }\n\n getReportPath(): undefined {\n return undefined;\n }\n enableSourceSnapshots(): void {}\n isBusy(): boolean {\n return this.busy?.() ?? false;\n }\n\n onExecutionUpdate(\n execution: ExecutionDump,\n meta: ReportMeta,\n attributes: ReportAttributes = {},\n ): void {\n if (this.finalization)\n throw new Error('The report record stream has been finalized.');\n const key = this.recorder.record(execution, meta);\n const update = new ExecutionRecorder();\n update.record(execution, meta);\n const captured = update.capture();\n this.queue = this.queue.then(async () => {\n const serialized = await this.serialize(captured);\n await this.store.writeExecution(\n key,\n serialized,\n Object.fromEntries(\n Object.entries(attributes).map(([key, value]) => [\n key,\n String(value),\n ]),\n ),\n );\n });\n }\n\n private async serialize(captured: ExecutionRecordSnapshot): Promise<string> {\n for (const screenshot of captured.screenshots)\n await this.images.persist(screenshot);\n const references = new Map<string, ImageUrlRef>();\n for (const url of captured.referenceImageUrls)\n references.set(url, await this.images.persistReferenceImage(url));\n return JSON.stringify(\n JSON.parse(captured.dump.serializeWithReferenceImages(references)),\n (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (!ref) return value;\n return {\n ...ref,\n storage: 'file',\n path: this.images.getFilePath(ref.id),\n };\n },\n );\n }\n\n async createSourceSnapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource> {\n if (this.finalization)\n throw new Error('The report record stream has been finalized.');\n return this.snapshot(scopeId, executionIds);\n }\n\n private async snapshot(\n scopeId: string,\n executionIds?: readonly string[],\n ): Promise<WorkflowReportSource> {\n if (typeof scopeId !== 'string' || !scopeId.trim())\n throw new Error('Invalid report scope ID');\n // Freeze before any I/O: late progress cannot mutate this Step's evidence.\n const busyAtCutoff = this.isBusy();\n const captured = this.recorder.capture(\n executionIds,\n this.recorder.reportMeta ?? {\n sdkVersion: '',\n groupName: 'Test execution',\n modelBriefs: [],\n },\n );\n const path = join(this.directory, `${this.id}.${uuid()}.json`);\n const publication = this.queue.then(async () => {\n const serialized = await this.serialize(captured);\n await writeReportArtifactFile(path, serialized);\n JSON.parse(serialized, (_key, value) => {\n const ref = normalizeStoredImageRef(value);\n if (ref?.path) this.snapshotImages.add(ref.path);\n return value;\n });\n this.sourcePath ??= path;\n for (const execution of captured.dump.executions)\n if (execution.id) this.collected.add(execution.id);\n });\n this.queue = publication;\n await publication;\n return {\n sourcePath: this.sourcePath!,\n dumpPath: path,\n collection: {\n status: busyAtCutoff ? 'partial' : 'complete',\n capturedAt: captured.capturedAt,\n ...(busyAtCutoff\n ? {\n reason:\n 'An Agent operation was still running at the snapshot cutoff.',\n }\n : {}),\n },\n };\n }\n\n async captureUncollected(): Promise<WorkflowReportSource | undefined> {\n if (this.finalization) {\n await this.finalization;\n const source = this.uncollectedSource;\n this.uncollectedSource = undefined;\n return source;\n }\n return this.capturePending();\n }\n\n private async capturePending(): Promise<WorkflowReportSource | undefined> {\n const ids = this.recorder.executions.flatMap((execution) =>\n execution.id && !this.collected.has(execution.id) ? [execution.id] : [],\n );\n return ids.length ? this.snapshot(this.id, ids) : undefined;\n }\n\n async flush(): Promise<void> {\n await this.queue;\n }\n\n async finalize(): Promise<undefined> {\n if (!this.finalization)\n this.finalization = (async () => {\n await this.flush();\n // Preserve setup/teardown evidence before releasing executions. The\n // Session can collect this lightweight source after Agent.destroy().\n this.uncollectedSource = await this.capturePending();\n await this.store.finalize();\n this.recorder.clear();\n this.collected.clear();\n this.busy = undefined;\n return undefined;\n })();\n return this.finalization;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","contextKey","host","globalThis","createExecutionContext","context","ReportSession","callback","Error","mkdir","dirname","isBusy","writer","ReportSourceRecorder","sources","source","rm","join","retained","Set","images","files","readdir","error","file","directory","isAbsolute","currentReportSession","execution","meta","attributes","update","ExecutionRecorder","captured","serialized","value","String","screenshot","references","Map","url","JSON","_key","ref","normalizeStoredImageRef","scopeId","executionIds","busyAtCutoff","path","uuid","publication","writeReportArtifactFile","undefined","ids","busy","Promise","ReportImageStore","ReportArtifactStore"],"mappings":"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"}
|
|
@@ -29,6 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
30
30
|
const promises_namespaceObject = require("node:fs/promises");
|
|
31
31
|
const external_node_path_namespaceObject = require("node:path");
|
|
32
|
+
const report_artifact_namespaceObject = require("@midscene/shared/report-artifact");
|
|
32
33
|
const external_html_utils_js_namespaceObject = require("./html-utils.js");
|
|
33
34
|
const external_image_reference_js_namespaceObject = require("./image-reference.js");
|
|
34
35
|
const external_screenshot_store_js_namespaceObject = require("./screenshot-store.js");
|
|
@@ -75,6 +76,7 @@ class TestReportImages {
|
|
|
75
76
|
const refs = new Map();
|
|
76
77
|
JSON.parse(serialized, (_key, value)=>{
|
|
77
78
|
const ref = (0, external_image_reference_js_namespaceObject.normalizeStoredImageRef)(value);
|
|
79
|
+
if (ref?.storage === 'file') (0, report_artifact_namespaceObject.assertReportArtifactPath)(ref.path);
|
|
78
80
|
if (ref && !this.locations.has(ref.id)) refs.set(ref.id, ref);
|
|
79
81
|
return value;
|
|
80
82
|
});
|
|
@@ -82,53 +84,77 @@ class TestReportImages {
|
|
|
82
84
|
...refs.values()
|
|
83
85
|
];
|
|
84
86
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
for (const ref of
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
inlineSources(refs, sourcePath, origins) {
|
|
88
|
+
const sources = new Map();
|
|
89
|
+
for (const ref of refs)if ('inline' === ref.storage) {
|
|
90
|
+
const source = origins?.get(ref.id) ?? sourcePath;
|
|
91
|
+
const images = sources.get(source) ?? new Map();
|
|
92
|
+
images.set(ref.id, ref);
|
|
93
|
+
sources.set(source, images);
|
|
94
|
+
}
|
|
95
|
+
return sources;
|
|
96
|
+
}
|
|
97
|
+
writeSync(ref, data) {
|
|
98
|
+
const target = this.reference(ref, data);
|
|
99
|
+
if ('file' === target.storage) {
|
|
100
|
+
if (!this.files.has(target.path)) {
|
|
101
|
+
const file = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), target.path);
|
|
102
|
+
(0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(file), {
|
|
103
|
+
recursive: true
|
|
104
|
+
});
|
|
105
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(file, Buffer.from((0, external_screenshot_store_js_namespaceObject.parseBase64ImageDataUrl)(data).rawBase64, 'base64'));
|
|
106
|
+
this.files.add(target.path);
|
|
94
107
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
} else (0, external_node_fs_namespaceObject.appendFileSync)(this.reportPath, `${(0, external_html_utils_js_namespaceObject.generateImageScriptTag)(ref.id, data)}\n`);
|
|
109
|
+
}
|
|
110
|
+
async write(ref, data) {
|
|
111
|
+
const target = this.reference(ref, data);
|
|
112
|
+
if ('file' === target.storage) {
|
|
113
|
+
if (!this.files.has(target.path)) {
|
|
114
|
+
const file = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), target.path);
|
|
115
|
+
await promises_namespaceObject.mkdir((0, external_node_path_namespaceObject.dirname)(file), {
|
|
116
|
+
recursive: true
|
|
117
|
+
});
|
|
118
|
+
await promises_namespaceObject.writeFile(file, Buffer.from((0, external_screenshot_store_js_namespaceObject.parseBase64ImageDataUrl)(data).rawBase64, 'base64'));
|
|
119
|
+
this.files.add(target.path);
|
|
120
|
+
}
|
|
121
|
+
} else await promises_namespaceObject.appendFile(this.reportPath, `${(0, external_html_utils_js_namespaceObject.generateImageScriptTag)(ref.id, data)}\n`);
|
|
122
|
+
}
|
|
123
|
+
rewriteSync(serialized, sourcePath, origins) {
|
|
124
|
+
const refs = this.collect(serialized);
|
|
125
|
+
for (const ref of refs)if ('file' === ref.storage) {
|
|
126
|
+
const bytes = (0, external_node_fs_namespaceObject.readFileSync)((0, external_node_path_namespaceObject.resolve)((0, external_node_path_namespaceObject.dirname)(origins?.get(ref.id) ?? sourcePath), ref.path));
|
|
127
|
+
this.writeSync(ref, `data:${ref.mimeType};base64,${bytes.toString('base64')}`);
|
|
128
|
+
}
|
|
129
|
+
for (const [source, images] of this.inlineSources(refs, sourcePath, origins)){
|
|
130
|
+
(0, external_html_utils_js_namespaceObject.streamInlineReportImages)(source, (id, data)=>{
|
|
131
|
+
const ref = images.get(id);
|
|
132
|
+
if (ref) {
|
|
133
|
+
this.writeSync(ref, data);
|
|
134
|
+
images.delete(id);
|
|
104
135
|
}
|
|
105
|
-
|
|
136
|
+
return 0 === images.size;
|
|
137
|
+
});
|
|
138
|
+
if (images.size) throw new Error(`Missing report image ${images.keys().next().value} in ${source}`);
|
|
106
139
|
}
|
|
107
140
|
return this.rewrite(serialized);
|
|
108
141
|
}
|
|
109
|
-
async rewriteAsync(serialized, sourcePath) {
|
|
110
|
-
|
|
111
|
-
for (const ref of
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const target = this.reference(ref, data);
|
|
122
|
-
if ('file' === target.storage) {
|
|
123
|
-
if (!this.files.has(target.path)) {
|
|
124
|
-
const file = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), target.path);
|
|
125
|
-
await promises_namespaceObject.mkdir((0, external_node_path_namespaceObject.dirname)(file), {
|
|
126
|
-
recursive: true
|
|
127
|
-
});
|
|
128
|
-
await promises_namespaceObject.writeFile(file, Buffer.from((0, external_screenshot_store_js_namespaceObject.parseBase64ImageDataUrl)(data).rawBase64, 'base64'));
|
|
129
|
-
this.files.add(target.path);
|
|
142
|
+
async rewriteAsync(serialized, sourcePath, origins) {
|
|
143
|
+
const refs = this.collect(serialized);
|
|
144
|
+
for (const ref of refs)if ('file' === ref.storage) {
|
|
145
|
+
const bytes = await promises_namespaceObject.readFile((0, external_node_path_namespaceObject.resolve)((0, external_node_path_namespaceObject.dirname)(origins?.get(ref.id) ?? sourcePath), ref.path));
|
|
146
|
+
await this.write(ref, `data:${ref.mimeType};base64,${bytes.toString('base64')}`);
|
|
147
|
+
}
|
|
148
|
+
for (const [source, images] of this.inlineSources(refs, sourcePath, origins)){
|
|
149
|
+
for await (const { id, data } of (0, external_html_utils_js_namespaceObject.streamInlineReportImagesAsync)(source)){
|
|
150
|
+
const ref = images.get(id);
|
|
151
|
+
if (ref) {
|
|
152
|
+
await this.write(ref, data);
|
|
153
|
+
images.delete(id);
|
|
130
154
|
}
|
|
131
|
-
|
|
155
|
+
if (!images.size) break;
|
|
156
|
+
}
|
|
157
|
+
if (images.size) throw new Error(`Missing report image ${images.keys().next().value} in ${source}`);
|
|
132
158
|
}
|
|
133
159
|
return this.rewrite(serialized);
|
|
134
160
|
}
|