@pedropaulovc/playwright-core 1.59.0-alpha-1769214875000

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 (364) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +3 -0
  4. package/ThirdPartyNotices.txt +4076 -0
  5. package/bin/install_media_pack.ps1 +5 -0
  6. package/bin/install_webkit_wsl.ps1 +33 -0
  7. package/bin/reinstall_chrome_beta_linux.sh +42 -0
  8. package/bin/reinstall_chrome_beta_mac.sh +13 -0
  9. package/bin/reinstall_chrome_beta_win.ps1 +24 -0
  10. package/bin/reinstall_chrome_stable_linux.sh +42 -0
  11. package/bin/reinstall_chrome_stable_mac.sh +12 -0
  12. package/bin/reinstall_chrome_stable_win.ps1 +24 -0
  13. package/bin/reinstall_msedge_beta_linux.sh +48 -0
  14. package/bin/reinstall_msedge_beta_mac.sh +11 -0
  15. package/bin/reinstall_msedge_beta_win.ps1 +23 -0
  16. package/bin/reinstall_msedge_dev_linux.sh +48 -0
  17. package/bin/reinstall_msedge_dev_mac.sh +11 -0
  18. package/bin/reinstall_msedge_dev_win.ps1 +23 -0
  19. package/bin/reinstall_msedge_stable_linux.sh +48 -0
  20. package/bin/reinstall_msedge_stable_mac.sh +11 -0
  21. package/bin/reinstall_msedge_stable_win.ps1 +24 -0
  22. package/browsers.json +79 -0
  23. package/cli.js +18 -0
  24. package/index.d.ts +17 -0
  25. package/index.js +32 -0
  26. package/index.mjs +28 -0
  27. package/lib/androidServerImpl.js +65 -0
  28. package/lib/browserServerImpl.js +120 -0
  29. package/lib/cli/driver.js +97 -0
  30. package/lib/cli/program.js +601 -0
  31. package/lib/cli/programWithTestStub.js +74 -0
  32. package/lib/client/android.js +361 -0
  33. package/lib/client/api.js +137 -0
  34. package/lib/client/artifact.js +79 -0
  35. package/lib/client/browser.js +161 -0
  36. package/lib/client/browserContext.js +582 -0
  37. package/lib/client/browserType.js +185 -0
  38. package/lib/client/cdpSession.js +51 -0
  39. package/lib/client/channelOwner.js +194 -0
  40. package/lib/client/clientHelper.js +64 -0
  41. package/lib/client/clientInstrumentation.js +55 -0
  42. package/lib/client/clientStackTrace.js +69 -0
  43. package/lib/client/clock.js +68 -0
  44. package/lib/client/connection.js +318 -0
  45. package/lib/client/consoleMessage.js +58 -0
  46. package/lib/client/coverage.js +44 -0
  47. package/lib/client/dialog.js +56 -0
  48. package/lib/client/download.js +62 -0
  49. package/lib/client/electron.js +138 -0
  50. package/lib/client/elementHandle.js +284 -0
  51. package/lib/client/errors.js +77 -0
  52. package/lib/client/eventEmitter.js +314 -0
  53. package/lib/client/events.js +103 -0
  54. package/lib/client/fetch.js +368 -0
  55. package/lib/client/fileChooser.js +46 -0
  56. package/lib/client/fileUtils.js +34 -0
  57. package/lib/client/frame.js +409 -0
  58. package/lib/client/harRouter.js +87 -0
  59. package/lib/client/input.js +84 -0
  60. package/lib/client/jsHandle.js +109 -0
  61. package/lib/client/jsonPipe.js +39 -0
  62. package/lib/client/localUtils.js +60 -0
  63. package/lib/client/locator.js +369 -0
  64. package/lib/client/network.js +747 -0
  65. package/lib/client/page.js +743 -0
  66. package/lib/client/pageAgent.js +64 -0
  67. package/lib/client/platform.js +77 -0
  68. package/lib/client/playwright.js +71 -0
  69. package/lib/client/selectors.js +55 -0
  70. package/lib/client/stream.js +39 -0
  71. package/lib/client/timeoutSettings.js +79 -0
  72. package/lib/client/tracing.js +119 -0
  73. package/lib/client/types.js +28 -0
  74. package/lib/client/video.js +59 -0
  75. package/lib/client/waiter.js +142 -0
  76. package/lib/client/webError.js +39 -0
  77. package/lib/client/webSocket.js +93 -0
  78. package/lib/client/worker.js +85 -0
  79. package/lib/client/writableStream.js +39 -0
  80. package/lib/generated/bindingsControllerSource.js +28 -0
  81. package/lib/generated/clockSource.js +28 -0
  82. package/lib/generated/injectedScriptSource.js +28 -0
  83. package/lib/generated/pollingRecorderSource.js +28 -0
  84. package/lib/generated/storageScriptSource.js +28 -0
  85. package/lib/generated/utilityScriptSource.js +28 -0
  86. package/lib/generated/webSocketMockSource.js +336 -0
  87. package/lib/inProcessFactory.js +60 -0
  88. package/lib/inprocess.js +3 -0
  89. package/lib/mcpBundle.js +84 -0
  90. package/lib/mcpBundleImpl/index.js +147 -0
  91. package/lib/outofprocess.js +76 -0
  92. package/lib/protocol/serializers.js +197 -0
  93. package/lib/protocol/validator.js +2969 -0
  94. package/lib/protocol/validatorPrimitives.js +193 -0
  95. package/lib/remote/playwrightConnection.js +129 -0
  96. package/lib/remote/playwrightServer.js +334 -0
  97. package/lib/server/agent/actionRunner.js +335 -0
  98. package/lib/server/agent/actions.js +128 -0
  99. package/lib/server/agent/codegen.js +111 -0
  100. package/lib/server/agent/context.js +150 -0
  101. package/lib/server/agent/expectTools.js +156 -0
  102. package/lib/server/agent/pageAgent.js +204 -0
  103. package/lib/server/agent/performTools.js +262 -0
  104. package/lib/server/agent/tool.js +109 -0
  105. package/lib/server/android/android.js +465 -0
  106. package/lib/server/android/backendAdb.js +177 -0
  107. package/lib/server/artifact.js +127 -0
  108. package/lib/server/bidi/bidiBrowser.js +549 -0
  109. package/lib/server/bidi/bidiChromium.js +148 -0
  110. package/lib/server/bidi/bidiConnection.js +213 -0
  111. package/lib/server/bidi/bidiDeserializer.js +116 -0
  112. package/lib/server/bidi/bidiExecutionContext.js +267 -0
  113. package/lib/server/bidi/bidiFirefox.js +128 -0
  114. package/lib/server/bidi/bidiInput.js +146 -0
  115. package/lib/server/bidi/bidiNetworkManager.js +383 -0
  116. package/lib/server/bidi/bidiOverCdp.js +102 -0
  117. package/lib/server/bidi/bidiPage.js +583 -0
  118. package/lib/server/bidi/bidiPdf.js +106 -0
  119. package/lib/server/bidi/third_party/bidiCommands.d.js +22 -0
  120. package/lib/server/bidi/third_party/bidiKeyboard.js +256 -0
  121. package/lib/server/bidi/third_party/bidiProtocol.js +24 -0
  122. package/lib/server/bidi/third_party/bidiProtocolCore.js +180 -0
  123. package/lib/server/bidi/third_party/bidiProtocolPermissions.js +42 -0
  124. package/lib/server/bidi/third_party/bidiSerializer.js +148 -0
  125. package/lib/server/bidi/third_party/firefoxPrefs.js +259 -0
  126. package/lib/server/browser.js +149 -0
  127. package/lib/server/browserContext.js +702 -0
  128. package/lib/server/browserType.js +336 -0
  129. package/lib/server/callLog.js +82 -0
  130. package/lib/server/chromium/appIcon.png +0 -0
  131. package/lib/server/chromium/chromium.js +395 -0
  132. package/lib/server/chromium/chromiumSwitches.js +104 -0
  133. package/lib/server/chromium/crBrowser.js +511 -0
  134. package/lib/server/chromium/crConnection.js +197 -0
  135. package/lib/server/chromium/crCoverage.js +235 -0
  136. package/lib/server/chromium/crDevTools.js +111 -0
  137. package/lib/server/chromium/crDragDrop.js +131 -0
  138. package/lib/server/chromium/crExecutionContext.js +146 -0
  139. package/lib/server/chromium/crInput.js +187 -0
  140. package/lib/server/chromium/crNetworkManager.js +707 -0
  141. package/lib/server/chromium/crPage.js +1001 -0
  142. package/lib/server/chromium/crPdf.js +121 -0
  143. package/lib/server/chromium/crProtocolHelper.js +145 -0
  144. package/lib/server/chromium/crServiceWorker.js +136 -0
  145. package/lib/server/chromium/defaultFontFamilies.js +162 -0
  146. package/lib/server/chromium/protocol.d.js +16 -0
  147. package/lib/server/clock.js +149 -0
  148. package/lib/server/codegen/csharp.js +327 -0
  149. package/lib/server/codegen/java.js +274 -0
  150. package/lib/server/codegen/javascript.js +247 -0
  151. package/lib/server/codegen/jsonl.js +52 -0
  152. package/lib/server/codegen/language.js +132 -0
  153. package/lib/server/codegen/languages.js +68 -0
  154. package/lib/server/codegen/python.js +279 -0
  155. package/lib/server/codegen/types.js +16 -0
  156. package/lib/server/console.js +57 -0
  157. package/lib/server/cookieStore.js +206 -0
  158. package/lib/server/debugController.js +191 -0
  159. package/lib/server/debugger.js +119 -0
  160. package/lib/server/deviceDescriptors.js +39 -0
  161. package/lib/server/deviceDescriptorsSource.json +1779 -0
  162. package/lib/server/dialog.js +116 -0
  163. package/lib/server/dispatchers/androidDispatcher.js +325 -0
  164. package/lib/server/dispatchers/artifactDispatcher.js +118 -0
  165. package/lib/server/dispatchers/browserContextDispatcher.js +384 -0
  166. package/lib/server/dispatchers/browserDispatcher.js +118 -0
  167. package/lib/server/dispatchers/browserTypeDispatcher.js +64 -0
  168. package/lib/server/dispatchers/cdpSessionDispatcher.js +44 -0
  169. package/lib/server/dispatchers/debugControllerDispatcher.js +78 -0
  170. package/lib/server/dispatchers/dialogDispatcher.js +47 -0
  171. package/lib/server/dispatchers/dispatcher.js +364 -0
  172. package/lib/server/dispatchers/electronDispatcher.js +89 -0
  173. package/lib/server/dispatchers/elementHandlerDispatcher.js +181 -0
  174. package/lib/server/dispatchers/frameDispatcher.js +227 -0
  175. package/lib/server/dispatchers/jsHandleDispatcher.js +85 -0
  176. package/lib/server/dispatchers/jsonPipeDispatcher.js +58 -0
  177. package/lib/server/dispatchers/localUtilsDispatcher.js +149 -0
  178. package/lib/server/dispatchers/networkDispatchers.js +213 -0
  179. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  180. package/lib/server/dispatchers/pageDispatcher.js +393 -0
  181. package/lib/server/dispatchers/playwrightDispatcher.js +108 -0
  182. package/lib/server/dispatchers/streamDispatcher.js +67 -0
  183. package/lib/server/dispatchers/tracingDispatcher.js +68 -0
  184. package/lib/server/dispatchers/webSocketRouteDispatcher.js +165 -0
  185. package/lib/server/dispatchers/writableStreamDispatcher.js +79 -0
  186. package/lib/server/dom.js +815 -0
  187. package/lib/server/download.js +70 -0
  188. package/lib/server/electron/electron.js +273 -0
  189. package/lib/server/electron/loader.js +29 -0
  190. package/lib/server/errors.js +69 -0
  191. package/lib/server/fetch.js +621 -0
  192. package/lib/server/fileChooser.js +43 -0
  193. package/lib/server/fileUploadUtils.js +84 -0
  194. package/lib/server/firefox/ffBrowser.js +418 -0
  195. package/lib/server/firefox/ffConnection.js +142 -0
  196. package/lib/server/firefox/ffExecutionContext.js +150 -0
  197. package/lib/server/firefox/ffInput.js +159 -0
  198. package/lib/server/firefox/ffNetworkManager.js +256 -0
  199. package/lib/server/firefox/ffPage.js +497 -0
  200. package/lib/server/firefox/firefox.js +114 -0
  201. package/lib/server/firefox/protocol.d.js +16 -0
  202. package/lib/server/formData.js +147 -0
  203. package/lib/server/frameSelectors.js +160 -0
  204. package/lib/server/frames.js +1471 -0
  205. package/lib/server/har/harRecorder.js +147 -0
  206. package/lib/server/har/harTracer.js +607 -0
  207. package/lib/server/harBackend.js +157 -0
  208. package/lib/server/helper.js +96 -0
  209. package/lib/server/index.js +58 -0
  210. package/lib/server/input.js +277 -0
  211. package/lib/server/instrumentation.js +72 -0
  212. package/lib/server/javascript.js +291 -0
  213. package/lib/server/launchApp.js +128 -0
  214. package/lib/server/localUtils.js +214 -0
  215. package/lib/server/macEditingCommands.js +143 -0
  216. package/lib/server/network.js +667 -0
  217. package/lib/server/page.js +830 -0
  218. package/lib/server/pipeTransport.js +89 -0
  219. package/lib/server/playwright.js +69 -0
  220. package/lib/server/progress.js +132 -0
  221. package/lib/server/protocolError.js +52 -0
  222. package/lib/server/recorder/chat.js +161 -0
  223. package/lib/server/recorder/recorderApp.js +366 -0
  224. package/lib/server/recorder/recorderRunner.js +138 -0
  225. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  226. package/lib/server/recorder/recorderUtils.js +157 -0
  227. package/lib/server/recorder/throttledFile.js +57 -0
  228. package/lib/server/recorder.js +499 -0
  229. package/lib/server/registry/browserFetcher.js +177 -0
  230. package/lib/server/registry/dependencies.js +371 -0
  231. package/lib/server/registry/index.js +1422 -0
  232. package/lib/server/registry/nativeDeps.js +1280 -0
  233. package/lib/server/registry/oopDownloadBrowserMain.js +127 -0
  234. package/lib/server/screencast.js +190 -0
  235. package/lib/server/screenshotter.js +333 -0
  236. package/lib/server/selectors.js +112 -0
  237. package/lib/server/socksClientCertificatesInterceptor.js +383 -0
  238. package/lib/server/socksInterceptor.js +95 -0
  239. package/lib/server/trace/exporter/traceExporter.js +1102 -0
  240. package/lib/server/trace/recorder/snapshotter.js +147 -0
  241. package/lib/server/trace/recorder/snapshotterInjected.js +561 -0
  242. package/lib/server/trace/recorder/tracing.js +604 -0
  243. package/lib/server/trace/viewer/traceParser.js +72 -0
  244. package/lib/server/trace/viewer/traceViewer.js +245 -0
  245. package/lib/server/transport.js +181 -0
  246. package/lib/server/types.js +28 -0
  247. package/lib/server/usKeyboardLayout.js +145 -0
  248. package/lib/server/utils/ascii.js +44 -0
  249. package/lib/server/utils/comparators.js +139 -0
  250. package/lib/server/utils/crypto.js +216 -0
  251. package/lib/server/utils/debug.js +42 -0
  252. package/lib/server/utils/debugLogger.js +122 -0
  253. package/lib/server/utils/env.js +73 -0
  254. package/lib/server/utils/eventsHelper.js +39 -0
  255. package/lib/server/utils/expectUtils.js +123 -0
  256. package/lib/server/utils/fileUtils.js +191 -0
  257. package/lib/server/utils/happyEyeballs.js +207 -0
  258. package/lib/server/utils/hostPlatform.js +123 -0
  259. package/lib/server/utils/httpServer.js +203 -0
  260. package/lib/server/utils/imageUtils.js +141 -0
  261. package/lib/server/utils/image_tools/colorUtils.js +89 -0
  262. package/lib/server/utils/image_tools/compare.js +109 -0
  263. package/lib/server/utils/image_tools/imageChannel.js +78 -0
  264. package/lib/server/utils/image_tools/stats.js +102 -0
  265. package/lib/server/utils/linuxUtils.js +71 -0
  266. package/lib/server/utils/network.js +242 -0
  267. package/lib/server/utils/nodePlatform.js +154 -0
  268. package/lib/server/utils/pipeTransport.js +84 -0
  269. package/lib/server/utils/processLauncher.js +241 -0
  270. package/lib/server/utils/profiler.js +65 -0
  271. package/lib/server/utils/socksProxy.js +511 -0
  272. package/lib/server/utils/spawnAsync.js +41 -0
  273. package/lib/server/utils/task.js +51 -0
  274. package/lib/server/utils/userAgent.js +98 -0
  275. package/lib/server/utils/wsServer.js +121 -0
  276. package/lib/server/utils/zipFile.js +74 -0
  277. package/lib/server/utils/zones.js +57 -0
  278. package/lib/server/videoRecorder.js +124 -0
  279. package/lib/server/webkit/protocol.d.js +16 -0
  280. package/lib/server/webkit/webkit.js +108 -0
  281. package/lib/server/webkit/wkBrowser.js +335 -0
  282. package/lib/server/webkit/wkConnection.js +144 -0
  283. package/lib/server/webkit/wkExecutionContext.js +154 -0
  284. package/lib/server/webkit/wkInput.js +181 -0
  285. package/lib/server/webkit/wkInterceptableRequest.js +197 -0
  286. package/lib/server/webkit/wkPage.js +1158 -0
  287. package/lib/server/webkit/wkProvisionalPage.js +83 -0
  288. package/lib/server/webkit/wkWorkers.js +105 -0
  289. package/lib/third_party/pixelmatch.js +255 -0
  290. package/lib/utils/isomorphic/ariaSnapshot.js +455 -0
  291. package/lib/utils/isomorphic/assert.js +31 -0
  292. package/lib/utils/isomorphic/colors.js +72 -0
  293. package/lib/utils/isomorphic/cssParser.js +245 -0
  294. package/lib/utils/isomorphic/cssTokenizer.js +1051 -0
  295. package/lib/utils/isomorphic/headers.js +53 -0
  296. package/lib/utils/isomorphic/locatorGenerators.js +689 -0
  297. package/lib/utils/isomorphic/locatorParser.js +176 -0
  298. package/lib/utils/isomorphic/locatorUtils.js +81 -0
  299. package/lib/utils/isomorphic/lruCache.js +51 -0
  300. package/lib/utils/isomorphic/manualPromise.js +114 -0
  301. package/lib/utils/isomorphic/mimeType.js +459 -0
  302. package/lib/utils/isomorphic/multimap.js +80 -0
  303. package/lib/utils/isomorphic/protocolFormatter.js +81 -0
  304. package/lib/utils/isomorphic/protocolMetainfo.js +330 -0
  305. package/lib/utils/isomorphic/rtti.js +43 -0
  306. package/lib/utils/isomorphic/selectorParser.js +386 -0
  307. package/lib/utils/isomorphic/semaphore.js +54 -0
  308. package/lib/utils/isomorphic/stackTrace.js +158 -0
  309. package/lib/utils/isomorphic/stringUtils.js +204 -0
  310. package/lib/utils/isomorphic/time.js +49 -0
  311. package/lib/utils/isomorphic/timeoutRunner.js +66 -0
  312. package/lib/utils/isomorphic/trace/entries.js +16 -0
  313. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  314. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  315. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  316. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  317. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  318. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  319. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  320. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  321. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  322. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  323. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  324. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  325. package/lib/utils/isomorphic/traceUtils.js +58 -0
  326. package/lib/utils/isomorphic/types.js +16 -0
  327. package/lib/utils/isomorphic/urlMatch.js +190 -0
  328. package/lib/utils/isomorphic/utilityScriptSerializers.js +251 -0
  329. package/lib/utils/isomorphic/yaml.js +84 -0
  330. package/lib/utils.js +111 -0
  331. package/lib/utilsBundle.js +112 -0
  332. package/lib/utilsBundleImpl/index.js +218 -0
  333. package/lib/utilsBundleImpl/xdg-open +1066 -0
  334. package/lib/vite/htmlReport/index.html +84 -0
  335. package/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css +1 -0
  336. package/lib/vite/recorder/assets/codeMirrorModule-DadYNm1I.js +32 -0
  337. package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
  338. package/lib/vite/recorder/assets/index-BSjZa4pk.css +1 -0
  339. package/lib/vite/recorder/assets/index-BhTWtUlo.js +193 -0
  340. package/lib/vite/recorder/index.html +29 -0
  341. package/lib/vite/recorder/playwright-logo.svg +9 -0
  342. package/lib/vite/traceViewer/assets/codeMirrorModule-a5XoALAZ.js +32 -0
  343. package/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js +266 -0
  344. package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
  345. package/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +1 -0
  346. package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  347. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  348. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  349. package/lib/vite/traceViewer/index.Dd9jebqr.js +2 -0
  350. package/lib/vite/traceViewer/index.html +43 -0
  351. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  352. package/lib/vite/traceViewer/playwright-logo.svg +9 -0
  353. package/lib/vite/traceViewer/snapshot.html +21 -0
  354. package/lib/vite/traceViewer/sw.bundle.js +5 -0
  355. package/lib/vite/traceViewer/uiMode.Btcz36p_.css +1 -0
  356. package/lib/vite/traceViewer/uiMode.CQJ9SCIQ.js +5 -0
  357. package/lib/vite/traceViewer/uiMode.html +17 -0
  358. package/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +32 -0
  359. package/lib/zipBundle.js +34 -0
  360. package/lib/zipBundleImpl.js +5 -0
  361. package/package.json +43 -0
  362. package/types/protocol.d.ts +23824 -0
  363. package/types/structs.d.ts +45 -0
  364. package/types/types.d.ts +23170 -0
