@stablyai/internal-playwright 0.1.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.
Files changed (297) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +168 -0
  4. package/ThirdPartyNotices.txt +6277 -0
  5. package/cli.js +19 -0
  6. package/index.d.ts +17 -0
  7. package/index.js +17 -0
  8. package/index.mjs +18 -0
  9. package/jsx-runtime.js +42 -0
  10. package/jsx-runtime.mjs +21 -0
  11. package/lib/agents/generateAgents.js +265 -0
  12. package/lib/agents/generator.md +102 -0
  13. package/lib/agents/healer.md +78 -0
  14. package/lib/agents/planner.md +135 -0
  15. package/lib/cli.js +274 -0
  16. package/lib/common/config.js +274 -0
  17. package/lib/common/config.js.map +7 -0
  18. package/lib/common/configLoader.js +377 -0
  19. package/lib/common/configLoader.js.map +7 -0
  20. package/lib/common/esmLoaderHost.js +102 -0
  21. package/lib/common/esmLoaderHost.js.map +7 -0
  22. package/lib/common/expectBundle.js +52 -0
  23. package/lib/common/expectBundle.js.map +7 -0
  24. package/lib/common/expectBundleImpl.js +389 -0
  25. package/lib/common/expectBundleImpl.js.map +7 -0
  26. package/lib/common/fixtures.js +302 -0
  27. package/lib/common/fixtures.js.map +7 -0
  28. package/lib/common/globals.js +58 -0
  29. package/lib/common/globals.js.map +7 -0
  30. package/lib/common/ipc.js +60 -0
  31. package/lib/common/ipc.js.map +7 -0
  32. package/lib/common/poolBuilder.js +85 -0
  33. package/lib/common/poolBuilder.js.map +7 -0
  34. package/lib/common/process.js +104 -0
  35. package/lib/common/process.js.map +7 -0
  36. package/lib/common/suiteUtils.js +140 -0
  37. package/lib/common/suiteUtils.js.map +7 -0
  38. package/lib/common/test.js +321 -0
  39. package/lib/common/test.js.map +7 -0
  40. package/lib/common/testLoader.js +100 -0
  41. package/lib/common/testLoader.js.map +7 -0
  42. package/lib/common/testType.js +310 -0
  43. package/lib/common/testType.js.map +7 -0
  44. package/lib/fsWatcher.js +67 -0
  45. package/lib/fsWatcher.js.map +7 -0
  46. package/lib/index.js +696 -0
  47. package/lib/index.js.map +7 -0
  48. package/lib/internalsForTest.js +42 -0
  49. package/lib/internalsForTest.js.map +7 -0
  50. package/lib/isomorphic/events.js +77 -0
  51. package/lib/isomorphic/events.js.map +7 -0
  52. package/lib/isomorphic/folders.js +30 -0
  53. package/lib/isomorphic/folders.js.map +7 -0
  54. package/lib/isomorphic/stringInternPool.js +69 -0
  55. package/lib/isomorphic/stringInternPool.js.map +7 -0
  56. package/lib/isomorphic/teleReceiver.js +507 -0
  57. package/lib/isomorphic/teleReceiver.js.map +7 -0
  58. package/lib/isomorphic/teleSuiteUpdater.js +137 -0
  59. package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
  60. package/lib/isomorphic/testServerConnection.js +211 -0
  61. package/lib/isomorphic/testServerConnection.js.map +7 -0
  62. package/lib/isomorphic/testServerInterface.js +16 -0
  63. package/lib/isomorphic/testServerInterface.js.map +7 -0
  64. package/lib/isomorphic/testTree.js +334 -0
  65. package/lib/isomorphic/testTree.js.map +7 -0
  66. package/lib/isomorphic/types.d.js +16 -0
  67. package/lib/isomorphic/types.d.js.map +7 -0
  68. package/lib/loader/loaderMain.js +59 -0
  69. package/lib/loader/loaderMain.js.map +7 -0
  70. package/lib/matchers/expect.js +325 -0
  71. package/lib/matchers/expect.js.map +7 -0
  72. package/lib/matchers/matcherHint.js +87 -0
  73. package/lib/matchers/matcherHint.js.map +7 -0
  74. package/lib/matchers/matchers.js +366 -0
  75. package/lib/matchers/matchers.js.map +7 -0
  76. package/lib/matchers/toBeTruthy.js +73 -0
  77. package/lib/matchers/toBeTruthy.js.map +7 -0
  78. package/lib/matchers/toEqual.js +99 -0
  79. package/lib/matchers/toEqual.js.map +7 -0
  80. package/lib/matchers/toHaveURL.js +102 -0
  81. package/lib/matchers/toHaveURL.js.map +7 -0
  82. package/lib/matchers/toMatchAriaSnapshot.js +159 -0
  83. package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
  84. package/lib/matchers/toMatchSnapshot.js +359 -0
  85. package/lib/matchers/toMatchSnapshot.js.map +7 -0
  86. package/lib/matchers/toMatchText.js +99 -0
  87. package/lib/matchers/toMatchText.js.map +7 -0
  88. package/lib/mcp/browser/actions.d.js +16 -0
  89. package/lib/mcp/browser/backend.js +93 -0
  90. package/lib/mcp/browser/backend.js.map +7 -0
  91. package/lib/mcp/browser/browserContextFactory.js +296 -0
  92. package/lib/mcp/browser/browserServerBackend.js +76 -0
  93. package/lib/mcp/browser/codegen.js +66 -0
  94. package/lib/mcp/browser/config.js +385 -0
  95. package/lib/mcp/browser/context.js +287 -0
  96. package/lib/mcp/browser/response.js +228 -0
  97. package/lib/mcp/browser/sessionLog.js +160 -0
  98. package/lib/mcp/browser/tab.js +277 -0
  99. package/lib/mcp/browser/tool.js +30 -0
  100. package/lib/mcp/browser/tool.js.map +7 -0
  101. package/lib/mcp/browser/tools/common.js +63 -0
  102. package/lib/mcp/browser/tools/console.js +44 -0
  103. package/lib/mcp/browser/tools/dialogs.js +60 -0
  104. package/lib/mcp/browser/tools/evaluate.js +70 -0
  105. package/lib/mcp/browser/tools/files.js +58 -0
  106. package/lib/mcp/browser/tools/form.js +74 -0
  107. package/lib/mcp/browser/tools/install.js +69 -0
  108. package/lib/mcp/browser/tools/keyboard.js +85 -0
  109. package/lib/mcp/browser/tools/mouse.js +107 -0
  110. package/lib/mcp/browser/tools/navigate.js +62 -0
  111. package/lib/mcp/browser/tools/network.js +54 -0
  112. package/lib/mcp/browser/tools/pdf.js +59 -0
  113. package/lib/mcp/browser/tools/screenshot.js +88 -0
  114. package/lib/mcp/browser/tools/snapshot.js +182 -0
  115. package/lib/mcp/browser/tools/tabs.js +67 -0
  116. package/lib/mcp/browser/tools/tool.js +49 -0
  117. package/lib/mcp/browser/tools/tracing.js +74 -0
  118. package/lib/mcp/browser/tools/utils.js +100 -0
  119. package/lib/mcp/browser/tools/verify.js +154 -0
  120. package/lib/mcp/browser/tools/wait.js +63 -0
  121. package/lib/mcp/browser/tools.js +80 -0
  122. package/lib/mcp/browser/tools.js.map +7 -0
  123. package/lib/mcp/browser/watchdog.js +44 -0
  124. package/lib/mcp/config.d.js +16 -0
  125. package/lib/mcp/extension/cdpRelay.js +351 -0
  126. package/lib/mcp/extension/extensionContextFactory.js +75 -0
  127. package/lib/mcp/extension/protocol.js +28 -0
  128. package/lib/mcp/index.js +61 -0
  129. package/lib/mcp/log.js +35 -0
  130. package/lib/mcp/program.js +96 -0
  131. package/lib/mcp/sdk/bundle.js +81 -0
  132. package/lib/mcp/sdk/bundle.js.map +7 -0
  133. package/lib/mcp/sdk/call.js +49 -0
  134. package/lib/mcp/sdk/call.js.map +7 -0
  135. package/lib/mcp/sdk/exports.js +32 -0
  136. package/lib/mcp/sdk/exports.js.map +7 -0
  137. package/lib/mcp/sdk/http.js +187 -0
  138. package/lib/mcp/sdk/http.js.map +7 -0
  139. package/lib/mcp/sdk/inProcessTransport.js +71 -0
  140. package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
  141. package/lib/mcp/sdk/mdb.js +206 -0
  142. package/lib/mcp/sdk/mdb.js.map +7 -0
  143. package/lib/mcp/sdk/proxyBackend.js +128 -0
  144. package/lib/mcp/sdk/proxyBackend.js.map +7 -0
  145. package/lib/mcp/sdk/server.js +189 -0
  146. package/lib/mcp/sdk/server.js.map +7 -0
  147. package/lib/mcp/sdk/tool.js +51 -0
  148. package/lib/mcp/sdk/tool.js.map +7 -0
  149. package/lib/mcp/test/backend.js +67 -0
  150. package/lib/mcp/test/backend.js.map +7 -0
  151. package/lib/mcp/test/browserBackend.js +98 -0
  152. package/lib/mcp/test/context.js +48 -0
  153. package/lib/mcp/test/context.js.map +7 -0
  154. package/lib/mcp/test/generatorTools.js +122 -0
  155. package/lib/mcp/test/plannerTools.js +46 -0
  156. package/lib/mcp/test/seed.js +72 -0
  157. package/lib/mcp/test/streams.js +39 -0
  158. package/lib/mcp/test/streams.js.map +7 -0
  159. package/lib/mcp/test/testBackend.js +97 -0
  160. package/lib/mcp/test/testContext.js +176 -0
  161. package/lib/mcp/test/testTool.js +30 -0
  162. package/lib/mcp/test/testTools.js +115 -0
  163. package/lib/mcp/test/tool.js +30 -0
  164. package/lib/mcp/test/tool.js.map +7 -0
  165. package/lib/mcp/test/tools.js +150 -0
  166. package/lib/mcp/test/tools.js.map +7 -0
  167. package/lib/mcp/vscode/host.js +187 -0
  168. package/lib/mcp/vscode/main.js +77 -0
  169. package/lib/mcpBundleImpl.js +41 -0
  170. package/lib/mcpBundleImpl.js.map +7 -0
  171. package/lib/plugins/gitCommitInfoPlugin.js +198 -0
  172. package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
  173. package/lib/plugins/index.js +28 -0
  174. package/lib/plugins/index.js.map +7 -0
  175. package/lib/plugins/webServerPlugin.js +209 -0
  176. package/lib/plugins/webServerPlugin.js.map +7 -0
  177. package/lib/program.js +412 -0
  178. package/lib/program.js.map +7 -0
  179. package/lib/reporters/base.js +609 -0
  180. package/lib/reporters/base.js.map +7 -0
  181. package/lib/reporters/blob.js +135 -0
  182. package/lib/reporters/blob.js.map +7 -0
  183. package/lib/reporters/dot.js +82 -0
  184. package/lib/reporters/dot.js.map +7 -0
  185. package/lib/reporters/empty.js +32 -0
  186. package/lib/reporters/empty.js.map +7 -0
  187. package/lib/reporters/github.js +128 -0
  188. package/lib/reporters/github.js.map +7 -0
  189. package/lib/reporters/html.js +644 -0
  190. package/lib/reporters/html.js.map +7 -0
  191. package/lib/reporters/internalReporter.js +130 -0
  192. package/lib/reporters/internalReporter.js.map +7 -0
  193. package/lib/reporters/json.js +254 -0
  194. package/lib/reporters/json.js.map +7 -0
  195. package/lib/reporters/junit.js +230 -0
  196. package/lib/reporters/junit.js.map +7 -0
  197. package/lib/reporters/line.js +113 -0
  198. package/lib/reporters/line.js.map +7 -0
  199. package/lib/reporters/list.js +235 -0
  200. package/lib/reporters/list.js.map +7 -0
  201. package/lib/reporters/listModeReporter.js +69 -0
  202. package/lib/reporters/listModeReporter.js.map +7 -0
  203. package/lib/reporters/markdown.js +144 -0
  204. package/lib/reporters/markdown.js.map +7 -0
  205. package/lib/reporters/merge.js +535 -0
  206. package/lib/reporters/merge.js.map +7 -0
  207. package/lib/reporters/multiplexer.js +104 -0
  208. package/lib/reporters/multiplexer.js.map +7 -0
  209. package/lib/reporters/reporterV2.js +102 -0
  210. package/lib/reporters/reporterV2.js.map +7 -0
  211. package/lib/reporters/teleEmitter.js +297 -0
  212. package/lib/reporters/teleEmitter.js.map +7 -0
  213. package/lib/reporters/versions/blobV1.js +16 -0
  214. package/lib/reporters/versions/blobV1.js.map +7 -0
  215. package/lib/runner/dispatcher.js +491 -0
  216. package/lib/runner/dispatcher.js.map +7 -0
  217. package/lib/runner/failureTracker.js +72 -0
  218. package/lib/runner/failureTracker.js.map +7 -0
  219. package/lib/runner/lastRun.js +77 -0
  220. package/lib/runner/lastRun.js.map +7 -0
  221. package/lib/runner/loadUtils.js +333 -0
  222. package/lib/runner/loadUtils.js.map +7 -0
  223. package/lib/runner/loaderHost.js +89 -0
  224. package/lib/runner/loaderHost.js.map +7 -0
  225. package/lib/runner/processHost.js +161 -0
  226. package/lib/runner/processHost.js.map +7 -0
  227. package/lib/runner/projectUtils.js +241 -0
  228. package/lib/runner/projectUtils.js.map +7 -0
  229. package/lib/runner/rebase.js +189 -0
  230. package/lib/runner/rebase.js.map +7 -0
  231. package/lib/runner/reporters.js +137 -0
  232. package/lib/runner/reporters.js.map +7 -0
  233. package/lib/runner/runner.js +173 -0
  234. package/lib/runner/sigIntWatcher.js +96 -0
  235. package/lib/runner/sigIntWatcher.js.map +7 -0
  236. package/lib/runner/taskRunner.js +127 -0
  237. package/lib/runner/taskRunner.js.map +7 -0
  238. package/lib/runner/tasks.js +410 -0
  239. package/lib/runner/tasks.js.map +7 -0
  240. package/lib/runner/testGroups.js +117 -0
  241. package/lib/runner/testGroups.js.map +7 -0
  242. package/lib/runner/testRunner.js +390 -0
  243. package/lib/runner/testRunner.js.map +7 -0
  244. package/lib/runner/testServer.js +264 -0
  245. package/lib/runner/testServer.js.map +7 -0
  246. package/lib/runner/uiMode.js +271 -0
  247. package/lib/runner/uiModeReporter.js +30 -0
  248. package/lib/runner/uiModeReporter.js.map +7 -0
  249. package/lib/runner/vcs.js +72 -0
  250. package/lib/runner/vcs.js.map +7 -0
  251. package/lib/runner/watchMode.js +395 -0
  252. package/lib/runner/watchMode.js.map +7 -0
  253. package/lib/runner/workerHost.js +95 -0
  254. package/lib/runner/workerHost.js.map +7 -0
  255. package/lib/store.js +98 -0
  256. package/lib/third_party/pirates.js +62 -0
  257. package/lib/third_party/pirates.js.map +7 -0
  258. package/lib/third_party/tsconfig-loader.js +103 -0
  259. package/lib/third_party/tsconfig-loader.js.map +7 -0
  260. package/lib/transform/babelBundle.js +43 -0
  261. package/lib/transform/babelBundle.js.map +7 -0
  262. package/lib/transform/babelBundleImpl.js +461 -0
  263. package/lib/transform/babelBundleImpl.js.map +7 -0
  264. package/lib/transform/compilationCache.js +272 -0
  265. package/lib/transform/compilationCache.js.map +7 -0
  266. package/lib/transform/esmLoader.js +104 -0
  267. package/lib/transform/esmLoader.js.map +7 -0
  268. package/lib/transform/esmUtils.js +32 -0
  269. package/lib/transform/portTransport.js +67 -0
  270. package/lib/transform/portTransport.js.map +7 -0
  271. package/lib/transform/transform.js +293 -0
  272. package/lib/transform/transform.js.map +7 -0
  273. package/lib/util.js +403 -0
  274. package/lib/util.js.map +7 -0
  275. package/lib/utilsBundle.js +43 -0
  276. package/lib/utilsBundle.js.map +7 -0
  277. package/lib/utilsBundleImpl.js +100 -0
  278. package/lib/utilsBundleImpl.js.map +7 -0
  279. package/lib/worker/fixtureRunner.js +258 -0
  280. package/lib/worker/fixtureRunner.js.map +7 -0
  281. package/lib/worker/stepContext.js +34 -0
  282. package/lib/worker/testInfo.js +508 -0
  283. package/lib/worker/testInfo.js.map +7 -0
  284. package/lib/worker/testTracing.js +344 -0
  285. package/lib/worker/testTracing.js.map +7 -0
  286. package/lib/worker/timeoutManager.js +174 -0
  287. package/lib/worker/timeoutManager.js.map +7 -0
  288. package/lib/worker/util.js +31 -0
  289. package/lib/worker/util.js.map +7 -0
  290. package/lib/worker/workerMain.js +520 -0
  291. package/lib/worker/workerMain.js.map +7 -0
  292. package/package.json +74 -0
  293. package/test.d.ts +18 -0
  294. package/test.js +24 -0
  295. package/test.mjs +33 -0
  296. package/types/test.d.ts +10217 -0
  297. package/types/testReporter.d.ts +816 -0
