@midscene/core 1.12.10-beta-20260920031616.0 → 1.13.0
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.mjs +103 -6
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/index.mjs +4 -3
- package/dist/es/agent/tasks.mjs +2 -2
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/test-runner-nodes.mjs +291 -40
- package/dist/es/agent/test-runner-nodes.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/device/index.mjs +15 -2
- package/dist/es/device/index.mjs.map +1 -1
- package/dist/es/dump/html-utils.mjs +37 -4
- package/dist/es/dump/html-utils.mjs.map +1 -1
- package/dist/es/dump/screenshot-store.mjs +8 -1
- package/dist/es/dump/screenshot-store.mjs.map +1 -1
- package/dist/es/report-cli.mjs +9 -4
- package/dist/es/report-cli.mjs.map +1 -1
- package/dist/es/report-generator.mjs +117 -4
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/report.mjs +190 -41
- package/dist/es/report.mjs.map +1 -1
- package/dist/es/test-run-report.mjs.map +1 -1
- package/dist/es/test-runner/engine/case-runner.mjs +52 -0
- package/dist/es/test-runner/engine/case-runner.mjs.map +1 -0
- package/dist/es/test-runner/engine/document-runtime.mjs +273 -0
- package/dist/es/test-runner/engine/document-runtime.mjs.map +1 -0
- package/dist/es/test-runner/engine/execute-step.mjs +177 -0
- package/dist/es/test-runner/engine/execute-step.mjs.map +1 -0
- package/dist/es/test-runner/engine/execution-failure.mjs +39 -0
- package/dist/es/test-runner/engine/execution-failure.mjs.map +1 -0
- package/dist/es/test-runner/engine/index.mjs +12 -0
- package/dist/es/test-runner/engine/project-runtime.mjs +142 -0
- package/dist/es/test-runner/engine/project-runtime.mjs.map +1 -0
- package/dist/es/test-runner/engine/registry.mjs +61 -0
- package/dist/es/test-runner/engine/registry.mjs.map +1 -0
- package/dist/es/test-runner/engine/resource-operations.mjs +211 -0
- package/dist/es/test-runner/engine/resource-operations.mjs.map +1 -0
- package/dist/es/test-runner/engine/run-collected-case.mjs +193 -0
- package/dist/es/test-runner/engine/run-collected-case.mjs.map +1 -0
- package/dist/es/test-runner/engine/run-workflow-document.mjs +155 -0
- package/dist/es/test-runner/engine/run-workflow-document.mjs.map +1 -0
- package/dist/es/test-runner/engine/scheduler.mjs +27 -0
- package/dist/es/test-runner/engine/scheduler.mjs.map +1 -0
- package/dist/es/test-runner/engine/scope-teardown.mjs +16 -0
- package/dist/es/test-runner/engine/scope-teardown.mjs.map +1 -0
- package/dist/es/test-runner/engine/types.mjs +0 -0
- package/dist/es/test-runner/errors.mjs +201 -0
- package/dist/es/test-runner/errors.mjs.map +1 -0
- package/dist/es/test-runner/execution-record.mjs +83 -0
- package/dist/es/test-runner/execution-record.mjs.map +1 -0
- package/dist/es/test-runner/index.mjs +12 -0
- package/dist/es/test-runner/node/define-node.mjs +44 -0
- package/dist/es/test-runner/node/define-node.mjs.map +1 -0
- package/dist/es/test-runner/node/index.mjs +2 -0
- package/dist/es/test-runner/node/types.mjs +0 -0
- package/dist/es/test-runner/parser/document-format.mjs +21 -0
- package/dist/es/test-runner/parser/document-format.mjs.map +1 -0
- package/dist/es/test-runner/parser/normalize.mjs +87 -0
- package/dist/es/test-runner/parser/normalize.mjs.map +1 -0
- package/dist/es/test-runner/parser/types.mjs +0 -0
- package/dist/es/test-runner/project.mjs +0 -0
- package/dist/es/test-runner/reporting/agent-report.mjs +23 -0
- package/dist/es/test-runner/reporting/agent-report.mjs.map +1 -0
- package/dist/es/test-runner/reporting/execution-record.mjs +73 -0
- package/dist/es/test-runner/reporting/execution-record.mjs.map +1 -0
- package/dist/es/test-runner/reporting/merge-report.mjs +231 -0
- package/dist/es/test-runner/reporting/merge-report.mjs.map +1 -0
- package/dist/es/test-runner/reporting/sanitize.mjs +162 -0
- package/dist/es/test-runner/reporting/sanitize.mjs.map +1 -0
- package/dist/es/test-runner/reporting/test-run-report.mjs +327 -0
- package/dist/es/test-runner/reporting/test-run-report.mjs.map +1 -0
- package/dist/es/test-runner/reporting/types.mjs +0 -0
- package/dist/es/utils.mjs +1 -1
- package/dist/es/yaml/execution-context.node.mjs +6 -0
- package/dist/es/yaml/execution-context.node.mjs.map +1 -0
- package/dist/es/yaml/execution-context.stub.mjs +8 -0
- package/dist/es/yaml/execution-context.stub.mjs.map +1 -0
- package/dist/es/yaml/execution-session.mjs +90 -0
- package/dist/es/yaml/execution-session.mjs.map +1 -0
- package/dist/es/yaml/index.mjs +2 -1
- package/dist/es/yaml/legacy-yaml-execution-record.mjs +47 -0
- package/dist/es/yaml/legacy-yaml-execution-record.mjs.map +1 -0
- package/dist/es/yaml/legacy-yaml-report.mjs +52 -0
- package/dist/es/yaml/legacy-yaml-report.mjs.map +1 -0
- package/dist/es/yaml/legacy-yaml-runtime.mjs +119 -0
- package/dist/es/yaml/legacy-yaml-runtime.mjs.map +1 -0
- package/dist/es/yaml/player-state.mjs +15 -0
- package/dist/es/yaml/player-state.mjs.map +1 -0
- package/dist/es/yaml/player.mjs +214 -348
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/es/yaml/report-policy.mjs +7 -0
- package/dist/es/yaml/report-policy.mjs.map +1 -0
- package/dist/es/yaml/test-runner-compat.mjs +301 -0
- package/dist/es/yaml/test-runner-compat.mjs.map +1 -0
- package/dist/es/yaml/test-runner-nodes.mjs +147 -0
- package/dist/es/yaml/test-runner-nodes.mjs.map +1 -0
- package/dist/es/yaml/utils.mjs +12 -1
- package/dist/es/yaml/utils.mjs.map +1 -1
- package/dist/es/yaml-runtime.mjs +7 -0
- package/dist/es/yaml.mjs.map +1 -1
- package/dist/lib/agent/agent.js +103 -6
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/index.js +37 -3
- package/dist/lib/agent/tasks.js +2 -2
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/test-runner-nodes.js +329 -45
- package/dist/lib/agent/test-runner-nodes.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/device/index.js +15 -2
- package/dist/lib/device/index.js.map +1 -1
- package/dist/lib/dump/html-utils.js +43 -4
- package/dist/lib/dump/html-utils.js.map +1 -1
- package/dist/lib/dump/screenshot-store.js +8 -1
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/report-cli.js +8 -3
- package/dist/lib/report-cli.js.map +1 -1
- package/dist/lib/report-generator.js +114 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/report.js +187 -38
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/test-run-report.js.map +1 -1
- package/dist/lib/test-runner/engine/case-runner.js +89 -0
- package/dist/lib/test-runner/engine/case-runner.js.map +1 -0
- package/dist/lib/test-runner/engine/document-runtime.js +307 -0
- package/dist/lib/test-runner/engine/document-runtime.js.map +1 -0
- package/dist/lib/test-runner/engine/execute-step.js +211 -0
- package/dist/lib/test-runner/engine/execute-step.js.map +1 -0
- package/dist/lib/test-runner/engine/execution-failure.js +79 -0
- package/dist/lib/test-runner/engine/execution-failure.js.map +1 -0
- package/dist/lib/test-runner/engine/index.js +137 -0
- package/dist/lib/test-runner/engine/index.js.map +1 -0
- package/dist/lib/test-runner/engine/project-runtime.js +176 -0
- package/dist/lib/test-runner/engine/project-runtime.js.map +1 -0
- package/dist/lib/test-runner/engine/registry.js +95 -0
- package/dist/lib/test-runner/engine/registry.js.map +1 -0
- package/dist/lib/test-runner/engine/resource-operations.js +272 -0
- package/dist/lib/test-runner/engine/resource-operations.js.map +1 -0
- package/dist/lib/test-runner/engine/run-collected-case.js +227 -0
- package/dist/lib/test-runner/engine/run-collected-case.js.map +1 -0
- package/dist/lib/test-runner/engine/run-workflow-document.js +189 -0
- package/dist/lib/test-runner/engine/run-workflow-document.js.map +1 -0
- package/dist/lib/test-runner/engine/scheduler.js +64 -0
- package/dist/lib/test-runner/engine/scheduler.js.map +1 -0
- package/dist/lib/test-runner/engine/scope-teardown.js +50 -0
- package/dist/lib/test-runner/engine/scope-teardown.js.map +1 -0
- package/dist/lib/test-runner/engine/types.js +20 -0
- package/dist/lib/test-runner/engine/types.js.map +1 -0
- package/dist/lib/test-runner/errors.js +283 -0
- package/dist/lib/test-runner/errors.js.map +1 -0
- package/dist/lib/test-runner/execution-record.js +123 -0
- package/dist/lib/test-runner/execution-record.js.map +1 -0
- package/dist/lib/test-runner/index.js +137 -0
- package/dist/lib/test-runner/index.js.map +1 -0
- package/dist/lib/test-runner/node/define-node.js +78 -0
- package/dist/lib/test-runner/node/define-node.js.map +1 -0
- package/dist/lib/test-runner/node/index.js +67 -0
- package/dist/lib/test-runner/node/index.js.map +1 -0
- package/dist/lib/test-runner/node/types.js +20 -0
- package/dist/lib/test-runner/node/types.js.map +1 -0
- package/dist/lib/test-runner/parser/document-format.js +58 -0
- package/dist/lib/test-runner/parser/document-format.js.map +1 -0
- package/dist/lib/test-runner/parser/normalize.js +124 -0
- package/dist/lib/test-runner/parser/normalize.js.map +1 -0
- package/dist/lib/test-runner/parser/types.js +20 -0
- package/dist/lib/test-runner/parser/types.js.map +1 -0
- package/dist/lib/test-runner/project.js +20 -0
- package/dist/lib/test-runner/project.js.map +1 -0
- package/dist/lib/test-runner/reporting/agent-report.js +57 -0
- package/dist/lib/test-runner/reporting/agent-report.js.map +1 -0
- package/dist/lib/test-runner/reporting/execution-record.js +107 -0
- package/dist/lib/test-runner/reporting/execution-record.js.map +1 -0
- package/dist/lib/test-runner/reporting/merge-report.js +265 -0
- package/dist/lib/test-runner/reporting/merge-report.js.map +1 -0
- package/dist/lib/test-runner/reporting/sanitize.js +202 -0
- package/dist/lib/test-runner/reporting/sanitize.js.map +1 -0
- package/dist/lib/test-runner/reporting/test-run-report.js +364 -0
- package/dist/lib/test-runner/reporting/test-run-report.js.map +1 -0
- package/dist/lib/test-runner/reporting/types.js +20 -0
- package/dist/lib/test-runner/reporting/types.js.map +1 -0
- package/dist/lib/utils.js +1 -1
- package/dist/lib/yaml/execution-context.node.js +43 -0
- package/dist/lib/yaml/execution-context.node.js.map +1 -0
- package/dist/lib/yaml/execution-context.stub.js +45 -0
- package/dist/lib/yaml/execution-context.stub.js.map +1 -0
- package/dist/lib/yaml/execution-session.js +136 -0
- package/dist/lib/yaml/execution-session.js.map +1 -0
- package/dist/lib/yaml/index.js +49 -7
- package/dist/lib/yaml/legacy-yaml-execution-record.js +81 -0
- package/dist/lib/yaml/legacy-yaml-execution-record.js.map +1 -0
- package/dist/lib/yaml/legacy-yaml-report.js +86 -0
- package/dist/lib/yaml/legacy-yaml-report.js.map +1 -0
- package/dist/lib/yaml/legacy-yaml-runtime.js +156 -0
- package/dist/lib/yaml/legacy-yaml-runtime.js.map +1 -0
- package/dist/lib/yaml/player-state.js +52 -0
- package/dist/lib/yaml/player-state.js.map +1 -0
- package/dist/lib/yaml/player.js +213 -347
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/lib/yaml/report-policy.js +41 -0
- package/dist/lib/yaml/report-policy.js.map +1 -0
- package/dist/lib/yaml/test-runner-compat.js +344 -0
- package/dist/lib/yaml/test-runner-compat.js.map +1 -0
- package/dist/lib/yaml/test-runner-nodes.js +184 -0
- package/dist/lib/yaml/test-runner-nodes.js.map +1 -0
- package/dist/lib/yaml/utils.js +18 -1
- package/dist/lib/yaml/utils.js.map +1 -1
- package/dist/lib/yaml-runtime.js +67 -0
- package/dist/lib/yaml-runtime.js.map +1 -0
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent/agent.d.ts +14 -1
- package/dist/types/agent/agent.d.ts.map +1 -1
- package/dist/types/agent/index.d.ts +4 -3
- package/dist/types/agent/index.d.ts.map +1 -1
- package/dist/types/agent/tasks.d.ts +1 -1
- package/dist/types/agent/tasks.d.ts.map +1 -1
- package/dist/types/agent/test-runner-nodes.d.ts +226 -0
- package/dist/types/agent/test-runner-nodes.d.ts.map +1 -1
- package/dist/types/device/index.d.ts +1 -1
- package/dist/types/device/index.d.ts.map +1 -1
- package/dist/types/dump/html-utils.d.ts +4 -0
- package/dist/types/dump/html-utils.d.ts.map +1 -1
- package/dist/types/dump/screenshot-store.d.ts +2 -1
- package/dist/types/dump/screenshot-store.d.ts.map +1 -1
- package/dist/types/report-cli.d.ts.map +1 -1
- package/dist/types/report-generator.d.ts +10 -0
- package/dist/types/report-generator.d.ts.map +1 -1
- package/dist/types/report.d.ts +3 -1
- package/dist/types/report.d.ts.map +1 -1
- package/dist/types/test-run-report.d.ts +18 -2
- package/dist/types/test-run-report.d.ts.map +1 -1
- package/dist/types/test-runner/engine/case-runner.d.ts +13 -0
- package/dist/types/test-runner/engine/case-runner.d.ts.map +1 -0
- package/dist/types/test-runner/engine/document-runtime.d.ts +4 -0
- package/dist/types/test-runner/engine/document-runtime.d.ts.map +1 -0
- package/dist/types/test-runner/engine/execute-step.d.ts +17 -0
- package/dist/types/test-runner/engine/execute-step.d.ts.map +1 -0
- package/dist/types/test-runner/engine/execution-failure.d.ts +13 -0
- package/dist/types/test-runner/engine/execution-failure.d.ts.map +1 -0
- package/dist/types/test-runner/engine/index.d.ts +13 -0
- package/dist/types/test-runner/engine/index.d.ts.map +1 -0
- package/dist/types/test-runner/engine/project-runtime.d.ts +3 -0
- package/dist/types/test-runner/engine/project-runtime.d.ts.map +1 -0
- package/dist/types/test-runner/engine/registry.d.ts +12 -0
- package/dist/types/test-runner/engine/registry.d.ts.map +1 -0
- package/dist/types/test-runner/engine/resource-operations.d.ts +32 -0
- package/dist/types/test-runner/engine/resource-operations.d.ts.map +1 -0
- package/dist/types/test-runner/engine/run-collected-case.d.ts +4 -0
- package/dist/types/test-runner/engine/run-collected-case.d.ts.map +1 -0
- package/dist/types/test-runner/engine/run-workflow-document.d.ts +4 -0
- package/dist/types/test-runner/engine/run-workflow-document.d.ts.map +1 -0
- package/dist/types/test-runner/engine/scheduler.d.ts +12 -0
- package/dist/types/test-runner/engine/scheduler.d.ts.map +1 -0
- package/dist/types/test-runner/engine/scope-teardown.d.ts +3 -0
- package/dist/types/test-runner/engine/scope-teardown.d.ts.map +1 -0
- package/dist/types/test-runner/engine/types.d.ts +226 -0
- package/dist/types/test-runner/engine/types.d.ts.map +1 -0
- package/dist/types/test-runner/errors.d.ts +79 -0
- package/dist/types/test-runner/errors.d.ts.map +1 -0
- package/dist/types/test-runner/execution-record.d.ts +43 -0
- package/dist/types/test-runner/execution-record.d.ts.map +1 -0
- package/dist/types/test-runner/index.d.ts +20 -0
- package/dist/types/test-runner/index.d.ts.map +1 -0
- package/dist/types/test-runner/node/define-node.d.ts +4 -0
- package/dist/types/test-runner/node/define-node.d.ts.map +1 -0
- package/dist/types/test-runner/node/index.d.ts +3 -0
- package/dist/types/test-runner/node/index.d.ts.map +1 -0
- package/dist/types/test-runner/node/types.d.ts +66 -0
- package/dist/types/test-runner/node/types.d.ts.map +1 -0
- package/dist/types/test-runner/parser/document-format.d.ts +8 -0
- package/dist/types/test-runner/parser/document-format.d.ts.map +1 -0
- package/dist/types/test-runner/parser/normalize.d.ts +9 -0
- package/dist/types/test-runner/parser/normalize.d.ts.map +1 -0
- package/dist/types/test-runner/parser/types.d.ts +69 -0
- package/dist/types/test-runner/parser/types.d.ts.map +1 -0
- package/dist/types/test-runner/project.d.ts +75 -0
- package/dist/types/test-runner/project.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/agent-report.d.ts +9 -0
- package/dist/types/test-runner/reporting/agent-report.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/execution-record.d.ts +9 -0
- package/dist/types/test-runner/reporting/execution-record.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/merge-report.d.ts +15 -0
- package/dist/types/test-runner/reporting/merge-report.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/sanitize.d.ts +6 -0
- package/dist/types/test-runner/reporting/sanitize.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/test-run-report.d.ts +5 -0
- package/dist/types/test-runner/reporting/test-run-report.d.ts.map +1 -0
- package/dist/types/test-runner/reporting/types.d.ts +34 -0
- package/dist/types/test-runner/reporting/types.d.ts.map +1 -0
- package/dist/types/yaml/execution-context.node.d.ts +4 -0
- package/dist/types/yaml/execution-context.node.d.ts.map +1 -0
- package/dist/types/yaml/execution-context.stub.d.ts +6 -0
- package/dist/types/yaml/execution-context.stub.d.ts.map +1 -0
- package/dist/types/yaml/execution-session.d.ts +17 -0
- package/dist/types/yaml/execution-session.d.ts.map +1 -0
- package/dist/types/yaml/index.d.ts +1 -1
- package/dist/types/yaml/index.d.ts.map +1 -1
- package/dist/types/yaml/legacy-yaml-execution-record.d.ts +24 -0
- package/dist/types/yaml/legacy-yaml-execution-record.d.ts.map +1 -0
- package/dist/types/yaml/legacy-yaml-report.d.ts +19 -0
- package/dist/types/yaml/legacy-yaml-report.d.ts.map +1 -0
- package/dist/types/yaml/legacy-yaml-runtime.d.ts +23 -0
- package/dist/types/yaml/legacy-yaml-runtime.d.ts.map +1 -0
- package/dist/types/yaml/player-state.d.ts +11 -0
- package/dist/types/yaml/player-state.d.ts.map +1 -0
- package/dist/types/yaml/player.d.ts +11 -3
- package/dist/types/yaml/player.d.ts.map +1 -1
- package/dist/types/yaml/report-policy.d.ts +4 -0
- package/dist/types/yaml/report-policy.d.ts.map +1 -0
- package/dist/types/yaml/test-runner-compat.d.ts +17 -0
- package/dist/types/yaml/test-runner-compat.d.ts.map +1 -0
- package/dist/types/yaml/test-runner-nodes.d.ts +6 -0
- package/dist/types/yaml/test-runner-nodes.d.ts.map +1 -0
- package/dist/types/yaml/utils.d.ts +9 -0
- package/dist/types/yaml/utils.d.ts.map +1 -1
- package/dist/types/yaml-runtime.d.ts +13 -0
- package/dist/types/yaml-runtime.d.ts.map +1 -0
- package/dist/types/yaml.d.ts +25 -7
- package/dist/types/yaml.d.ts.map +1 -1
- package/package.json +28 -2
package/dist/es/report.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { appendFileSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readdirSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { appendFileSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { copyFile, cp, mkdir, mkdtemp, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
4
|
import { getMidsceneRunSubDir } from "@midscene/shared/common";
|
|
4
|
-
import { antiEscapeScriptTag,
|
|
5
|
+
import { antiEscapeScriptTag, logMsg, uuid } from "@midscene/shared/utils";
|
|
5
6
|
import { getReportFileName } from "./agent/report-file-name.mjs";
|
|
6
|
-
import { DATA_SCREENSHOT_MODE_ATTR, extractAllDumpScriptsSync, extractLastDumpScriptSync, generateAgentReportComment, getBaseUrlFixScript, streamDumpScriptsSync, streamImageScriptsToFile } from "./dump/html-utils.mjs";
|
|
7
|
+
import { DATA_SCREENSHOT_MODE_ATTR, extractAllDumpScriptsSync, extractLastDumpScriptSync, extractTestRunReportDumpSync, generateAgentReportComment, generateTestRunReportScriptTag, getBaseUrlFixScript, streamDumpScriptsSync, streamImageScriptsToFile } from "./dump/html-utils.mjs";
|
|
7
8
|
import { imageRefFileExtension, normalizeStoredImageRef } from "./dump/image-reference.mjs";
|
|
8
9
|
import { parseBase64ImageDataUrl, resolveImageSource } from "./dump/screenshot-store.mjs";
|
|
9
10
|
import { collectReportSummary } from "./report-stats.mjs";
|
|
10
|
-
import {
|
|
11
|
+
import { mergeTestRunReportDumps } from "./test-runner/reporting/merge-report.mjs";
|
|
11
12
|
import { ReportActionDump } from "./types.mjs";
|
|
12
13
|
import { getReportTpl, getVersion, reportHTMLContent } from "./utils.mjs";
|
|
13
14
|
function _define_property(obj, key, value) {
|
|
@@ -88,7 +89,7 @@ function mergedAgentReportComment(reports) {
|
|
|
88
89
|
groupDescription: 'Agent-readable summary for merged report HTML',
|
|
89
90
|
modelBriefs: reports.flatMap((report)=>report.modelBriefs ?? []),
|
|
90
91
|
deviceType: 1 === deviceTypes.length ? deviceTypes[0] : 'mixed',
|
|
91
|
-
executions: reports.flatMap((report)=>report.executions ?? [])
|
|
92
|
+
executions: dedupeExecutionsKeepLatest(reports.flatMap((report)=>report.executions ?? []))
|
|
92
93
|
});
|
|
93
94
|
return generateAgentReportComment(mergedReport);
|
|
94
95
|
}
|
|
@@ -138,6 +139,8 @@ class ReportMergingTool {
|
|
|
138
139
|
logMsg('No reports to merge');
|
|
139
140
|
return null;
|
|
140
141
|
}
|
|
142
|
+
const runnerDumps = this.reportInfos.map((info)=>info.reportFilePath ? extractTestRunReportDumpSync(info.reportFilePath) : void 0);
|
|
143
|
+
const hasRunnerDump = runnerDumps.some(Boolean);
|
|
141
144
|
const targetDir = outputDir ? resolve(outputDir) : getMidsceneRunSubDir('report');
|
|
142
145
|
if (outputDir) mkdirSync(targetDir, {
|
|
143
146
|
recursive: true
|
|
@@ -166,6 +169,7 @@ class ReportMergingTool {
|
|
|
166
169
|
appendFileSync(outputFilePath, tplWithoutClose);
|
|
167
170
|
if (hasDirectoryModeReport) appendFileSync(outputFilePath, getBaseUrlFixScript());
|
|
168
171
|
const agentReports = [];
|
|
172
|
+
const runnerSources = [];
|
|
169
173
|
const writtenInlineImageIds = new Set();
|
|
170
174
|
for(let i = 0; i < this.reportInfos.length; i++){
|
|
171
175
|
const reportInfo = this.reportInfos[i];
|
|
@@ -191,16 +195,26 @@ class ReportMergingTool {
|
|
|
191
195
|
} else streamImageScriptsToFile(reportInfo.reportFilePath, outputFilePath, writtenInlineImageIds);
|
|
192
196
|
const allDumps = extractAllDumpScriptsSync(reportInfo.reportFilePath).filter((d)=>d.openTag.includes('data-group-id'));
|
|
193
197
|
const groupIdMatch = allDumps[0]?.openTag.match(/data-group-id="([^"]+)"/);
|
|
194
|
-
if (groupIdMatch) mergedGroupId = decodeURIComponent(groupIdMatch[1]);
|
|
198
|
+
if (groupIdMatch && !hasRunnerDump) mergedGroupId = decodeURIComponent(groupIdMatch[1]);
|
|
195
199
|
const extractedDumpString = allDumps.length > 0 ? this.mergeDumpScripts(allDumps.map((d)=>d.content)) : extractLastDumpScriptSync(reportInfo.reportFilePath);
|
|
196
200
|
if (extractedDumpString) dumpString = extractedDumpString;
|
|
197
201
|
}
|
|
198
202
|
const agentReport = tryParseAgentReportDump(dumpString);
|
|
199
203
|
if (agentReport) agentReports.push(agentReport);
|
|
204
|
+
if (hasRunnerDump) runnerSources.push({
|
|
205
|
+
reportId: mergedGroupId,
|
|
206
|
+
sourcePath: reportInfo.reportFilePath ?? '<skipped-agent-report>',
|
|
207
|
+
attributes: reportAttributes,
|
|
208
|
+
dump: runnerDumps[i],
|
|
209
|
+
timing: agentReport ? agentReportTiming(agentReport, reportAttributes.testDuration) : void 0
|
|
210
|
+
});
|
|
200
211
|
const reportHtmlStr = `${reportHTMLContent({
|
|
201
212
|
dumpString,
|
|
202
213
|
attributes: {
|
|
203
214
|
'data-group-id': mergedGroupId,
|
|
215
|
+
...hasRunnerDump ? {
|
|
216
|
+
'data-report-id': mergedGroupId
|
|
217
|
+
} : {},
|
|
204
218
|
[DATA_SCREENSHOT_MODE_ATTR]: hasDirectoryModeReport ? 'directory' : 'inline',
|
|
205
219
|
playwright_test_duration: reportAttributes.testDuration,
|
|
206
220
|
playwright_test_status: reportAttributes.testStatus,
|
|
@@ -212,6 +226,16 @@ class ReportMergingTool {
|
|
|
212
226
|
}, void 0, void 0, false)}\n`;
|
|
213
227
|
appendFileSync(outputFilePath, reportHtmlStr);
|
|
214
228
|
}
|
|
229
|
+
if (hasRunnerDump) {
|
|
230
|
+
const summary = collectReportSummary({
|
|
231
|
+
executions: dedupeExecutionsKeepLatest(agentReports.flatMap((report)=>report.executions))
|
|
232
|
+
});
|
|
233
|
+
appendFileSync(outputFilePath, generateTestRunReportScriptTag(mergeTestRunReportDumps(runnerSources, {
|
|
234
|
+
modelCallCount: summary.timing.modelCallCount,
|
|
235
|
+
modelTimeMs: summary.timing.modelCallTimeMs,
|
|
236
|
+
...summary.tokens
|
|
237
|
+
}, uuid())));
|
|
238
|
+
}
|
|
215
239
|
const agentComment = mergedAgentReportComment(agentReports);
|
|
216
240
|
if (agentComment) appendFileSync(outputFilePath, agentComment);
|
|
217
241
|
appendFileSync(outputFilePath, `${htmlEndTag}\n`);
|
|
@@ -240,28 +264,29 @@ class ReportMergingTool {
|
|
|
240
264
|
_define_property(this, "reportInfos", []);
|
|
241
265
|
}
|
|
242
266
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
267
|
+
function agentReportTiming(report, durationMs) {
|
|
268
|
+
const timing = collectReportSummary(report).timing;
|
|
269
|
+
const executionTimes = report.executions.map((execution)=>execution.logTime).filter((value)=>'number' == typeof value && Number.isFinite(value));
|
|
270
|
+
const started = timing.wallTimeStart ?? (executionTimes.length ? Math.min(...executionTimes) : void 0);
|
|
271
|
+
if (void 0 === started) return;
|
|
272
|
+
const ended = timing.wallTimeEnd ?? Math.max(...executionTimes, started + (Number.isFinite(durationMs) ? Math.max(0, durationMs) : 0));
|
|
273
|
+
return {
|
|
274
|
+
startedAt: new Date(started).toISOString(),
|
|
275
|
+
endedAt: new Date(ended).toISOString(),
|
|
276
|
+
durationMs: Math.max(0, ended - started)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
251
279
|
const validateTestRunReportFileName = (fileName)=>{
|
|
252
280
|
if (!fileName || '.' === fileName || '..' === fileName || basename(fileName) !== fileName || fileName.endsWith('.html')) throw new Error(`Midscene Test reportFileName must be one path segment without an extension: ${fileName}`);
|
|
253
281
|
};
|
|
254
282
|
const uniqueTestRunReportSources = (sources)=>{
|
|
255
283
|
const unique = new Map();
|
|
256
|
-
const scopeBySourcePath = new Map();
|
|
257
284
|
for (const source of sources){
|
|
258
285
|
const scopeId = source.scopeId.trim();
|
|
259
286
|
const sourcePath = resolve(source.sourcePath);
|
|
260
287
|
if (!scopeId) throw new Error('Midscene Test report source scopeId must not be empty.');
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
scopeBySourcePath.set(sourcePath, scopeId);
|
|
264
|
-
unique.set(`${scopeId}\u0000${sourcePath}`, {
|
|
288
|
+
unique.set(`${scopeId}\u0000${source.dumpPath ?? sourcePath}`, {
|
|
289
|
+
...source,
|
|
265
290
|
scopeId,
|
|
266
291
|
sourcePath
|
|
267
292
|
});
|
|
@@ -270,20 +295,49 @@ const uniqueTestRunReportSources = (sources)=>{
|
|
|
270
295
|
...unique.values()
|
|
271
296
|
];
|
|
272
297
|
};
|
|
273
|
-
const prepareTestRunReportSources = (sources)=>{
|
|
298
|
+
const prepareTestRunReportSources = (sources, loadedDumps)=>{
|
|
274
299
|
const prepared = [];
|
|
275
|
-
const metrics = emptyTestRunReportMetrics();
|
|
276
300
|
const ownerByScopedExecution = new Map();
|
|
301
|
+
const preparedByPath = new Map();
|
|
277
302
|
for (const [sourceIndex, source] of uniqueTestRunReportSources(sources).entries()){
|
|
278
|
-
|
|
279
|
-
const
|
|
303
|
+
const sourceKey = source.sourcePath;
|
|
304
|
+
const shared = preparedByPath.get(sourceKey);
|
|
305
|
+
if (shared) {
|
|
306
|
+
if (source.dumpPath) {
|
|
307
|
+
const snapshot = ReportActionDump.fromSerializedString(loadedDumps?.get(source.dumpPath) ?? readFileSync(source.dumpPath, 'utf8'));
|
|
308
|
+
shared.dump.executions = dedupeExecutionsKeepLatest([
|
|
309
|
+
...shared.dump.executions,
|
|
310
|
+
...snapshot.executions
|
|
311
|
+
]);
|
|
312
|
+
shared.executionIds.splice(0, shared.executionIds.length, ...shared.dump.executions.flatMap((execution)=>execution.id ? [
|
|
313
|
+
execution.id
|
|
314
|
+
] : []));
|
|
315
|
+
}
|
|
316
|
+
for (const executionId of shared.executionIds){
|
|
317
|
+
const key = `${source.scopeId}\u0000${executionId}`;
|
|
318
|
+
const owner = ownerByScopedExecution.get(key);
|
|
319
|
+
if (owner && owner !== shared.reportId) throw new Error(`Agent execution ${executionId} is present in multiple reports for test scope ${source.scopeId}: ${owner}, ${shared.reportId}`);
|
|
320
|
+
ownerByScopedExecution.set(key, shared.reportId);
|
|
321
|
+
}
|
|
322
|
+
prepared.push({
|
|
323
|
+
...shared,
|
|
324
|
+
scopeId: source.scopeId
|
|
325
|
+
});
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (!source.dumpPath && !existsSync(source.sourcePath)) throw new Error(`Agent report does not exist: ${source.sourcePath}`);
|
|
329
|
+
const sourceVersion = source.dumpPath ? void 0 : peekReportSdkVersion(source.sourcePath);
|
|
280
330
|
const currentVersion = getVersion();
|
|
281
331
|
if (sourceVersion && currentVersion && sourceVersion !== currentVersion && !warnedMismatchedVersions.has(sourceVersion)) {
|
|
282
332
|
warnedMismatchedVersions.add(sourceVersion);
|
|
283
333
|
logMsg(`[@midscene/core] TestRunReportAssembler version mismatch: source report was written by @midscene/core@${sourceVersion} but the assembler is @midscene/core@${currentVersion}. Align the workspace package versions before generating the Midscene Test report.`);
|
|
284
334
|
}
|
|
285
335
|
const reportId = `runner-report-${sourceIndex + 1}`;
|
|
286
|
-
const
|
|
336
|
+
const snapshot = source.dumpPath ? ReportActionDump.fromSerializedString(loadedDumps?.get(source.dumpPath) ?? readFileSync(source.dumpPath, 'utf8')) : void 0;
|
|
337
|
+
const { baseDump, executions } = snapshot ? {
|
|
338
|
+
baseDump: snapshot,
|
|
339
|
+
executions: snapshot.executions
|
|
340
|
+
} : collectDedupedExecutions(source.sourcePath);
|
|
287
341
|
const executionIds = [];
|
|
288
342
|
for (const execution of executions){
|
|
289
343
|
if (!execution.id) continue;
|
|
@@ -301,32 +355,124 @@ const prepareTestRunReportSources = (sources)=>{
|
|
|
301
355
|
deviceType: baseDump.deviceType,
|
|
302
356
|
executions
|
|
303
357
|
});
|
|
304
|
-
const
|
|
305
|
-
metrics.modelCallCount += sourceMetrics.timing.modelCallCount;
|
|
306
|
-
metrics.modelTimeMs += sourceMetrics.timing.modelCallTimeMs;
|
|
307
|
-
metrics.promptTokens += sourceMetrics.tokens.promptTokens;
|
|
308
|
-
metrics.cachedInputTokens += sourceMetrics.tokens.cachedInputTokens;
|
|
309
|
-
metrics.completionTokens += sourceMetrics.tokens.completionTokens;
|
|
310
|
-
metrics.totalTokens += sourceMetrics.tokens.totalTokens;
|
|
311
|
-
prepared.push({
|
|
358
|
+
const preparedSource = {
|
|
312
359
|
reportId,
|
|
313
360
|
scopeId: source.scopeId,
|
|
314
361
|
sourcePath: source.sourcePath,
|
|
315
362
|
executionIds,
|
|
316
363
|
dump,
|
|
317
|
-
directoryMode: isDirectoryModeReport(source.sourcePath)
|
|
318
|
-
|
|
364
|
+
directoryMode: !!source.dumpPath || isDirectoryModeReport(source.sourcePath),
|
|
365
|
+
...source.dumpPath ? {
|
|
366
|
+
dumpPath: source.dumpPath
|
|
367
|
+
} : {}
|
|
368
|
+
};
|
|
369
|
+
prepared.push(preparedSource);
|
|
370
|
+
preparedByPath.set(sourceKey, preparedSource);
|
|
319
371
|
}
|
|
372
|
+
const summary = collectReportSummary({
|
|
373
|
+
executions: dedupeExecutionsKeepLatest([
|
|
374
|
+
...preparedByPath.values()
|
|
375
|
+
].flatMap((source)=>source.dump.executions))
|
|
376
|
+
});
|
|
320
377
|
return {
|
|
321
378
|
sources: prepared,
|
|
322
|
-
metrics
|
|
379
|
+
metrics: {
|
|
380
|
+
modelCallCount: summary.timing.modelCallCount,
|
|
381
|
+
modelTimeMs: summary.timing.modelCallTimeMs,
|
|
382
|
+
...summary.tokens
|
|
383
|
+
}
|
|
323
384
|
};
|
|
324
385
|
};
|
|
325
|
-
const runnerDumpScript = (dump)=>{
|
|
326
|
-
const closeTag = "<\/script>";
|
|
327
|
-
return '<script type="' + TEST_RUN_REPORT_SCRIPT_TYPE + '">\n' + escapeScriptTag(JSON.stringify(dump)) + '\n' + closeTag + '\n';
|
|
328
|
-
};
|
|
329
386
|
class TestRunReportAssembler {
|
|
387
|
+
async assembleAsync(options) {
|
|
388
|
+
validateTestRunReportFileName(options.reportFileName);
|
|
389
|
+
const loaded = new Map();
|
|
390
|
+
await Promise.all(options.sources.map(async (source)=>{
|
|
391
|
+
if (source.dumpPath) loaded.set(source.dumpPath, await readFile(source.dumpPath, 'utf8'));
|
|
392
|
+
}));
|
|
393
|
+
const prepared = prepareTestRunReportSources(options.sources, loaded);
|
|
394
|
+
const dump = options.buildRunnerDump({
|
|
395
|
+
sources: prepared.sources,
|
|
396
|
+
metrics: prepared.metrics
|
|
397
|
+
});
|
|
398
|
+
if ('test-runner' !== dump.kind || 1 !== dump.schemaVersion) throw new Error('Invalid Runner report dump');
|
|
399
|
+
const directoryMode = prepared.sources.some((source)=>source.directoryMode);
|
|
400
|
+
const outputDir = resolve(options.outputDir);
|
|
401
|
+
await mkdir(outputDir, {
|
|
402
|
+
recursive: true
|
|
403
|
+
});
|
|
404
|
+
const artifact = join(outputDir, options.reportFileName);
|
|
405
|
+
const finalPath = directoryMode ? join(artifact, 'index.html') : `${artifact}.html`;
|
|
406
|
+
if (!options.overwrite && (existsSync(artifact) || existsSync(`${artifact}.html`))) throw new Error(`Report artifact already exists: ${artifact}`);
|
|
407
|
+
const temporary = await mkdtemp(join(outputDir, '.test-run-report-'));
|
|
408
|
+
const htmlPath = join(temporary, 'index.html');
|
|
409
|
+
try {
|
|
410
|
+
const parts = [
|
|
411
|
+
getReportTpl(),
|
|
412
|
+
directoryMode ? getBaseUrlFixScript() : ''
|
|
413
|
+
];
|
|
414
|
+
const imageIds = new Set();
|
|
415
|
+
const reports = [];
|
|
416
|
+
for (const source of new Map(prepared.sources.map((source)=>[
|
|
417
|
+
source.reportId,
|
|
418
|
+
source
|
|
419
|
+
])).values()){
|
|
420
|
+
const serialized = source.dump.serialize();
|
|
421
|
+
if (source.dumpPath) {
|
|
422
|
+
const refs = new Map();
|
|
423
|
+
JSON.parse(serialized, (_key, value)=>{
|
|
424
|
+
const ref = normalizeStoredImageRef(value);
|
|
425
|
+
if (ref) refs.set(ref.id, ref);
|
|
426
|
+
return value;
|
|
427
|
+
});
|
|
428
|
+
if (refs.size) await mkdir(join(temporary, 'screenshots'), {
|
|
429
|
+
recursive: true
|
|
430
|
+
});
|
|
431
|
+
for (const ref of refs.values())if (!imageIds.has(ref.id)) {
|
|
432
|
+
if ('file' !== ref.storage || !ref.path) throw new Error(`Snapshot image ${ref.id} has no file source`);
|
|
433
|
+
await copyFile(resolve(dirname(source.dumpPath), ref.path), join(temporary, 'screenshots', `${ref.id}.${imageRefFileExtension(ref)}`));
|
|
434
|
+
imageIds.add(ref.id);
|
|
435
|
+
}
|
|
436
|
+
} else if (source.directoryMode) {
|
|
437
|
+
const images = join(dirname(source.sourcePath), 'screenshots');
|
|
438
|
+
if (existsSync(images)) await cp(images, join(temporary, 'screenshots'), {
|
|
439
|
+
recursive: true
|
|
440
|
+
});
|
|
441
|
+
} else {
|
|
442
|
+
const html = await readFile(source.sourcePath, 'utf8');
|
|
443
|
+
for (const match of html.matchAll(/<script\b([^>]*)>[\s\S]*?<\/script>/g))if (/(?:^|\s)type=["']midscene-image["']/.test(match[1])) parts.push(match[0]);
|
|
444
|
+
}
|
|
445
|
+
reports.push(source.dump);
|
|
446
|
+
parts.push(reportHTMLContent({
|
|
447
|
+
dumpString: serialized,
|
|
448
|
+
attributes: {
|
|
449
|
+
'data-group-id': source.reportId,
|
|
450
|
+
'data-report-id': source.reportId,
|
|
451
|
+
'data-runner-scope-id': source.scopeId,
|
|
452
|
+
[DATA_SCREENSHOT_MODE_ATTR]: directoryMode ? 'directory' : 'inline'
|
|
453
|
+
}
|
|
454
|
+
}, void 0, void 0, false));
|
|
455
|
+
}
|
|
456
|
+
parts.push(generateTestRunReportScriptTag(dump), mergedAgentReportComment(reports));
|
|
457
|
+
await writeFile(htmlPath, parts.join('\n'));
|
|
458
|
+
if (options.overwrite) {
|
|
459
|
+
await rm(artifact, {
|
|
460
|
+
recursive: true,
|
|
461
|
+
force: true
|
|
462
|
+
});
|
|
463
|
+
await rm(`${artifact}.html`, {
|
|
464
|
+
force: true
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
await rename(directoryMode ? temporary : htmlPath, directoryMode ? artifact : finalPath);
|
|
468
|
+
return finalPath;
|
|
469
|
+
} finally{
|
|
470
|
+
await rm(temporary, {
|
|
471
|
+
recursive: true,
|
|
472
|
+
force: true
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
330
476
|
assemble(options) {
|
|
331
477
|
validateTestRunReportFileName(options.reportFileName);
|
|
332
478
|
const outputDir = resolve(options.outputDir);
|
|
@@ -369,7 +515,10 @@ class TestRunReportAssembler {
|
|
|
369
515
|
appendFileSync(temporaryReportPath, -1 === htmlEndIndex ? template : template.slice(0, htmlEndIndex));
|
|
370
516
|
if (directoryMode) appendFileSync(temporaryReportPath, getBaseUrlFixScript());
|
|
371
517
|
const agentReports = [];
|
|
372
|
-
for (const source of prepared.sources)
|
|
518
|
+
for (const source of new Map(prepared.sources.map((source)=>[
|
|
519
|
+
source.reportId,
|
|
520
|
+
source
|
|
521
|
+
])).values()){
|
|
373
522
|
if (source.directoryMode) {
|
|
374
523
|
const screenshotsDir = join(dirname(source.sourcePath), 'screenshots');
|
|
375
524
|
if (existsSync(screenshotsDir)) {
|
|
@@ -391,7 +540,7 @@ class TestRunReportAssembler {
|
|
|
391
540
|
}
|
|
392
541
|
}, void 0, void 0, false)}\n`);
|
|
393
542
|
}
|
|
394
|
-
appendFileSync(temporaryReportPath,
|
|
543
|
+
appendFileSync(temporaryReportPath, generateTestRunReportScriptTag(runnerDump));
|
|
395
544
|
const agentComment = mergedAgentReportComment(agentReports);
|
|
396
545
|
if (agentComment) appendFileSync(temporaryReportPath, agentComment);
|
|
397
546
|
appendFileSync(temporaryReportPath, `${htmlEndTag}\n`);
|