@@ -0,0 +1,1102 @@
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 traceExporter_exports = {};
30
+ __export(traceExporter_exports, {
31
+ exportTraceToMarkdown: () => exportTraceToMarkdown
32
+ });
33
+ module.exports = __toCommonJS(traceExporter_exports);
34
+ var import_fs = __toESM(require("fs"));
35
+ var import_path = __toESM(require("path"));
36
+ var import_zipFile = require("../../utils/zipFile");
37
+ var import_stringUtils = require("../../../utils/isomorphic/stringUtils");
38
+ async function exportTraceToMarkdown(traceFile, options) {
39
+ const context = await parseTrace(traceFile);
40
+ const outputDir = options.outputDir;
41
+ const assetsDir = import_path.default.join(outputDir, "assets");
42
+ const snapshotsDir = import_path.default.join(assetsDir, "snapshots");
43
+ await import_fs.default.promises.mkdir(outputDir, { recursive: true });
44
+ await import_fs.default.promises.mkdir(snapshotsDir, { recursive: true });
45
+ const assetMap = await extractAssets(traceFile, context, outputDir);
46
+ const files = [
47
+ { name: "README.md", content: generateReadmeMarkdown() },
48
+ { name: "index.md", content: generateIndexMarkdown(context, traceFile) },
49
+ { name: "metadata.md", content: generateMetadataMarkdown(context) },
50
+ { name: "timeline.md", content: generateTimelineMarkdown(context.actions, assetMap, buildStepSnapshotMap(context.actions)) },
51
+ { name: "errors.md", content: generateErrorsMarkdown(context.errors, context.actions) },
52
+ { name: "console.md", content: generateConsoleMarkdown(context.events) },
53
+ { name: "network.md", content: generateNetworkMarkdown(context.resources) },
54
+ { name: "filmstrip.md", content: generateFilmstripMarkdown(context.pages, context.startTime, assetMap) },
55
+ { name: "attachments.md", content: generateAttachmentsMarkdown(context.actions, assetMap) }
56
+ ];
57
+ for (const file of files)
58
+ await import_fs.default.promises.writeFile(import_path.default.join(outputDir, file.name), file.content);
59
+ }
60
+ async function parseTrace(traceFile) {
61
+ const zipFile = new import_zipFile.ZipFile(traceFile);
62
+ const entries = await zipFile.entries();
63
+ const context = {
64
+ browserName: "Unknown",
65
+ wallTime: 0,
66
+ startTime: Number.MAX_SAFE_INTEGER,
67
+ endTime: 0,
68
+ options: {},
69
+ actions: [],
70
+ events: [],
71
+ errors: [],
72
+ resources: [],
73
+ pages: [],
74
+ snapshots: [],
75
+ networkResourceMap: /* @__PURE__ */ new Map()
76
+ };
77
+ const actionMap = /* @__PURE__ */ new Map();
78
+ const pageMap = /* @__PURE__ */ new Map();
79
+ const traceEntries = entries.filter((name) => name.endsWith(".trace"));
80
+ const networkEntries = entries.filter((name) => name.endsWith(".network"));
81
+ for (const entryName of [...traceEntries, ...networkEntries]) {
82
+ const content = await zipFile.read(entryName);
83
+ const lines = content.toString("utf-8").split("\n");
84
+ for (const line of lines) {
85
+ if (!line.trim())
86
+ continue;
87
+ try {
88
+ const event = JSON.parse(line);
89
+ processTraceEvent(event, context, actionMap, pageMap);
90
+ } catch {
91
+ }
92
+ }
93
+ }
94
+ context.actions = [...actionMap.values()].sort((a, b) => a.startTime - b.startTime);
95
+ context.pages = [...pageMap.values()];
96
+ for (const action of context.actions) {
97
+ if (action.endTime > context.endTime)
98
+ context.endTime = action.endTime;
99
+ }
100
+ zipFile.close();
101
+ return context;
102
+ }
103
+ function processTraceEvent(event, context, actionMap, pageMap) {
104
+ switch (event.type) {
105
+ case "context-options":
106
+ context.browserName = event.browserName || "Unknown";
107
+ context.channel = event.channel;
108
+ context.title = event.title;
109
+ context.platform = event.platform;
110
+ context.playwrightVersion = event.playwrightVersion;
111
+ context.wallTime = event.wallTime || 0;
112
+ context.startTime = event.monotonicTime || 0;
113
+ context.sdkLanguage = event.sdkLanguage;
114
+ context.options = event.options || {};
115
+ break;
116
+ case "before":
117
+ actionMap.set(event.callId, {
118
+ callId: event.callId,
119
+ class: event.class,
120
+ method: event.method,
121
+ params: event.params || {},
122
+ startTime: event.startTime || 0,
123
+ endTime: 0,
124
+ log: [],
125
+ stack: event.stack,
126
+ beforeSnapshot: event.beforeSnapshot,
127
+ pageId: event.pageId,
128
+ parentId: event.parentId,
129
+ title: event.title,
130
+ group: event.group,
131
+ stepId: event.stepId
132
+ });
133
+ break;
134
+ case "after":
135
+ const action = actionMap.get(event.callId);
136
+ if (action) {
137
+ action.endTime = event.endTime || action.startTime;
138
+ action.error = event.error;
139
+ action.result = event.result;
140
+ action.afterSnapshot = event.afterSnapshot;
141
+ if (event.attachments?.length) {
142
+ action.attachments = event.attachments.map((a) => ({
143
+ name: a.name,
144
+ contentType: a.contentType,
145
+ path: a.path,
146
+ sha1: a.sha1
147
+ }));
148
+ }
149
+ }
150
+ break;
151
+ case "log":
152
+ const logAction = actionMap.get(event.callId);
153
+ if (logAction) {
154
+ logAction.log.push({
155
+ time: event.time || 0,
156
+ message: event.message || ""
157
+ });
158
+ }
159
+ break;
160
+ case "console":
161
+ context.events.push({
162
+ type: "console",
163
+ time: event.time || 0,
164
+ messageType: event.messageType,
165
+ text: event.text,
166
+ location: event.location
167
+ });
168
+ break;
169
+ case "error":
170
+ context.errors.push({
171
+ message: event.message || "Unknown error",
172
+ stack: event.stack
173
+ });
174
+ break;
175
+ case "resource-snapshot":
176
+ if (event.snapshot) {
177
+ const url = event.snapshot.request?.url || "";
178
+ const sha1 = event.snapshot.response?.content?._sha1;
179
+ context.resources.push({
180
+ request: {
181
+ method: event.snapshot.request?.method || "GET",
182
+ url
183
+ },
184
+ response: {
185
+ status: event.snapshot.response?.status || 0,
186
+ content: event.snapshot.response?.content,
187
+ _failureText: event.snapshot.response?._failureText
188
+ }
189
+ });
190
+ if (url && sha1)
191
+ context.networkResourceMap.set(url, sha1);
192
+ }
193
+ break;
194
+ case "screencast-frame":
195
+ let page = pageMap.get(event.pageId);
196
+ if (!page) {
197
+ page = { pageId: event.pageId, screencastFrames: [] };
198
+ pageMap.set(event.pageId, page);
199
+ }
200
+ page.screencastFrames.push({
201
+ sha1: event.sha1,
202
+ timestamp: event.timestamp || 0
203
+ });
204
+ break;
205
+ case "frame-snapshot":
206
+ if (event.snapshot) {
207
+ context.snapshots.push({
208
+ snapshotName: event.snapshot.snapshotName || "",
209
+ callId: event.snapshot.callId || "",
210
+ pageId: event.snapshot.pageId || "",
211
+ frameId: event.snapshot.frameId || "",
212
+ frameUrl: event.snapshot.frameUrl || "",
213
+ html: event.snapshot.html,
214
+ timestamp: event.snapshot.timestamp || 0,
215
+ resourceOverrides: event.snapshot.resourceOverrides || [],
216
+ doctype: event.snapshot.doctype,
217
+ viewport: event.snapshot.viewport
218
+ });
219
+ }
220
+ break;
221
+ }
222
+ }
223
+ async function extractAssets(traceFile, context, outputDir) {
224
+ const assetMap = /* @__PURE__ */ new Map();
225
+ const zipFile = new import_zipFile.ZipFile(traceFile);
226
+ const entries = await zipFile.entries();
227
+ const resourcesDir = import_path.default.join(outputDir, "assets", "resources");
228
+ await import_fs.default.promises.mkdir(resourcesDir, { recursive: true });
229
+ const snapshotsByFrame = /* @__PURE__ */ new Map();
230
+ for (const snapshot of context.snapshots) {
231
+ let frameSnapshots = snapshotsByFrame.get(snapshot.frameId);
232
+ if (!frameSnapshots) {
233
+ frameSnapshots = [];
234
+ snapshotsByFrame.set(snapshot.frameId, frameSnapshots);
235
+ }
236
+ frameSnapshots.push(snapshot);
237
+ }
238
+ const neededSha1s = /* @__PURE__ */ new Set();
239
+ for (const snapshot of context.snapshots) {
240
+ const frameSnapshots = snapshotsByFrame.get(snapshot.frameId) || [];
241
+ const snapshotIndex = frameSnapshots.indexOf(snapshot);
242
+ for (const override of snapshot.resourceOverrides) {
243
+ if (override.sha1) {
244
+ neededSha1s.add(override.sha1);
245
+ } else if (override.ref !== void 0 && snapshotIndex >= 0) {
246
+ const refIndex = snapshotIndex - override.ref;
247
+ if (refIndex >= 0 && refIndex < frameSnapshots.length) {
248
+ const refSnapshot = frameSnapshots[refIndex];
249
+ const refOverride = refSnapshot.resourceOverrides.find((o) => o.url === override.url);
250
+ if (refOverride?.sha1)
251
+ neededSha1s.add(refOverride.sha1);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ for (const page of context.pages) {
257
+ for (const frame of page.screencastFrames)
258
+ neededSha1s.add(frame.sha1);
259
+ }
260
+ for (const sha1 of context.networkResourceMap.values())
261
+ neededSha1s.add(sha1);
262
+ const attachmentMap = /* @__PURE__ */ new Map();
263
+ for (const action of context.actions) {
264
+ if (action.attachments) {
265
+ for (const attachment of action.attachments) {
266
+ if (attachment.sha1)
267
+ attachmentMap.set(attachment.sha1, attachment.name);
268
+ }
269
+ }
270
+ }
271
+ for (const sha1 of neededSha1s) {
272
+ if (attachmentMap.has(sha1))
273
+ continue;
274
+ const resourcePath = `resources/${sha1}`;
275
+ if (!entries.includes(resourcePath))
276
+ continue;
277
+ try {
278
+ const buffer = await zipFile.read(resourcePath);
279
+ const fullPath = import_path.default.join(resourcesDir, sha1);
280
+ await import_fs.default.promises.writeFile(fullPath, buffer);
281
+ assetMap.set(sha1, `./assets/resources/${sha1}`);
282
+ } catch {
283
+ }
284
+ }
285
+ const attachmentsDir = import_path.default.join(outputDir, "assets", "attachments");
286
+ await import_fs.default.promises.mkdir(attachmentsDir, { recursive: true });
287
+ for (const [sha1, filename] of attachmentMap) {
288
+ const resourcePath = `resources/${sha1}`;
289
+ if (!entries.includes(resourcePath))
290
+ continue;
291
+ try {
292
+ const buffer = await zipFile.read(resourcePath);
293
+ const safeName = filename.replace(/[/\\:*?"<>|]/g, "_");
294
+ const fullPath = import_path.default.join(attachmentsDir, safeName);
295
+ await import_fs.default.promises.writeFile(fullPath, buffer);
296
+ assetMap.set(sha1, `./assets/attachments/${safeName}`);
297
+ } catch {
298
+ }
299
+ }
300
+ const snapshotsDir = import_path.default.join(outputDir, "assets", "snapshots");
301
+ await import_fs.default.promises.mkdir(snapshotsDir, { recursive: true });
302
+ for (const snapshot of context.snapshots) {
303
+ if (!snapshot.html || !snapshot.snapshotName)
304
+ continue;
305
+ try {
306
+ const frameSnapshots = snapshotsByFrame.get(snapshot.frameId) || [];
307
+ const snapshotIndex = frameSnapshots.indexOf(snapshot);
308
+ const renderer = new ExportSnapshotRenderer(frameSnapshots, snapshotIndex, context.networkResourceMap);
309
+ const html = renderer.render();
310
+ for (const sha1 of renderer.getUsedSha1s()) {
311
+ if (!assetMap.has(sha1)) {
312
+ const resourcePath = `resources/${sha1}`;
313
+ if (entries.includes(resourcePath)) {
314
+ try {
315
+ const buffer = await zipFile.read(resourcePath);
316
+ const fullPath2 = import_path.default.join(resourcesDir, sha1);
317
+ await import_fs.default.promises.writeFile(fullPath2, buffer);
318
+ assetMap.set(sha1, `./assets/resources/${sha1}`);
319
+ } catch {
320
+ }
321
+ }
322
+ }
323
+ }
324
+ const safeName = snapshot.snapshotName.replace(/[^a-zA-Z0-9@_-]/g, "_");
325
+ const relativePath = `assets/snapshots/${safeName}.html`;
326
+ const fullPath = import_path.default.join(outputDir, relativePath);
327
+ await import_fs.default.promises.writeFile(fullPath, html);
328
+ assetMap.set(snapshot.snapshotName, `./${relativePath}`);
329
+ } catch {
330
+ }
331
+ }
332
+ zipFile.close();
333
+ return assetMap;
334
+ }
335
+ function generateReadmeMarkdown() {
336
+ return `# Playwright Trace Export
337
+
338
+ This folder contains a Playwright trace exported to LLM-friendly Markdown format.
339
+
340
+ ## Contents
341
+
342
+ - **index.md** - Overview with test status and error summary
343
+ - **timeline.md** - Step-by-step action timeline with links to DOM snapshots
344
+ - **metadata.md** - Browser and environment information
345
+ - **errors.md** - Full error details with stack traces
346
+ - **console.md** - Browser console output
347
+ - **network.md** - HTTP request log
348
+ - **filmstrip.md** - Screenshot timeline
349
+ - **attachments.md** - Test attachments
350
+
351
+ ## Viewing DOM Snapshots
352
+
353
+ The exported DOM snapshots include CSS and can be viewed in a browser. Since snapshots use relative paths, you need to serve them via HTTP:
354
+
355
+ \`\`\`bash
356
+ # Using npx serve
357
+ npx serve
358
+
359
+ # Or using Python
360
+ python -m http.server 8000
361
+ \`\`\`
362
+
363
+ Then open the snapshot URLs from \`timeline.md\`, for example:
364
+ - http://localhost:3000/assets/snapshots/after@call@123.html (npx serve)
365
+ - http://localhost:8000/assets/snapshots/after@call@123.html (Python)
366
+
367
+ ## Loading Snapshots with Playwright
368
+
369
+ You can load exported snapshots into Playwright for automated DOM inspection:
370
+
371
+ \`\`\`js
372
+ const { chromium } = require('playwright');
373
+
374
+ (async () => {
375
+ const browser = await chromium.launch();
376
+ const page = await browser.newPage();
377
+
378
+ // Serve the export directory first, then:
379
+ await page.goto('http://localhost:3000/assets/snapshots/after@call@123.html');
380
+
381
+ // Inspect the DOM
382
+ const title = await page.title();
383
+ const buttons = await page.locator('button').all();
384
+ console.log(\`Page has \${buttons.length} buttons\`);
385
+
386
+ await browser.close();
387
+ })();
388
+ \`\`\`
389
+
390
+ This is useful for LLM-based analysis where the AI can navigate and inspect the captured page state.
391
+ `;
392
+ }
393
+ function generateIndexMarkdown(context, traceFile) {
394
+ const title = context.title || "Trace Export";
395
+ const duration = Math.round(context.endTime - context.startTime);
396
+ const actionCount = context.actions.length;
397
+ const errorCount = context.errors.length + context.actions.filter((a) => a.error).length;
398
+ const hasErrors = errorCount > 0;
399
+ const errorSummary = collectErrorSummary(context);
400
+ let md = `# Trace Export: ${title}
401
+
402
+ `;
403
+ md += `**Test:** \`${title}\`
404
+ `;
405
+ md += `**Source:** \`${traceFile}\`
406
+
407
+ `;
408
+ md += `**Status:** ${hasErrors ? "FAILED" : "PASSED"} | **Duration:** ${duration}ms | **Actions:** ${actionCount} | **Errors:** ${errorCount}
409
+
410
+ `;
411
+ if (errorSummary.length > 0) {
412
+ md += `## Error Summary
413
+ `;
414
+ for (const error of errorSummary)
415
+ md += `- ${error}
416
+ `;
417
+ md += "\n";
418
+ }
419
+ md += `## Sections
420
+ `;
421
+ md += `- [Timeline](./timeline.md) - Step-by-step action timeline
422
+ `;
423
+ md += `- [Metadata](./metadata.md) - Browser/environment info
424
+ `;
425
+ md += `- [Errors](./errors.md) - Full error details with stack traces
426
+ `;
427
+ md += `- [Console](./console.md) - Browser console output
428
+ `;
429
+ md += `- [Network](./network.md) - HTTP request log
430
+ `;
431
+ md += `- [Filmstrip](./filmstrip.md) - Screenshot timeline
432
+ `;
433
+ md += `- [Attachments](./attachments.md) - Test attachments
434
+ `;
435
+ return md;
436
+ }
437
+ function collectErrorSummary(context) {
438
+ const errors = [];
439
+ for (const error of context.errors)
440
+ errors.push(truncateString(stripAnsi(error.message), 100));
441
+ for (const action of context.actions) {
442
+ if (action.error)
443
+ errors.push(truncateString(stripAnsi(action.error.message), 100));
444
+ }
445
+ return errors.slice(0, 10);
446
+ }
447
+ function generateMetadataMarkdown(context) {
448
+ let md = `# Trace Metadata
449
+
450
+ `;
451
+ md += `## Environment
452
+
453
+ `;
454
+ md += `| Property | Value |
455
+ `;
456
+ md += `|----------|-------|
457
+ `;
458
+ md += `| Browser | ${context.browserName || "Unknown"} |
459
+ `;
460
+ if (context.channel)
461
+ md += `| Channel | ${context.channel} |
462
+ `;
463
+ if (context.platform)
464
+ md += `| Platform | ${context.platform} |
465
+ `;
466
+ if (context.playwrightVersion)
467
+ md += `| Playwright Version | ${context.playwrightVersion} |
468
+ `;
469
+ if (context.sdkLanguage)
470
+ md += `| SDK Language | ${context.sdkLanguage} |
471
+ `;
472
+ md += `
473
+ ## Context Options
474
+
475
+ `;
476
+ md += `| Property | Value |
477
+ `;
478
+ md += `|----------|-------|
479
+ `;
480
+ if (context.options.viewport)
481
+ md += `| Viewport | ${context.options.viewport.width}x${context.options.viewport.height} |
482
+ `;
483
+ if (context.options.deviceScaleFactor)
484
+ md += `| Device Scale Factor | ${context.options.deviceScaleFactor} |
485
+ `;
486
+ if (context.options.isMobile !== void 0)
487
+ md += `| Mobile | ${context.options.isMobile} |
488
+ `;
489
+ if (context.options.userAgent)
490
+ md += `| User Agent | ${truncateString(context.options.userAgent, 80)} |
491
+ `;
492
+ if (context.options.baseURL)
493
+ md += `| Base URL | ${context.options.baseURL} |
494
+ `;
495
+ md += `
496
+ ## Timing
497
+
498
+ `;
499
+ md += `| Property | Value |
500
+ `;
501
+ md += `|----------|-------|
502
+ `;
503
+ md += `| Wall Time | ${new Date(context.wallTime).toISOString()} |
504
+ `;
505
+ md += `| Duration | ${Math.round(context.endTime - context.startTime)}ms |
506
+ `;
507
+ return md;
508
+ }
509
+ function buildActionTree(actions) {
510
+ const itemMap = /* @__PURE__ */ new Map();
511
+ for (const action of actions) {
512
+ itemMap.set(action.callId, {
513
+ action,
514
+ children: [],
515
+ parent: void 0
516
+ });
517
+ }
518
+ const rootItem = {
519
+ action: {
520
+ callId: "root",
521
+ class: "Root",
522
+ method: "",
523
+ params: {},
524
+ startTime: actions[0]?.startTime || 0,
525
+ endTime: actions[actions.length - 1]?.endTime || 0,
526
+ log: []
527
+ },
528
+ children: [],
529
+ parent: void 0
530
+ };
531
+ for (const item of itemMap.values()) {
532
+ const parent = item.action.parentId ? itemMap.get(item.action.parentId) || rootItem : rootItem;
533
+ parent.children.push(item);
534
+ item.parent = parent;
535
+ }
536
+ const sortChildren = (item) => {
537
+ item.children.sort((a, b) => a.action.startTime - b.action.startTime);
538
+ for (const child of item.children)
539
+ sortChildren(child);
540
+ };
541
+ sortChildren(rootItem);
542
+ return rootItem;
543
+ }
544
+ function getActionTitle(action) {
545
+ if (action.title)
546
+ return action.title;
547
+ return `${action.class}.${action.method}`;
548
+ }
549
+ function buildStepSnapshotMap(actions) {
550
+ const map = /* @__PURE__ */ new Map();
551
+ for (const action of actions) {
552
+ if (action.stepId && (action.beforeSnapshot || action.afterSnapshot)) {
553
+ const existing = map.get(action.stepId) || {};
554
+ if (action.beforeSnapshot)
555
+ existing.before = action.beforeSnapshot;
556
+ if (action.afterSnapshot)
557
+ existing.after = action.afterSnapshot;
558
+ map.set(action.stepId, existing);
559
+ }
560
+ }
561
+ return map;
562
+ }
563
+ function generateTimelineMarkdown(actions, assetMap, stepSnapshotMap) {
564
+ if (actions.length === 0)
565
+ return `# Actions Timeline
566
+
567
+ No actions recorded.
568
+ `;
569
+ const filteredActions = actions.filter((action) => action.class === "Test");
570
+ const startTime = filteredActions[0]?.startTime || 0;
571
+ const totalDuration = filteredActions.length > 0 ? (filteredActions[filteredActions.length - 1].endTime || filteredActions[filteredActions.length - 1].startTime) - startTime : 0;
572
+ let md = `# Actions Timeline
573
+
574
+ `;
575
+ md += `Total actions: ${filteredActions.length} | Duration: ${Math.round(totalDuration)}ms
576
+
577
+ `;
578
+ const rootItem = buildActionTree(filteredActions);
579
+ const renderItem = (item, prefix, index, depth) => {
580
+ const action = item.action;
581
+ if (action.callId === "root")
582
+ return;
583
+ const number = prefix ? `${prefix}.${index}` : `${index}`;
584
+ const relativeTime = action.startTime - startTime;
585
+ const duration = (action.endTime || action.startTime) - action.startTime;
586
+ const hasError = !!action.error;
587
+ const title = getActionTitle(action);
588
+ const headingLevel = Math.min(depth + 1, 6);
589
+ const heading = "#".repeat(headingLevel);
590
+ md += `${heading} ${number}. ${title}${hasError ? " - ERROR" : ""}
591
+
592
+ `;
593
+ md += `- **Start:** ${Math.round(relativeTime)}ms
594
+ `;
595
+ md += `- **Duration:** ${Math.round(duration)}ms
596
+ `;
597
+ if (action.params && Object.keys(action.params).length > 0 && action.group !== "internal") {
598
+ const paramsStr = formatParams(action.params);
599
+ if (paramsStr !== "{}")
600
+ md += `- **Params:** \`${paramsStr}\`
601
+ `;
602
+ }
603
+ if (hasError)
604
+ md += `- **Error:** ${stripAnsi(action.error.message)}
605
+ `;
606
+ else if (action.result !== void 0 && action.group !== "internal")
607
+ md += `- **Result:** ${formatResult(action.result)}
608
+ `;
609
+ if (action.stack && action.stack.length > 0) {
610
+ const frame = action.stack[0];
611
+ md += `- **Source:** \`${frame.file}:${frame.line}\`
612
+ `;
613
+ }
614
+ const stepSnapshots = stepSnapshotMap.get(action.callId);
615
+ const beforeSnapshotName = action.beforeSnapshot || stepSnapshots?.before;
616
+ const afterSnapshotName = action.afterSnapshot || stepSnapshots?.after;
617
+ const beforeSnapshot = beforeSnapshotName ? resolveSnapshotLink(beforeSnapshotName, assetMap) : null;
618
+ const afterSnapshot = afterSnapshotName ? resolveSnapshotLink(afterSnapshotName, assetMap) : null;
619
+ if (beforeSnapshot || afterSnapshot) {
620
+ const links = [];
621
+ if (beforeSnapshot)
622
+ links.push(`[before](${beforeSnapshot})`);
623
+ if (afterSnapshot)
624
+ links.push(`[after](${afterSnapshot})`);
625
+ md += `- **Snapshots:** ${links.join(" | ")}
626
+ `;
627
+ }
628
+ if (action.attachments && action.attachments.length > 0) {
629
+ const attachmentLinks = action.attachments.filter((a) => a.sha1).map((a) => {
630
+ const resourcePath = assetMap.get(a.sha1) || `./assets/resources/${a.sha1}`;
631
+ return `[${a.name}](${resourcePath})`;
632
+ });
633
+ if (attachmentLinks.length > 0)
634
+ md += `- **Attachments:** ${attachmentLinks.join(" | ")}
635
+ `;
636
+ }
637
+ if (action.log && action.log.length > 0) {
638
+ md += `
639
+ <details><summary>Action Log</summary>
640
+
641
+ `;
642
+ for (const entry of action.log)
643
+ md += `- ${entry.message}
644
+ `;
645
+ md += `
646
+ </details>
647
+ `;
648
+ }
649
+ if (hasError && action.stack && action.stack.length > 0) {
650
+ md += `
651
+ <details><summary>Stack Trace</summary>
652
+
653
+ `;
654
+ md += "```\n";
655
+ md += `Error: ${stripAnsi(action.error.message)}
656
+ `;
657
+ for (const frame of action.stack)
658
+ md += ` at ${frame.function || "(anonymous)"} (${frame.file}:${frame.line}:${frame.column})
659
+ `;
660
+ md += "```\n\n";
661
+ md += `</details>
662
+ `;
663
+ }
664
+ md += `
665
+ `;
666
+ for (let i = 0; i < item.children.length; i++)
667
+ renderItem(item.children[i], number, i + 1, depth + 1);
668
+ };
669
+ for (let i = 0; i < rootItem.children.length; i++)
670
+ renderItem(rootItem.children[i], "", i + 1, 1);
671
+ return md;
672
+ }
673
+ function resolveSnapshotLink(snapshotName, assetMap) {
674
+ if (assetMap.has(snapshotName))
675
+ return assetMap.get(snapshotName);
676
+ for (const [key, assetPath] of assetMap) {
677
+ if (snapshotName.includes(key) || key.includes(snapshotName))
678
+ return assetPath;
679
+ }
680
+ return null;
681
+ }
682
+ function generateErrorsMarkdown(errors, actions) {
683
+ const allErrors = [];
684
+ for (const error of errors) {
685
+ allErrors.push({
686
+ message: stripAnsi(error.message),
687
+ stack: error.stack
688
+ });
689
+ }
690
+ for (const action of actions) {
691
+ if (action.error) {
692
+ allErrors.push({
693
+ message: stripAnsi(action.error.message),
694
+ stack: action.stack,
695
+ source: action.stack?.[0] ? `${action.stack[0].file}:${action.stack[0].line}` : void 0
696
+ });
697
+ }
698
+ }
699
+ if (allErrors.length === 0)
700
+ return `# Errors
701
+
702
+ No errors recorded.
703
+ `;
704
+ let md = `# Errors
705
+
706
+ `;
707
+ md += `Total errors: ${allErrors.length}
708
+
709
+ `;
710
+ for (let i = 0; i < allErrors.length; i++) {
711
+ const error = allErrors[i];
712
+ md += `## Error ${i + 1}
713
+
714
+ `;
715
+ md += `**Message:** ${error.message}
716
+
717
+ `;
718
+ if (error.source)
719
+ md += `**Source:** \`${error.source}\`
720
+
721
+ `;
722
+ if (error.stack && error.stack.length > 0) {
723
+ md += `**Stack Trace:**
724
+
725
+ `;
726
+ md += "```\n";
727
+ for (const frame of error.stack)
728
+ md += ` at ${frame.function || "(anonymous)"} (${frame.file}:${frame.line}:${frame.column})
729
+ `;
730
+ md += "```\n\n";
731
+ }
732
+ md += `---
733
+
734
+ `;
735
+ }
736
+ return md;
737
+ }
738
+ function generateConsoleMarkdown(events) {
739
+ const consoleEvents = events.filter((e) => e.type === "console");
740
+ if (consoleEvents.length === 0)
741
+ return `# Console Log
742
+
743
+ No console messages recorded.
744
+ `;
745
+ let md = `# Console Log
746
+
747
+ `;
748
+ md += `Total messages: ${consoleEvents.length}
749
+
750
+ `;
751
+ md += `| Time | Type | Message | Location |
752
+ `;
753
+ md += `|------|------|---------|----------|
754
+ `;
755
+ for (const event of consoleEvents) {
756
+ const message = truncateString(event.text || "", 100).replace(/\|/g, "\\|").replace(/\n/g, " ");
757
+ const location = event.location ? `${event.location.url}:${event.location.lineNumber}` : "";
758
+ md += `| ${event.time}ms | ${event.messageType || "log"} | ${message} | ${truncateString(location, 50)} |
759
+ `;
760
+ }
761
+ return md;
762
+ }
763
+ function generateNetworkMarkdown(resources) {
764
+ if (resources.length === 0)
765
+ return `# Network Log
766
+
767
+ No network requests recorded.
768
+ `;
769
+ let md = `# Network Log
770
+
771
+ `;
772
+ md += `Total requests: ${resources.length}
773
+
774
+ `;
775
+ md += `| # | Method | URL | Status | Size |
776
+ `;
777
+ md += `|---|--------|-----|--------|------|
778
+ `;
779
+ const failedRequests = [];
780
+ for (let i = 0; i < resources.length; i++) {
781
+ const resource = resources[i];
782
+ const url = truncateString(resource.request.url, 60);
783
+ const status = resource.response.status;
784
+ const size = formatSize(resource.response.content?.size || 0);
785
+ md += `| ${i + 1} | ${resource.request.method} | ${url} | ${status} | ${size} |
786
+ `;
787
+ if (status >= 400)
788
+ failedRequests.push(resource);
789
+ }
790
+ if (failedRequests.length > 0) {
791
+ md += `
792
+ ## Failed Requests
793
+
794
+ `;
795
+ for (const resource of failedRequests) {
796
+ md += `### ${resource.request.method} ${truncateString(resource.request.url, 80)} - ${resource.response.status}
797
+
798
+ `;
799
+ if (resource.response._failureText)
800
+ md += `**Failure:** ${resource.response._failureText}
801
+
802
+ `;
803
+ if (resource.response.content?.text) {
804
+ md += `<details><summary>Response</summary>
805
+
806
+ `;
807
+ md += "```\n";
808
+ md += truncateString(resource.response.content.text, 1e3);
809
+ md += "\n```\n\n";
810
+ md += `</details>
811
+
812
+ `;
813
+ }
814
+ }
815
+ }
816
+ return md;
817
+ }
818
+ function generateFilmstripMarkdown(pages, startTime, assetMap) {
819
+ const allFrames = [];
820
+ for (const page of pages) {
821
+ for (const frame of page.screencastFrames) {
822
+ allFrames.push({
823
+ timestamp: frame.timestamp,
824
+ sha1: frame.sha1,
825
+ pageId: page.pageId
826
+ });
827
+ }
828
+ }
829
+ if (allFrames.length === 0)
830
+ return `# Filmstrip
831
+
832
+ No screenshots recorded.
833
+ `;
834
+ allFrames.sort((a, b) => a.timestamp - b.timestamp);
835
+ let md = `# Filmstrip
836
+
837
+ `;
838
+ md += `Total screenshots: ${allFrames.length}
839
+
840
+ `;
841
+ md += `| # | Time | Screenshot |
842
+ `;
843
+ md += `|---|------|------------|
844
+ `;
845
+ for (let i = 0; i < allFrames.length; i++) {
846
+ const frame = allFrames[i];
847
+ const relativeTime = Math.round(frame.timestamp - startTime);
848
+ const resourcePath = assetMap.get(frame.sha1) || `./assets/resources/${frame.sha1}`;
849
+ md += `| ${i + 1} | ${relativeTime}ms | [view](${resourcePath}) |
850
+ `;
851
+ }
852
+ return md;
853
+ }
854
+ function generateAttachmentsMarkdown(actions, assetMap) {
855
+ const allAttachments = [];
856
+ for (const action of actions) {
857
+ if (!action.attachments?.length)
858
+ continue;
859
+ const actionTitle = action.title || `${action.class}.${action.method}`;
860
+ for (const attachment of action.attachments) {
861
+ allAttachments.push({
862
+ actionTitle,
863
+ attachment
864
+ });
865
+ }
866
+ }
867
+ if (allAttachments.length === 0)
868
+ return `# Attachments
869
+
870
+ No attachments recorded.
871
+ `;
872
+ let md = `# Attachments
873
+
874
+ `;
875
+ md += `Total attachments: ${allAttachments.length}
876
+
877
+ `;
878
+ md += `| # | Name | Type | Action | Link |
879
+ `;
880
+ md += `|---|------|------|--------|------|
881
+ `;
882
+ for (let i = 0; i < allAttachments.length; i++) {
883
+ const { actionTitle, attachment } = allAttachments[i];
884
+ const name = attachment.name.replace(/\|/g, "\\|");
885
+ const contentType = attachment.contentType.replace(/\|/g, "\\|");
886
+ const action = truncateString(actionTitle, 30).replace(/\|/g, "\\|");
887
+ let link = "";
888
+ if (attachment.sha1) {
889
+ const resourcePath = assetMap.get(attachment.sha1) || `./assets/resources/${attachment.sha1}`;
890
+ link = `[view](${resourcePath})`;
891
+ }
892
+ md += `| ${i + 1} | ${name} | ${contentType} | ${action} | ${link} |
893
+ `;
894
+ }
895
+ return md;
896
+ }
897
+ const autoClosing = /* @__PURE__ */ new Set(["AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "MENUITEM", "META", "PARAM", "SOURCE", "TRACK", "WBR"]);
898
+ function isNodeNameAttributesChildNodesSnapshot(n) {
899
+ return Array.isArray(n) && typeof n[0] === "string";
900
+ }
901
+ function isSubtreeReferenceSnapshot(n) {
902
+ return Array.isArray(n) && Array.isArray(n[0]);
903
+ }
904
+ function buildNodeIndex(snapshot) {
905
+ const nodes = [];
906
+ const visit = (n) => {
907
+ if (typeof n === "string") {
908
+ nodes.push(n);
909
+ } else if (isNodeNameAttributesChildNodesSnapshot(n)) {
910
+ const [, , ...children] = n;
911
+ for (const child of children)
912
+ visit(child);
913
+ nodes.push(n);
914
+ }
915
+ };
916
+ visit(snapshot.html);
917
+ return nodes;
918
+ }
919
+ class ExportSnapshotRenderer {
920
+ constructor(snapshots, index, networkResourceMap) {
921
+ this._nodeIndexCache = /* @__PURE__ */ new Map();
922
+ // URL -> SHA1 from network log
923
+ this._usedSha1s = /* @__PURE__ */ new Set();
924
+ this._snapshots = snapshots;
925
+ this._index = index;
926
+ this._snapshot = snapshots[index];
927
+ this._baseUrl = snapshots[index].frameUrl;
928
+ this._networkResourceMap = networkResourceMap;
929
+ this._overrideMap = this._buildOverrideMap();
930
+ }
931
+ // Build a map of URL -> SHA1 from all resourceOverrides, resolving refs
932
+ _buildOverrideMap() {
933
+ const map = /* @__PURE__ */ new Map();
934
+ for (const override of this._snapshot.resourceOverrides) {
935
+ if (override.sha1) {
936
+ map.set(override.url, override.sha1);
937
+ } else if (override.ref !== void 0) {
938
+ const refIndex = this._index - override.ref;
939
+ if (refIndex >= 0 && refIndex < this._snapshots.length) {
940
+ const refSnapshot = this._snapshots[refIndex];
941
+ const refOverride = refSnapshot.resourceOverrides.find((o) => o.url === override.url);
942
+ if (refOverride?.sha1)
943
+ map.set(override.url, refOverride.sha1);
944
+ }
945
+ }
946
+ }
947
+ return map;
948
+ }
949
+ _getNodeIndex(snapshotIndex) {
950
+ let nodes = this._nodeIndexCache.get(snapshotIndex);
951
+ if (!nodes) {
952
+ nodes = buildNodeIndex(this._snapshots[snapshotIndex]);
953
+ this._nodeIndexCache.set(snapshotIndex, nodes);
954
+ }
955
+ return nodes;
956
+ }
957
+ // Resolve a potentially relative URL to absolute using base URL
958
+ _resolveUrl(url) {
959
+ if (!url || url.startsWith("data:") || url.startsWith("blob:") || url.startsWith("javascript:"))
960
+ return url;
961
+ try {
962
+ return new URL(url, this._baseUrl).href;
963
+ } catch {
964
+ return url;
965
+ }
966
+ }
967
+ // Rewrite URL to relative path for export
968
+ _rewriteUrl(url) {
969
+ let sha1 = this._overrideMap.get(url);
970
+ if (!sha1) {
971
+ const resolvedUrl = this._resolveUrl(url);
972
+ sha1 = this._overrideMap.get(resolvedUrl);
973
+ if (!sha1) {
974
+ sha1 = this._networkResourceMap.get(url) || this._networkResourceMap.get(resolvedUrl);
975
+ }
976
+ }
977
+ if (sha1) {
978
+ this._usedSha1s.add(sha1);
979
+ return `../resources/${sha1}`;
980
+ }
981
+ return url;
982
+ }
983
+ // Rewrite URLs in CSS text (url(...) references)
984
+ _rewriteCssUrls(cssText) {
985
+ return cssText.replace(/url\(\s*(['"]?)([^'")]+)\1\s*\)/gi, (match, quote, url) => {
986
+ const rewritten = this._rewriteUrl(url.trim());
987
+ return `url('${rewritten}')`;
988
+ });
989
+ }
990
+ // Get all SHA1s that were actually used during rendering
991
+ getUsedSha1s() {
992
+ return this._usedSha1s;
993
+ }
994
+ render() {
995
+ const result = [];
996
+ const visit = (n, snapshotIndex, parentTag) => {
997
+ if (typeof n === "string") {
998
+ if (parentTag === "STYLE" || parentTag === "style")
999
+ result.push(this._rewriteCssUrls((0, import_stringUtils.escapeHTML)(n)));
1000
+ else
1001
+ result.push((0, import_stringUtils.escapeHTML)(n));
1002
+ return;
1003
+ }
1004
+ if (isSubtreeReferenceSnapshot(n)) {
1005
+ const [snapshotsAgo, nodeIndex] = n[0];
1006
+ const referenceIndex = snapshotIndex - snapshotsAgo;
1007
+ if (referenceIndex >= 0 && referenceIndex <= snapshotIndex) {
1008
+ const nodes = this._getNodeIndex(referenceIndex);
1009
+ if (nodeIndex >= 0 && nodeIndex < nodes.length)
1010
+ return visit(nodes[nodeIndex], referenceIndex, parentTag);
1011
+ }
1012
+ return;
1013
+ }
1014
+ if (isNodeNameAttributesChildNodesSnapshot(n)) {
1015
+ const [name, nodeAttrs, ...children] = n;
1016
+ const nodeName = name === "NOSCRIPT" ? "X-NOSCRIPT" : name;
1017
+ const attrs = Object.entries(nodeAttrs || {});
1018
+ if (nodeName === "BASE")
1019
+ return;
1020
+ result.push("<", nodeName.toLowerCase());
1021
+ const isFrame = nodeName === "IFRAME" || nodeName === "FRAME";
1022
+ const isAnchor = nodeName === "A";
1023
+ const isLink = nodeName === "LINK";
1024
+ const isScript = nodeName === "SCRIPT";
1025
+ const isImg = nodeName === "IMG";
1026
+ for (const [attr, value] of attrs) {
1027
+ if (attr.startsWith("__playwright") && attr !== "__playwright_src__")
1028
+ continue;
1029
+ let attrName = attr;
1030
+ let attrValue = value;
1031
+ const attrLower = attr.toLowerCase();
1032
+ if (isFrame && attr === "__playwright_src__") {
1033
+ attrName = "src";
1034
+ attrValue = this._rewriteUrl(value);
1035
+ } else if (isLink && attrLower === "href") {
1036
+ attrValue = this._rewriteUrl(value);
1037
+ } else if ((isScript || isImg) && attrLower === "src") {
1038
+ attrValue = this._rewriteUrl(value);
1039
+ } else if (!isAnchor && !isLink && attrLower === "src") {
1040
+ attrValue = this._rewriteUrl(value);
1041
+ } else if (attrLower === "srcset") {
1042
+ attrValue = this._rewriteSrcset(value);
1043
+ } else if (attrLower === "style") {
1044
+ attrValue = this._rewriteCssUrls(value);
1045
+ }
1046
+ result.push(" ", attrName, '="', (0, import_stringUtils.escapeHTMLAttribute)(attrValue), '"');
1047
+ }
1048
+ result.push(">");
1049
+ for (const child of children)
1050
+ visit(child, snapshotIndex, nodeName);
1051
+ if (!autoClosing.has(nodeName))
1052
+ result.push("</", nodeName.toLowerCase(), ">");
1053
+ }
1054
+ };
1055
+ const snapshot = this._snapshot;
1056
+ visit(snapshot.html, this._index, void 0);
1057
+ const doctype = snapshot.doctype ? `<!DOCTYPE ${snapshot.doctype}>` : "<!DOCTYPE html>";
1058
+ const comment = `<!-- Playwright Snapshot: ${snapshot.snapshotName} | URL: ${snapshot.frameUrl} | Timestamp: ${snapshot.timestamp} -->`;
1059
+ return doctype + "\n" + comment + "\n" + result.join("");
1060
+ }
1061
+ // Rewrite srcset attribute (format: "url1 1x, url2 2x, ...")
1062
+ _rewriteSrcset(srcset) {
1063
+ return srcset.split(",").map((entry) => {
1064
+ const parts = entry.trim().split(/\s+/);
1065
+ if (parts.length >= 1) {
1066
+ parts[0] = this._rewriteUrl(parts[0]);
1067
+ }
1068
+ return parts.join(" ");
1069
+ }).join(", ");
1070
+ }
1071
+ }
1072
+ function truncateString(str, maxLength) {
1073
+ if (str.length <= maxLength)
1074
+ return str;
1075
+ return str.substring(0, maxLength - 3) + "...";
1076
+ }
1077
+ function formatParams(params) {
1078
+ const str = JSON.stringify(params);
1079
+ return truncateString(str, 200);
1080
+ }
1081
+ function formatResult(result) {
1082
+ if (result === null || result === void 0)
1083
+ return "null";
1084
+ if (typeof result === "string")
1085
+ return truncateString(result, 100);
1086
+ const str = JSON.stringify(result);
1087
+ return truncateString(str, 100);
1088
+ }
1089
+ function formatSize(bytes) {
1090
+ if (bytes < 1024)
1091
+ return `${bytes}B`;
1092
+ if (bytes < 1024 * 1024)
1093
+ return `${(bytes / 1024).toFixed(1)}KB`;
1094
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1095
+ }
1096
+ function stripAnsi(str) {
1097
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
1098
+ }
1099
+ // Annotate the CommonJS export names for ESM import in node:
1100
+ 0 && (module.exports = {
1101
+ exportTraceToMarkdown
1102
+ });