@@ -0,0 +1,535 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var merge_exports = {};
30
+ __export(merge_exports, {
31
+ createMergedReport: () => createMergedReport
32
+ });
33
+ module.exports = __toCommonJS(merge_exports);
34
+ var import_fs = __toESM(require("fs"));
35
+ var import_path = __toESM(require("path"));
36
+ var import_utils = require("playwright-core/lib/utils");
37
+ var import_blob = require("./blob");
38
+ var import_multiplexer = require("./multiplexer");
39
+ var import_stringInternPool = require("../isomorphic/stringInternPool");
40
+ var import_teleReceiver = require("../isomorphic/teleReceiver");
41
+ var import_reporters = require("../runner/reporters");
42
+ var import_util = require("../util");
43
+ async function createMergedReport(config, dir, reporterDescriptions, rootDirOverride) {
44
+ const reporters = await (0, import_reporters.createReporters)(config, "merge", false, reporterDescriptions);
45
+ const multiplexer = new import_multiplexer.Multiplexer(reporters);
46
+ const stringPool = new import_stringInternPool.StringInternPool();
47
+ let printStatus = () => {
48
+ };
49
+ if (!multiplexer.printsToStdio()) {
50
+ printStatus = printStatusToStdout;
51
+ printStatus(`merging reports from ${dir}`);
52
+ }
53
+ const shardFiles = await sortedShardFiles(dir);
54
+ if (shardFiles.length === 0)
55
+ throw new Error(`No report files found in ${dir}`);
56
+ const eventData = await mergeEvents(dir, shardFiles, stringPool, printStatus, rootDirOverride);
57
+ const pathSeparator = rootDirOverride ? import_path.default.sep : eventData.pathSeparatorFromMetadata ?? import_path.default.sep;
58
+ const receiver = new import_teleReceiver.TeleReporterReceiver(multiplexer, {
59
+ mergeProjects: false,
60
+ mergeTestCases: false,
61
+ resolvePath: (rootDir, relativePath) => stringPool.internString(rootDir + pathSeparator + relativePath),
62
+ configOverrides: config.config
63
+ });
64
+ printStatus(`processing test events`);
65
+ const dispatchEvents = async (events) => {
66
+ for (const event of events) {
67
+ if (event.method === "onEnd")
68
+ printStatus(`building final report`);
69
+ await receiver.dispatch(event);
70
+ if (event.method === "onEnd")
71
+ printStatus(`finished building report`);
72
+ }
73
+ };
74
+ await dispatchEvents(eventData.prologue);
75
+ for (const { reportFile, eventPatchers, metadata } of eventData.reports) {
76
+ const reportJsonl = await import_fs.default.promises.readFile(reportFile);
77
+ const events = parseTestEvents(reportJsonl);
78
+ new import_stringInternPool.JsonStringInternalizer(stringPool).traverse(events);
79
+ eventPatchers.patchers.push(new AttachmentPathPatcher(dir));
80
+ if (metadata.name)
81
+ eventPatchers.patchers.push(new GlobalErrorPatcher(metadata.name));
82
+ eventPatchers.patchEvents(events);
83
+ await dispatchEvents(events);
84
+ }
85
+ await dispatchEvents(eventData.epilogue);
86
+ }
87
+ const commonEventNames = ["onBlobReportMetadata", "onConfigure", "onProject", "onBegin", "onEnd"];
88
+ const commonEvents = new Set(commonEventNames);
89
+ const commonEventRegex = new RegExp(`${commonEventNames.join("|")}`);
90
+ function parseCommonEvents(reportJsonl) {
91
+ return splitBufferLines(reportJsonl).map((line) => line.toString("utf8")).filter((line) => commonEventRegex.test(line)).map((line) => JSON.parse(line)).filter((event) => commonEvents.has(event.method));
92
+ }
93
+ function parseTestEvents(reportJsonl) {
94
+ return splitBufferLines(reportJsonl).map((line) => line.toString("utf8")).filter((line) => line.length).map((line) => JSON.parse(line)).filter((event) => !commonEvents.has(event.method));
95
+ }
96
+ function splitBufferLines(buffer) {
97
+ const lines = [];
98
+ let start = 0;
99
+ while (start < buffer.length) {
100
+ const end = buffer.indexOf(10, start);
101
+ if (end === -1) {
102
+ lines.push(buffer.slice(start));
103
+ break;
104
+ }
105
+ lines.push(buffer.slice(start, end));
106
+ start = end + 1;
107
+ }
108
+ return lines;
109
+ }
110
+ async function extractAndParseReports(dir, shardFiles, internalizer, printStatus) {
111
+ const shardEvents = [];
112
+ await import_fs.default.promises.mkdir(import_path.default.join(dir, "resources"), { recursive: true });
113
+ const reportNames = new UniqueFileNameGenerator();
114
+ for (const file of shardFiles) {
115
+ const absolutePath = import_path.default.join(dir, file);
116
+ printStatus(`extracting: ${(0, import_util.relativeFilePath)(absolutePath)}`);
117
+ const zipFile = new import_utils.ZipFile(absolutePath);
118
+ const entryNames = await zipFile.entries();
119
+ for (const entryName of entryNames.sort()) {
120
+ let fileName = import_path.default.join(dir, entryName);
121
+ const content = await zipFile.read(entryName);
122
+ if (entryName.endsWith(".jsonl")) {
123
+ fileName = reportNames.makeUnique(fileName);
124
+ let parsedEvents = parseCommonEvents(content);
125
+ internalizer.traverse(parsedEvents);
126
+ const metadata = findMetadata(parsedEvents, file);
127
+ parsedEvents = modernizer.modernize(metadata.version, parsedEvents);
128
+ shardEvents.push({
129
+ file,
130
+ localPath: fileName,
131
+ metadata,
132
+ parsedEvents
133
+ });
134
+ }
135
+ await import_fs.default.promises.writeFile(fileName, content);
136
+ }
137
+ zipFile.close();
138
+ }
139
+ return shardEvents;
140
+ }
141
+ function findMetadata(events, file) {
142
+ if (events[0]?.method !== "onBlobReportMetadata")
143
+ throw new Error(`No metadata event found in ${file}`);
144
+ const metadata = events[0].params;
145
+ if (metadata.version > import_blob.currentBlobReportVersion)
146
+ throw new Error(`Blob report ${file} was created with a newer version of Playwright.`);
147
+ return metadata;
148
+ }
149
+ async function mergeEvents(dir, shardReportFiles, stringPool, printStatus, rootDirOverride) {
150
+ const internalizer = new import_stringInternPool.JsonStringInternalizer(stringPool);
151
+ const configureEvents = [];
152
+ const projectEvents = [];
153
+ const endEvents = [];
154
+ const blobs = await extractAndParseReports(dir, shardReportFiles, internalizer, printStatus);
155
+ blobs.sort((a, b) => {
156
+ const nameA = a.metadata.name ?? "";
157
+ const nameB = b.metadata.name ?? "";
158
+ if (nameA !== nameB)
159
+ return nameA.localeCompare(nameB);
160
+ const shardA = a.metadata.shard?.current ?? 0;
161
+ const shardB = b.metadata.shard?.current ?? 0;
162
+ if (shardA !== shardB)
163
+ return shardA - shardB;
164
+ return a.file.localeCompare(b.file);
165
+ });
166
+ printStatus(`merging events`);
167
+ const reports = [];
168
+ const globalTestIdSet = /* @__PURE__ */ new Set();
169
+ for (let i = 0; i < blobs.length; ++i) {
170
+ const { parsedEvents, metadata, localPath } = blobs[i];
171
+ const eventPatchers = new JsonEventPatchers();
172
+ eventPatchers.patchers.push(new IdsPatcher(
173
+ stringPool,
174
+ metadata.name,
175
+ String(i),
176
+ globalTestIdSet
177
+ ));
178
+ if (rootDirOverride)
179
+ eventPatchers.patchers.push(new PathSeparatorPatcher(metadata.pathSeparator));
180
+ eventPatchers.patchEvents(parsedEvents);
181
+ for (const event of parsedEvents) {
182
+ if (event.method === "onConfigure")
183
+ configureEvents.push(event);
184
+ else if (event.method === "onProject")
185
+ projectEvents.push(event);
186
+ else if (event.method === "onEnd")
187
+ endEvents.push(event);
188
+ }
189
+ reports.push({
190
+ eventPatchers,
191
+ reportFile: localPath,
192
+ metadata
193
+ });
194
+ }
195
+ return {
196
+ prologue: [
197
+ mergeConfigureEvents(configureEvents, rootDirOverride),
198
+ ...projectEvents,
199
+ { method: "onBegin", params: void 0 }
200
+ ],
201
+ reports,
202
+ epilogue: [
203
+ mergeEndEvents(endEvents),
204
+ { method: "onExit", params: void 0 }
205
+ ],
206
+ pathSeparatorFromMetadata: blobs[0]?.metadata.pathSeparator
207
+ };
208
+ }
209
+ function mergeConfigureEvents(configureEvents, rootDirOverride) {
210
+ if (!configureEvents.length)
211
+ throw new Error("No configure events found");
212
+ let config = {
213
+ configFile: void 0,
214
+ globalTimeout: 0,
215
+ maxFailures: 0,
216
+ metadata: {},
217
+ rootDir: "",
218
+ version: "",
219
+ workers: 0,
220
+ globalSetup: null,
221
+ globalTeardown: null
222
+ };
223
+ for (const event of configureEvents)
224
+ config = mergeConfigs(config, event.params.config);
225
+ if (rootDirOverride) {
226
+ config.rootDir = rootDirOverride;
227
+ } else {
228
+ const rootDirs = new Set(configureEvents.map((e) => e.params.config.rootDir));
229
+ if (rootDirs.size > 1) {
230
+ throw new Error([
231
+ `Blob reports being merged were recorded with different test directories, and`,
232
+ `merging cannot proceed. This may happen if you are merging reports from`,
233
+ `machines with different environments, like different operating systems or`,
234
+ `if the tests ran with different playwright configs.`,
235
+ ``,
236
+ `You can force merge by specifying a merge config file with "-c" option. If`,
237
+ `you'd like all test paths to be correct, make sure 'testDir' in the merge config`,
238
+ `file points to the actual tests location.`,
239
+ ``,
240
+ `Found directories:`,
241
+ ...rootDirs
242
+ ].join("\n"));
243
+ }
244
+ }
245
+ return {
246
+ method: "onConfigure",
247
+ params: {
248
+ config
249
+ }
250
+ };
251
+ }
252
+ function mergeConfigs(to, from) {
253
+ return {
254
+ ...to,
255
+ ...from,
256
+ metadata: {
257
+ ...to.metadata,
258
+ ...from.metadata,
259
+ actualWorkers: (to.metadata.actualWorkers || 0) + (from.metadata.actualWorkers || 0)
260
+ },
261
+ workers: to.workers + from.workers
262
+ };
263
+ }
264
+ function mergeEndEvents(endEvents) {
265
+ let startTime = endEvents.length ? 1e13 : Date.now();
266
+ let status = "passed";
267
+ let duration = 0;
268
+ for (const event of endEvents) {
269
+ const shardResult = event.params.result;
270
+ if (shardResult.status === "failed")
271
+ status = "failed";
272
+ else if (shardResult.status === "timedout" && status !== "failed")
273
+ status = "timedout";
274
+ else if (shardResult.status === "interrupted" && status !== "failed" && status !== "timedout")
275
+ status = "interrupted";
276
+ startTime = Math.min(startTime, shardResult.startTime);
277
+ duration = Math.max(duration, shardResult.duration);
278
+ }
279
+ const result = {
280
+ status,
281
+ startTime,
282
+ duration
283
+ };
284
+ return {
285
+ method: "onEnd",
286
+ params: {
287
+ result
288
+ }
289
+ };
290
+ }
291
+ async function sortedShardFiles(dir) {
292
+ const files = await import_fs.default.promises.readdir(dir);
293
+ return files.filter((file) => file.endsWith(".zip")).sort();
294
+ }
295
+ function printStatusToStdout(message) {
296
+ process.stdout.write(`${message}
297
+ `);
298
+ }
299
+ class UniqueFileNameGenerator {
300
+ constructor() {
301
+ this._usedNames = /* @__PURE__ */ new Set();
302
+ }
303
+ makeUnique(name) {
304
+ if (!this._usedNames.has(name)) {
305
+ this._usedNames.add(name);
306
+ return name;
307
+ }
308
+ const extension = import_path.default.extname(name);
309
+ name = name.substring(0, name.length - extension.length);
310
+ let index = 0;
311
+ while (true) {
312
+ const candidate = `${name}-${++index}${extension}`;
313
+ if (!this._usedNames.has(candidate)) {
314
+ this._usedNames.add(candidate);
315
+ return candidate;
316
+ }
317
+ }
318
+ }
319
+ }
320
+ class IdsPatcher {
321
+ constructor(stringPool, botName, salt, globalTestIdSet) {
322
+ this._stringPool = stringPool;
323
+ this._botName = botName;
324
+ this._salt = salt;
325
+ this._testIdsMap = /* @__PURE__ */ new Map();
326
+ this._globalTestIdSet = globalTestIdSet;
327
+ }
328
+ patchEvent(event) {
329
+ const { method, params } = event;
330
+ switch (method) {
331
+ case "onProject":
332
+ this._onProject(params.project);
333
+ return;
334
+ case "onAttach":
335
+ case "onTestBegin":
336
+ case "onStepBegin":
337
+ case "onStepEnd":
338
+ case "onStdIO":
339
+ params.testId = params.testId ? this._mapTestId(params.testId) : void 0;
340
+ return;
341
+ case "onTestEnd":
342
+ params.test.testId = this._mapTestId(params.test.testId);
343
+ return;
344
+ }
345
+ }
346
+ _onProject(project) {
347
+ project.metadata ??= {};
348
+ project.suites.forEach((suite) => this._updateTestIds(suite));
349
+ }
350
+ _updateTestIds(suite) {
351
+ suite.entries.forEach((entry) => {
352
+ if ("testId" in entry)
353
+ this._updateTestId(entry);
354
+ else
355
+ this._updateTestIds(entry);
356
+ });
357
+ }
358
+ _updateTestId(test) {
359
+ test.testId = this._mapTestId(test.testId);
360
+ if (this._botName) {
361
+ test.tags = test.tags || [];
362
+ test.tags.unshift("@" + this._botName);
363
+ }
364
+ }
365
+ _mapTestId(testId) {
366
+ const t1 = this._stringPool.internString(testId);
367
+ if (this._testIdsMap.has(t1))
368
+ return this._testIdsMap.get(t1);
369
+ if (this._globalTestIdSet.has(t1)) {
370
+ const t2 = this._stringPool.internString(testId + this._salt);
371
+ this._globalTestIdSet.add(t2);
372
+ this._testIdsMap.set(t1, t2);
373
+ return t2;
374
+ }
375
+ this._globalTestIdSet.add(t1);
376
+ this._testIdsMap.set(t1, t1);
377
+ return t1;
378
+ }
379
+ }
380
+ class AttachmentPathPatcher {
381
+ constructor(_resourceDir) {
382
+ this._resourceDir = _resourceDir;
383
+ }
384
+ patchEvent(event) {
385
+ if (event.method === "onAttach")
386
+ this._patchAttachments(event.params.attachments);
387
+ else if (event.method === "onTestEnd")
388
+ this._patchAttachments(event.params.result.attachments ?? []);
389
+ }
390
+ _patchAttachments(attachments) {
391
+ for (const attachment of attachments) {
392
+ if (!attachment.path)
393
+ continue;
394
+ attachment.path = import_path.default.join(this._resourceDir, attachment.path);
395
+ }
396
+ }
397
+ }
398
+ class PathSeparatorPatcher {
399
+ constructor(from) {
400
+ this._from = from ?? (import_path.default.sep === "/" ? "\\" : "/");
401
+ this._to = import_path.default.sep;
402
+ }
403
+ patchEvent(jsonEvent) {
404
+ if (this._from === this._to)
405
+ return;
406
+ if (jsonEvent.method === "onProject") {
407
+ this._updateProject(jsonEvent.params.project);
408
+ return;
409
+ }
410
+ if (jsonEvent.method === "onTestEnd") {
411
+ const test = jsonEvent.params.test;
412
+ test.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation));
413
+ const testResult = jsonEvent.params.result;
414
+ testResult.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation));
415
+ testResult.errors.forEach((error) => this._updateErrorLocations(error));
416
+ (testResult.attachments ?? []).forEach((attachment) => {
417
+ if (attachment.path)
418
+ attachment.path = this._updatePath(attachment.path);
419
+ });
420
+ return;
421
+ }
422
+ if (jsonEvent.method === "onStepBegin") {
423
+ const step = jsonEvent.params.step;
424
+ this._updateLocation(step.location);
425
+ return;
426
+ }
427
+ if (jsonEvent.method === "onStepEnd") {
428
+ const step = jsonEvent.params.step;
429
+ this._updateErrorLocations(step.error);
430
+ step.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation));
431
+ return;
432
+ }
433
+ if (jsonEvent.method === "onAttach") {
434
+ const attach = jsonEvent.params;
435
+ attach.attachments.forEach((attachment) => {
436
+ if (attachment.path)
437
+ attachment.path = this._updatePath(attachment.path);
438
+ });
439
+ return;
440
+ }
441
+ }
442
+ _updateProject(project) {
443
+ project.outputDir = this._updatePath(project.outputDir);
444
+ project.testDir = this._updatePath(project.testDir);
445
+ project.snapshotDir = this._updatePath(project.snapshotDir);
446
+ project.suites.forEach((suite) => this._updateSuite(suite, true));
447
+ }
448
+ _updateSuite(suite, isFileSuite = false) {
449
+ this._updateLocation(suite.location);
450
+ if (isFileSuite)
451
+ suite.title = this._updatePath(suite.title);
452
+ for (const entry of suite.entries) {
453
+ if ("testId" in entry) {
454
+ this._updateLocation(entry.location);
455
+ entry.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation));
456
+ } else {
457
+ this._updateSuite(entry);
458
+ }
459
+ }
460
+ }
461
+ _updateErrorLocations(error) {
462
+ while (error) {
463
+ this._updateLocation(error.location);
464
+ error = error.cause;
465
+ }
466
+ }
467
+ _updateAnnotationLocation(annotation) {
468
+ this._updateLocation(annotation.location);
469
+ }
470
+ _updateLocation(location) {
471
+ if (location)
472
+ location.file = this._updatePath(location.file);
473
+ }
474
+ _updatePath(text) {
475
+ return text.split(this._from).join(this._to);
476
+ }
477
+ }
478
+ class GlobalErrorPatcher {
479
+ constructor(botName) {
480
+ this._prefix = `(${botName}) `;
481
+ }
482
+ patchEvent(event) {
483
+ if (event.method !== "onError")
484
+ return;
485
+ const error = event.params.error;
486
+ if (error.message !== void 0)
487
+ error.message = this._prefix + error.message;
488
+ if (error.stack !== void 0)
489
+ error.stack = this._prefix + error.stack;
490
+ }
491
+ }
492
+ class JsonEventPatchers {
493
+ constructor() {
494
+ this.patchers = [];
495
+ }
496
+ patchEvents(events) {
497
+ for (const event of events) {
498
+ for (const patcher of this.patchers)
499
+ patcher.patchEvent(event);
500
+ }
501
+ }
502
+ }
503
+ class BlobModernizer {
504
+ modernize(fromVersion, events) {
505
+ const result = [];
506
+ for (const event of events)
507
+ result.push(...this._modernize(fromVersion, event));
508
+ return result;
509
+ }
510
+ _modernize(fromVersion, event) {
511
+ let events = [event];
512
+ for (let version = fromVersion; version < import_blob.currentBlobReportVersion; ++version)
513
+ events = this[`_modernize_${version}_to_${version + 1}`].call(this, events);
514
+ return events;
515
+ }
516
+ _modernize_1_to_2(events) {
517
+ return events.map((event) => {
518
+ if (event.method === "onProject") {
519
+ const modernizeSuite = (suite) => {
520
+ const newSuites = suite.suites.map(modernizeSuite);
521
+ const { suites, tests, ...remainder } = suite;
522
+ return { entries: [...newSuites, ...tests], ...remainder };
523
+ };
524
+ const project = event.params.project;
525
+ project.suites = project.suites.map(modernizeSuite);
526
+ }
527
+ return event;
528
+ });
529
+ }
530
+ }
531
+ const modernizer = new BlobModernizer();
532
+ // Annotate the CommonJS export names for ESM import in node:
533
+ 0 && (module.exports = {
534
+ createMergedReport
535
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/reporters/merge.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { ZipFile } from 'playwright-core/lib/utils';\n\nimport { currentBlobReportVersion } from './blob';\nimport { Multiplexer } from './multiplexer';\nimport { JsonStringInternalizer, StringInternPool } from '../isomorphic/stringInternPool';\nimport { TeleReporterReceiver } from '../isomorphic/teleReceiver';\nimport { createReporters } from '../runner/reporters';\nimport { relativeFilePath } from '../util';\n\nimport type { ReporterDescription, TestAnnotation } from '../../types/test';\nimport type { TestError } from '../../types/testReporter';\nimport type { FullConfigInternal } from '../common/config';\nimport type { BlobReportMetadata, JsonAttachment, JsonConfig, JsonEvent, JsonFullResult, JsonLocation, JsonOnConfigureEvent, JsonOnEndEvent, JsonOnProjectEvent, JsonProject, JsonSuite, JsonTestCase } from '../isomorphic/teleReceiver';\nimport type * as blobV1 from './versions/blobV1';\n\ntype StatusCallback = (message: string) => void;\n\ntype ReportData = {\n eventPatchers: JsonEventPatchers;\n reportFile: string;\n metadata: BlobReportMetadata;\n};\n\nexport async function createMergedReport(config: FullConfigInternal, dir: string, reporterDescriptions: ReporterDescription[], rootDirOverride: string | undefined) {\n const reporters = await createReporters(config, 'merge', false, reporterDescriptions);\n const multiplexer = new Multiplexer(reporters);\n const stringPool = new StringInternPool();\n\n let printStatus: StatusCallback = () => {};\n if (!multiplexer.printsToStdio()) {\n printStatus = printStatusToStdout;\n printStatus(`merging reports from ${dir}`);\n }\n\n const shardFiles = await sortedShardFiles(dir);\n if (shardFiles.length === 0)\n throw new Error(`No report files found in ${dir}`);\n const eventData = await mergeEvents(dir, shardFiles, stringPool, printStatus, rootDirOverride);\n // If explicit config is provided, use platform path separator, otherwise use the one from the report (if any).\n const pathSeparator = rootDirOverride ? path.sep : (eventData.pathSeparatorFromMetadata ?? path.sep);\n const receiver = new TeleReporterReceiver(multiplexer, {\n mergeProjects: false,\n mergeTestCases: false,\n resolvePath: (rootDir, relativePath) => stringPool.internString(rootDir + pathSeparator + relativePath),\n configOverrides: config.config,\n });\n printStatus(`processing test events`);\n\n const dispatchEvents = async (events: JsonEvent[]) => {\n for (const event of events) {\n if (event.method === 'onEnd')\n printStatus(`building final report`);\n await receiver.dispatch(event);\n if (event.method === 'onEnd')\n printStatus(`finished building report`);\n }\n };\n\n await dispatchEvents(eventData.prologue);\n for (const { reportFile, eventPatchers, metadata } of eventData.reports) {\n const reportJsonl = await fs.promises.readFile(reportFile);\n const events = parseTestEvents(reportJsonl);\n new JsonStringInternalizer(stringPool).traverse(events);\n eventPatchers.patchers.push(new AttachmentPathPatcher(dir));\n if (metadata.name)\n eventPatchers.patchers.push(new GlobalErrorPatcher(metadata.name));\n eventPatchers.patchEvents(events);\n await dispatchEvents(events);\n }\n await dispatchEvents(eventData.epilogue);\n}\n\nconst commonEventNames = ['onBlobReportMetadata', 'onConfigure', 'onProject', 'onBegin', 'onEnd'];\nconst commonEvents = new Set(commonEventNames);\nconst commonEventRegex = new RegExp(`${commonEventNames.join('|')}`);\n\nfunction parseCommonEvents(reportJsonl: Buffer): JsonEvent[] {\n return splitBufferLines(reportJsonl)\n .map(line => line.toString('utf8'))\n .filter(line => commonEventRegex.test(line)) // quick filter\n .map(line => JSON.parse(line) as JsonEvent)\n .filter(event => commonEvents.has(event.method));\n}\n\nfunction parseTestEvents(reportJsonl: Buffer): JsonEvent[] {\n return splitBufferLines(reportJsonl)\n .map(line => line.toString('utf8'))\n .filter(line => line.length)\n .map(line => JSON.parse(line) as JsonEvent)\n .filter(event => !commonEvents.has(event.method));\n}\n\nfunction splitBufferLines(buffer: Buffer) {\n const lines = [];\n let start = 0;\n while (start < buffer.length) {\n // 0x0A is the byte for '\\n'\n const end = buffer.indexOf(0x0A, start);\n if (end === -1) {\n lines.push(buffer.slice(start));\n break;\n }\n lines.push(buffer.slice(start, end));\n start = end + 1;\n }\n return lines;\n}\n\nasync function extractAndParseReports(dir: string, shardFiles: string[], internalizer: JsonStringInternalizer, printStatus: StatusCallback) {\n const shardEvents: { file: string, localPath: string, metadata: BlobReportMetadata, parsedEvents: JsonEvent[] }[] = [];\n await fs.promises.mkdir(path.join(dir, 'resources'), { recursive: true });\n\n const reportNames = new UniqueFileNameGenerator();\n for (const file of shardFiles) {\n const absolutePath = path.join(dir, file);\n printStatus(`extracting: ${relativeFilePath(absolutePath)}`);\n const zipFile = new ZipFile(absolutePath);\n const entryNames = await zipFile.entries();\n for (const entryName of entryNames.sort()) {\n let fileName = path.join(dir, entryName);\n const content = await zipFile.read(entryName);\n if (entryName.endsWith('.jsonl')) {\n fileName = reportNames.makeUnique(fileName);\n let parsedEvents = parseCommonEvents(content);\n // Passing reviver to JSON.parse doesn't work, as the original strings\n // keep being used. To work around that we traverse the parsed events\n // as a post-processing step.\n internalizer.traverse(parsedEvents);\n const metadata = findMetadata(parsedEvents, file);\n parsedEvents = modernizer.modernize(metadata.version, parsedEvents);\n shardEvents.push({\n file,\n localPath: fileName,\n metadata,\n parsedEvents\n });\n }\n await fs.promises.writeFile(fileName, content);\n }\n zipFile.close();\n }\n return shardEvents;\n}\n\nfunction findMetadata(events: JsonEvent[], file: string): BlobReportMetadata {\n if (events[0]?.method !== 'onBlobReportMetadata')\n throw new Error(`No metadata event found in ${file}`);\n const metadata = events[0].params;\n if (metadata.version > currentBlobReportVersion)\n throw new Error(`Blob report ${file} was created with a newer version of Playwright.`);\n return metadata;\n}\n\nasync function mergeEvents(dir: string, shardReportFiles: string[], stringPool: StringInternPool, printStatus: StatusCallback, rootDirOverride: string | undefined): Promise<{\n prologue: JsonEvent[];\n reports: ReportData[];\n epilogue: JsonEvent[];\n pathSeparatorFromMetadata?: string;\n}> {\n const internalizer = new JsonStringInternalizer(stringPool);\n\n const configureEvents: JsonOnConfigureEvent[] = [];\n const projectEvents: JsonOnProjectEvent[] = [];\n const endEvents: JsonOnEndEvent[] = [];\n\n const blobs = await extractAndParseReports(dir, shardReportFiles, internalizer, printStatus);\n // Sort by (report name; shard; file name), so that salt generation below is deterministic when:\n // - report names are unique;\n // - report names are missing;\n // - report names are clashing between shards.\n blobs.sort((a, b) => {\n const nameA = a.metadata.name ?? '';\n const nameB = b.metadata.name ?? '';\n if (nameA !== nameB)\n return nameA.localeCompare(nameB);\n const shardA = a.metadata.shard?.current ?? 0;\n const shardB = b.metadata.shard?.current ?? 0;\n if (shardA !== shardB)\n return shardA - shardB;\n return a.file.localeCompare(b.file);\n });\n\n printStatus(`merging events`);\n\n const reports: ReportData[] = [];\n const globalTestIdSet = new Set<string>();\n\n for (let i = 0; i < blobs.length; ++i) {\n // Generate unique salt for each blob.\n const { parsedEvents, metadata, localPath } = blobs[i];\n const eventPatchers = new JsonEventPatchers();\n eventPatchers.patchers.push(new IdsPatcher(\n stringPool,\n metadata.name,\n String(i),\n globalTestIdSet,\n ));\n // Only patch path separators if we are merging reports with explicit config.\n if (rootDirOverride)\n eventPatchers.patchers.push(new PathSeparatorPatcher(metadata.pathSeparator));\n eventPatchers.patchEvents(parsedEvents);\n\n for (const event of parsedEvents) {\n if (event.method === 'onConfigure')\n configureEvents.push(event);\n else if (event.method === 'onProject')\n projectEvents.push(event);\n else if (event.method === 'onEnd')\n endEvents.push(event);\n }\n\n // Save information about the reports to stream their test events later.\n reports.push({\n eventPatchers,\n reportFile: localPath,\n metadata,\n });\n }\n\n return {\n prologue: [\n mergeConfigureEvents(configureEvents, rootDirOverride),\n ...projectEvents,\n { method: 'onBegin', params: undefined },\n ],\n reports,\n epilogue: [\n mergeEndEvents(endEvents),\n { method: 'onExit', params: undefined },\n ],\n pathSeparatorFromMetadata: blobs[0]?.metadata.pathSeparator,\n };\n}\n\nfunction mergeConfigureEvents(configureEvents: JsonOnConfigureEvent[], rootDirOverride: string | undefined): JsonEvent {\n if (!configureEvents.length)\n throw new Error('No configure events found');\n let config: JsonConfig = {\n configFile: undefined,\n globalTimeout: 0,\n maxFailures: 0,\n metadata: {\n },\n rootDir: '',\n version: '',\n workers: 0,\n globalSetup: null,\n globalTeardown: null,\n };\n for (const event of configureEvents)\n config = mergeConfigs(config, event.params.config);\n\n if (rootDirOverride) {\n config.rootDir = rootDirOverride;\n } else {\n const rootDirs = new Set(configureEvents.map(e => e.params.config.rootDir));\n if (rootDirs.size > 1) {\n throw new Error([\n `Blob reports being merged were recorded with different test directories, and`,\n `merging cannot proceed. This may happen if you are merging reports from`,\n `machines with different environments, like different operating systems or`,\n `if the tests ran with different playwright configs.`,\n ``,\n `You can force merge by specifying a merge config file with \"-c\" option. If`,\n `you'd like all test paths to be correct, make sure 'testDir' in the merge config`,\n `file points to the actual tests location.`,\n ``,\n `Found directories:`,\n ...rootDirs\n ].join('\\n'));\n }\n }\n\n return {\n method: 'onConfigure',\n params: {\n config,\n }\n };\n}\n\nfunction mergeConfigs(to: JsonConfig, from: JsonConfig): JsonConfig {\n return {\n ...to,\n ...from,\n metadata: {\n ...to.metadata,\n ...from.metadata,\n actualWorkers: (to.metadata.actualWorkers || 0) + (from.metadata.actualWorkers || 0),\n },\n workers: to.workers + from.workers,\n };\n}\n\nfunction mergeEndEvents(endEvents: JsonOnEndEvent[]): JsonEvent {\n let startTime = endEvents.length ? 10000000000000 : Date.now();\n let status: JsonFullResult['status'] = 'passed';\n let duration: number = 0;\n\n for (const event of endEvents) {\n const shardResult = event.params.result;\n if (shardResult.status === 'failed')\n status = 'failed';\n else if (shardResult.status === 'timedout' && status !== 'failed')\n status = 'timedout';\n else if (shardResult.status === 'interrupted' && status !== 'failed' && status !== 'timedout')\n status = 'interrupted';\n startTime = Math.min(startTime, shardResult.startTime);\n duration = Math.max(duration, shardResult.duration);\n }\n const result: JsonFullResult = {\n status,\n startTime,\n duration,\n };\n return {\n method: 'onEnd',\n params: {\n result\n }\n };\n}\n\nasync function sortedShardFiles(dir: string) {\n const files = await fs.promises.readdir(dir);\n return files.filter(file => file.endsWith('.zip')).sort();\n}\n\nfunction printStatusToStdout(message: string) {\n // eslint-disable-next-line no-restricted-properties\n process.stdout.write(`${message}\\n`);\n}\n\nclass UniqueFileNameGenerator {\n private _usedNames = new Set<string>();\n\n makeUnique(name: string): string {\n if (!this._usedNames.has(name)) {\n this._usedNames.add(name);\n return name;\n }\n const extension = path.extname(name);\n name = name.substring(0, name.length - extension.length);\n let index = 0;\n while (true) {\n const candidate = `${name}-${++index}${extension}`;\n if (!this._usedNames.has(candidate)) {\n this._usedNames.add(candidate);\n return candidate;\n }\n }\n }\n}\n\nclass IdsPatcher {\n private _stringPool: StringInternPool;\n private _botName: string | undefined;\n private _salt: string;\n private _testIdsMap: Map<string, string>;\n private _globalTestIdSet: Set<string>;\n\n constructor(\n stringPool: StringInternPool,\n botName: string | undefined,\n salt: string,\n globalTestIdSet: Set<string>,\n ) {\n this._stringPool = stringPool;\n this._botName = botName;\n this._salt = salt;\n this._testIdsMap = new Map();\n this._globalTestIdSet = globalTestIdSet;\n }\n\n patchEvent(event: JsonEvent) {\n const { method, params } = event;\n switch (method) {\n case 'onProject':\n this._onProject(params.project);\n return;\n case 'onAttach':\n case 'onTestBegin':\n case 'onStepBegin':\n case 'onStepEnd':\n case 'onStdIO':\n params.testId = params.testId ? this._mapTestId(params.testId) : undefined;\n return;\n case 'onTestEnd':\n params.test.testId = this._mapTestId(params.test.testId);\n return;\n }\n }\n\n private _onProject(project: JsonProject) {\n project.metadata ??= {};\n project.suites.forEach(suite => this._updateTestIds(suite));\n }\n\n private _updateTestIds(suite: JsonSuite) {\n suite.entries.forEach(entry => {\n if ('testId' in entry)\n this._updateTestId(entry);\n else\n this._updateTestIds(entry);\n });\n }\n\n private _updateTestId(test: JsonTestCase) {\n test.testId = this._mapTestId(test.testId);\n if (this._botName) {\n test.tags = test.tags || [];\n test.tags.unshift('@' + this._botName);\n }\n }\n\n private _mapTestId(testId: string): string {\n const t1 = this._stringPool.internString(testId);\n if (this._testIdsMap.has(t1))\n // already mapped\n return this._testIdsMap.get(t1)!;\n if (this._globalTestIdSet.has(t1)) {\n // test id is used in another blob, so we need to salt it.\n const t2 = this._stringPool.internString(testId + this._salt);\n this._globalTestIdSet.add(t2);\n this._testIdsMap.set(t1, t2);\n return t2;\n }\n this._globalTestIdSet.add(t1);\n this._testIdsMap.set(t1, t1);\n return t1;\n }\n}\n\nclass AttachmentPathPatcher {\n constructor(private _resourceDir: string) {\n }\n\n patchEvent(event: JsonEvent) {\n if (event.method === 'onAttach')\n this._patchAttachments(event.params.attachments);\n else if (event.method === 'onTestEnd')\n this._patchAttachments(event.params.result.attachments ?? []);\n }\n\n private _patchAttachments(attachments: JsonAttachment[]) {\n for (const attachment of attachments) {\n if (!attachment.path)\n continue;\n\n attachment.path = path.join(this._resourceDir, attachment.path);\n }\n }\n}\n\nclass PathSeparatorPatcher {\n private _from: string;\n private _to: string;\n constructor(from?: string) {\n this._from = from ?? (path.sep === '/' ? '\\\\' : '/');\n this._to = path.sep;\n }\n\n patchEvent(jsonEvent: JsonEvent) {\n if (this._from === this._to)\n return;\n if (jsonEvent.method === 'onProject') {\n this._updateProject(jsonEvent.params.project);\n return;\n }\n if (jsonEvent.method === 'onTestEnd') {\n const test = jsonEvent.params.test;\n test.annotations?.forEach(annotation => this._updateAnnotationLocation(annotation));\n const testResult = jsonEvent.params.result;\n testResult.annotations?.forEach(annotation => this._updateAnnotationLocation(annotation));\n testResult.errors.forEach(error => this._updateErrorLocations(error));\n (testResult.attachments ?? []).forEach(attachment => {\n if (attachment.path)\n attachment.path = this._updatePath(attachment.path);\n });\n return;\n }\n if (jsonEvent.method === 'onStepBegin') {\n const step = jsonEvent.params.step;\n this._updateLocation(step.location);\n return;\n }\n if (jsonEvent.method === 'onStepEnd') {\n const step = jsonEvent.params.step;\n this._updateErrorLocations(step.error);\n step.annotations?.forEach(annotation => this._updateAnnotationLocation(annotation));\n return;\n }\n if (jsonEvent.method === 'onAttach') {\n const attach = jsonEvent.params;\n attach.attachments.forEach(attachment => {\n if (attachment.path)\n attachment.path = this._updatePath(attachment.path);\n });\n return;\n }\n }\n\n private _updateProject(project: JsonProject) {\n project.outputDir = this._updatePath(project.outputDir);\n project.testDir = this._updatePath(project.testDir);\n project.snapshotDir = this._updatePath(project.snapshotDir);\n project.suites.forEach(suite => this._updateSuite(suite, true));\n }\n\n private _updateSuite(suite: JsonSuite, isFileSuite: boolean = false) {\n this._updateLocation(suite.location);\n if (isFileSuite)\n suite.title = this._updatePath(suite.title);\n for (const entry of suite.entries) {\n if ('testId' in entry) {\n this._updateLocation(entry.location);\n entry.annotations?.forEach(annotation => this._updateAnnotationLocation(annotation));\n } else {\n this._updateSuite(entry);\n }\n }\n }\n\n private _updateErrorLocations(error: TestError | undefined) {\n while (error) {\n this._updateLocation(error.location);\n error = error.cause;\n }\n }\n\n private _updateAnnotationLocation(annotation: TestAnnotation) {\n this._updateLocation(annotation.location);\n }\n\n private _updateLocation(location?: JsonLocation) {\n if (location)\n location.file = this._updatePath(location.file);\n }\n\n private _updatePath(text: string): string {\n return text.split(this._from).join(this._to);\n }\n}\n\nclass GlobalErrorPatcher {\n private _prefix: string;\n\n constructor(botName: string) {\n this._prefix = `(${botName}) `;\n }\n\n patchEvent(event: JsonEvent) {\n if (event.method !== 'onError')\n return;\n const error = event.params.error;\n if (error.message !== undefined)\n error.message = this._prefix + error.message;\n if (error.stack !== undefined)\n error.stack = this._prefix + error.stack;\n }\n}\n\ninterface JsonEventPatcher {\n patchEvent(event: JsonEvent): void;\n}\n\nclass JsonEventPatchers {\n readonly patchers: JsonEventPatcher[] = [];\n\n patchEvents(events: JsonEvent[]) {\n for (const event of events) {\n for (const patcher of this.patchers)\n patcher.patchEvent(event);\n }\n }\n}\n\nclass BlobModernizer {\n modernize(fromVersion: number, events: JsonEvent[]): JsonEvent[] {\n const result = [];\n for (const event of events)\n result.push(...this._modernize(fromVersion, event));\n return result;\n }\n\n private _modernize(fromVersion: number, event: JsonEvent): JsonEvent[] {\n let events = [event];\n for (let version = fromVersion; version < currentBlobReportVersion; ++version)\n events = (this as any)[`_modernize_${version}_to_${version + 1}`].call(this, events);\n return events;\n }\n\n _modernize_1_to_2(events: JsonEvent[]): JsonEvent[] {\n return events.map(event => {\n if (event.method === 'onProject') {\n const modernizeSuite = (suite: blobV1.JsonSuite): JsonSuite => {\n const newSuites = suite.suites.map(modernizeSuite);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { suites, tests, ...remainder } = suite;\n return { entries: [...newSuites, ...tests], ...remainder };\n };\n const project = event.params.project;\n project.suites = (project.suites as unknown as blobV1.JsonSuite[]).map(modernizeSuite);\n }\n return event;\n });\n }\n}\n\nconst modernizer = new BlobModernizer();\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "fs"]
7
+ }