patchright-bun-core 1.58.2 → 1.59.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 (272) hide show
  1. package/ThirdPartyNotices.txt +126 -650
  2. package/browsers.json +16 -14
  3. package/lib/bootstrap.js +77 -0
  4. package/lib/cli/browserActions.js +308 -0
  5. package/lib/cli/driver.js +3 -2
  6. package/lib/cli/installActions.js +171 -0
  7. package/lib/cli/program.js +47 -411
  8. package/lib/client/android.js +4 -4
  9. package/lib/client/api.js +3 -3
  10. package/lib/client/browser.js +8 -0
  11. package/lib/client/browserContext.js +18 -37
  12. package/lib/client/browserType.js +19 -51
  13. package/lib/client/cdpSession.js +6 -2
  14. package/lib/client/channelOwner.js +1 -1
  15. package/lib/client/{webSocket.js → connect.js} +57 -7
  16. package/lib/client/connection.js +8 -4
  17. package/lib/client/consoleMessage.js +3 -0
  18. package/lib/client/debugger.js +57 -0
  19. package/lib/client/dialog.js +8 -1
  20. package/lib/client/disposable.js +76 -0
  21. package/lib/client/electron.js +1 -0
  22. package/lib/client/elementHandle.js +1 -4
  23. package/lib/client/events.js +3 -3
  24. package/lib/client/fetch.js +0 -1
  25. package/lib/client/frame.js +0 -5
  26. package/lib/client/harRouter.js +13 -1
  27. package/lib/client/jsHandle.js +0 -4
  28. package/lib/client/locator.js +5 -7
  29. package/lib/client/network.js +14 -11
  30. package/lib/client/page.js +34 -48
  31. package/lib/client/platform.js +0 -3
  32. package/lib/client/screencast.js +88 -0
  33. package/lib/client/selectors.js +3 -1
  34. package/lib/client/tracing.js +11 -4
  35. package/lib/client/video.js +13 -20
  36. package/lib/generated/bindingsControllerSource.js +1 -1
  37. package/lib/generated/clockSource.js +1 -1
  38. package/lib/generated/injectedScriptSource.js +1 -1
  39. package/lib/generated/pollingRecorderSource.js +1 -1
  40. package/lib/generated/storageScriptSource.js +1 -1
  41. package/lib/generated/utilityScriptSource.js +1 -1
  42. package/lib/mcpBundle.js +0 -6
  43. package/lib/mcpBundleImpl.js +91 -0
  44. package/lib/protocol/validator.js +216 -118
  45. package/lib/protocol/validatorPrimitives.js +1 -1
  46. package/lib/remote/playwrightConnection.js +10 -8
  47. package/lib/remote/playwrightPipeServer.js +100 -0
  48. package/lib/remote/playwrightServer.js +13 -8
  49. package/lib/remote/playwrightWebSocketServer.js +73 -0
  50. package/lib/remote/serverTransport.js +96 -0
  51. package/lib/server/android/android.js +2 -2
  52. package/lib/server/bidi/bidiBrowser.js +30 -8
  53. package/lib/server/bidi/bidiChromium.js +18 -5
  54. package/lib/server/bidi/bidiNetworkManager.js +39 -11
  55. package/lib/server/bidi/bidiPage.js +31 -15
  56. package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
  57. package/lib/server/browser.js +84 -21
  58. package/lib/server/browserContext.js +97 -58
  59. package/lib/server/browserType.js +14 -12
  60. package/lib/server/chromium/chromium.js +15 -13
  61. package/lib/server/chromium/crBrowser.js +18 -10
  62. package/lib/server/chromium/crNetworkManager.js +4 -4
  63. package/lib/server/chromium/crPage.js +26 -64
  64. package/lib/server/chromium/crServiceWorker.js +5 -4
  65. package/lib/server/clock.js +33 -33
  66. package/lib/server/console.js +5 -1
  67. package/lib/server/debugController.js +12 -6
  68. package/lib/server/debugger.js +40 -47
  69. package/lib/server/deviceDescriptorsSource.json +137 -137
  70. package/lib/server/dispatchers/browserContextDispatcher.js +27 -30
  71. package/lib/server/dispatchers/browserDispatcher.js +11 -5
  72. package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
  73. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
  74. package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
  75. package/lib/server/dispatchers/dispatcher.js +1 -1
  76. package/lib/server/dispatchers/disposableDispatcher.js +39 -0
  77. package/lib/server/dispatchers/electronDispatcher.js +2 -1
  78. package/lib/server/dispatchers/frameDispatcher.js +3 -3
  79. package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
  80. package/lib/server/dispatchers/networkDispatchers.js +6 -5
  81. package/lib/server/dispatchers/pageDispatcher.js +101 -38
  82. package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
  83. package/lib/server/disposable.js +41 -0
  84. package/lib/server/dom.js +44 -26
  85. package/lib/server/download.js +3 -2
  86. package/lib/server/electron/electron.js +12 -7
  87. package/lib/server/firefox/ffBrowser.js +9 -19
  88. package/lib/server/firefox/ffInput.js +21 -5
  89. package/lib/server/firefox/ffNetworkManager.js +2 -2
  90. package/lib/server/firefox/ffPage.js +24 -27
  91. package/lib/server/frames.js +40 -11
  92. package/lib/server/har/harRecorder.js +2 -2
  93. package/lib/server/har/harTracer.js +5 -4
  94. package/lib/server/input.js +49 -4
  95. package/lib/server/instrumentation.js +5 -0
  96. package/lib/server/launchApp.js +0 -1
  97. package/lib/server/localUtils.js +6 -6
  98. package/lib/server/network.js +9 -8
  99. package/lib/server/overlay.js +138 -0
  100. package/lib/server/page.js +111 -51
  101. package/lib/server/progress.js +6 -0
  102. package/lib/server/recorder/recorderApp.js +9 -8
  103. package/lib/server/recorder.js +76 -40
  104. package/lib/server/registry/index.js +54 -81
  105. package/lib/server/registry/nativeDeps.js +1 -0
  106. package/lib/server/screencast.js +90 -143
  107. package/lib/server/trace/recorder/snapshotter.js +2 -2
  108. package/lib/server/trace/recorder/tracing.js +87 -36
  109. package/lib/server/trace/viewer/traceViewer.js +3 -4
  110. package/lib/server/usKeyboardLayout.js +7 -0
  111. package/lib/server/utils/comparators.js +1 -1
  112. package/lib/server/utils/disposable.js +32 -0
  113. package/lib/server/utils/eventsHelper.js +3 -1
  114. package/lib/server/utils/fileUtils.js +16 -2
  115. package/lib/server/utils/happyEyeballs.js +15 -12
  116. package/lib/server/utils/hostPlatform.js +0 -15
  117. package/lib/server/utils/httpServer.js +5 -3
  118. package/lib/server/utils/network.js +2 -1
  119. package/lib/server/utils/nodePlatform.js +0 -6
  120. package/lib/server/utils/processLauncher.js +8 -6
  121. package/lib/server/utils/zipFile.js +2 -2
  122. package/lib/server/videoRecorder.js +82 -12
  123. package/lib/server/webkit/wkBrowser.js +1 -6
  124. package/lib/server/webkit/wkPage.js +27 -25
  125. package/lib/server/webkit/wkWorkers.js +2 -1
  126. package/lib/serverRegistry.js +156 -0
  127. package/lib/tools/backend/browserBackend.js +79 -0
  128. package/lib/tools/backend/common.js +63 -0
  129. package/lib/tools/backend/config.js +41 -0
  130. package/lib/tools/backend/console.js +66 -0
  131. package/lib/tools/backend/context.js +296 -0
  132. package/lib/tools/backend/cookies.js +152 -0
  133. package/lib/tools/backend/devtools.js +69 -0
  134. package/lib/tools/backend/dialogs.js +59 -0
  135. package/lib/tools/backend/evaluate.js +64 -0
  136. package/lib/tools/backend/files.js +60 -0
  137. package/lib/tools/backend/form.js +64 -0
  138. package/lib/tools/backend/keyboard.js +155 -0
  139. package/lib/tools/backend/logFile.js +95 -0
  140. package/lib/tools/backend/mouse.js +168 -0
  141. package/lib/tools/backend/navigate.js +106 -0
  142. package/lib/tools/backend/network.js +135 -0
  143. package/lib/tools/backend/pdf.js +48 -0
  144. package/lib/tools/backend/response.js +305 -0
  145. package/lib/tools/backend/route.js +140 -0
  146. package/lib/tools/backend/runCode.js +77 -0
  147. package/lib/tools/backend/screenshot.js +88 -0
  148. package/lib/tools/backend/sessionLog.js +74 -0
  149. package/lib/tools/backend/snapshot.js +208 -0
  150. package/lib/tools/backend/storage.js +68 -0
  151. package/lib/tools/backend/tab.js +445 -0
  152. package/lib/tools/backend/tabs.js +67 -0
  153. package/lib/tools/backend/tool.js +47 -0
  154. package/lib/tools/backend/tools.js +102 -0
  155. package/lib/tools/backend/tracing.js +78 -0
  156. package/lib/tools/backend/utils.js +83 -0
  157. package/lib/tools/backend/verify.js +151 -0
  158. package/lib/tools/backend/video.js +98 -0
  159. package/lib/tools/backend/wait.js +63 -0
  160. package/lib/tools/backend/webstorage.js +223 -0
  161. package/lib/tools/cli-client/cli.js +6 -0
  162. package/lib/tools/cli-client/help.json +399 -0
  163. package/lib/tools/cli-client/minimist.js +128 -0
  164. package/lib/tools/cli-client/program.js +350 -0
  165. package/lib/tools/cli-client/registry.js +176 -0
  166. package/lib/tools/cli-client/session.js +289 -0
  167. package/lib/tools/cli-client/skill/SKILL.md +328 -0
  168. package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
  169. package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
  170. package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
  171. package/lib/tools/cli-client/skill/references/running-code.md +231 -0
  172. package/lib/tools/cli-client/skill/references/session-management.md +169 -0
  173. package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
  174. package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
  175. package/lib/tools/cli-client/skill/references/tracing.md +139 -0
  176. package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
  177. package/lib/tools/cli-daemon/command.js +73 -0
  178. package/lib/tools/cli-daemon/commands.js +956 -0
  179. package/lib/tools/cli-daemon/daemon.js +157 -0
  180. package/lib/tools/cli-daemon/helpGenerator.js +177 -0
  181. package/lib/tools/cli-daemon/program.js +129 -0
  182. package/lib/tools/dashboard/appIcon.png +0 -0
  183. package/lib/tools/dashboard/dashboardApp.js +284 -0
  184. package/lib/tools/dashboard/dashboardController.js +296 -0
  185. package/lib/tools/exports.js +60 -0
  186. package/lib/tools/mcp/browserFactory.js +233 -0
  187. package/lib/tools/mcp/cdpRelay.js +352 -0
  188. package/lib/tools/mcp/cli-stub.js +7 -0
  189. package/lib/tools/mcp/config.d.js +16 -0
  190. package/lib/tools/mcp/config.js +446 -0
  191. package/lib/tools/mcp/configIni.js +189 -0
  192. package/lib/tools/mcp/extensionContextFactory.js +55 -0
  193. package/lib/tools/mcp/index.js +62 -0
  194. package/lib/tools/mcp/log.js +35 -0
  195. package/lib/tools/mcp/program.js +107 -0
  196. package/lib/tools/mcp/protocol.js +28 -0
  197. package/lib/tools/mcp/watchdog.js +44 -0
  198. package/lib/tools/trace/SKILL.md +171 -0
  199. package/lib/{server/trace/viewer/traceParser.js → tools/trace/installSkill.js} +15 -39
  200. package/lib/tools/trace/traceActions.js +142 -0
  201. package/lib/tools/trace/traceAttachments.js +69 -0
  202. package/lib/tools/trace/traceCli.js +87 -0
  203. package/lib/tools/trace/traceConsole.js +97 -0
  204. package/lib/tools/trace/traceErrors.js +55 -0
  205. package/lib/tools/trace/traceOpen.js +69 -0
  206. package/lib/tools/trace/traceParser.js +96 -0
  207. package/lib/tools/trace/traceRequests.js +182 -0
  208. package/lib/tools/trace/traceScreenshot.js +68 -0
  209. package/lib/tools/trace/traceSnapshot.js +149 -0
  210. package/lib/tools/trace/traceUtils.js +153 -0
  211. package/lib/tools/utils/connect.js +32 -0
  212. package/lib/tools/utils/mcp/http.js +152 -0
  213. package/lib/tools/utils/mcp/server.js +230 -0
  214. package/lib/tools/utils/mcp/tool.js +47 -0
  215. package/lib/tools/utils/socketConnection.js +108 -0
  216. package/lib/utils/isomorphic/formatUtils.js +64 -0
  217. package/lib/utils/isomorphic/jsonSchema.js +89 -0
  218. package/lib/utils/isomorphic/mimeType.js +7 -2
  219. package/lib/utils/isomorphic/protocolFormatter.js +2 -2
  220. package/lib/utils/isomorphic/protocolMetainfo.js +127 -106
  221. package/lib/utils/isomorphic/stringUtils.js +3 -3
  222. package/lib/utils/isomorphic/timeoutRunner.js +3 -3
  223. package/lib/utils/isomorphic/trace/snapshotRenderer.js +35 -42
  224. package/lib/utils/isomorphic/trace/traceLoader.js +15 -14
  225. package/lib/utils/isomorphic/trace/traceModel.js +3 -2
  226. package/lib/utils/isomorphic/trace/traceModernizer.js +1 -0
  227. package/lib/utils/isomorphic/urlMatch.js +54 -1
  228. package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
  229. package/lib/utils.js +6 -2
  230. package/lib/utilsBundle.js +3 -21
  231. package/lib/utilsBundleImpl/index.js +132 -133
  232. package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
  233. package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
  234. package/lib/vite/dashboard/index.html +28 -0
  235. package/lib/vite/htmlReport/index.html +2 -70
  236. package/lib/vite/htmlReport/report.css +1 -0
  237. package/lib/vite/htmlReport/report.js +72 -0
  238. package/lib/vite/recorder/assets/{codeMirrorModule-DadYNm1I.js → codeMirrorModule-C8KMvO9L.js} +20 -20
  239. package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
  240. package/lib/vite/recorder/index.html +1 -1
  241. package/lib/vite/traceViewer/assets/{codeMirrorModule-a5XoALAZ.js → codeMirrorModule-DS0FLvoc.js} +20 -20
  242. package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
  243. package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
  244. package/lib/vite/traceViewer/{index.BVu7tZDe.css → index.CzXZzn5A.css} +1 -1
  245. package/lib/vite/traceViewer/{index.BDwrLSGN.js → index.Dtstcb7U.js} +1 -1
  246. package/lib/vite/traceViewer/index.html +4 -4
  247. package/lib/vite/traceViewer/sw.bundle.js +4 -4
  248. package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
  249. package/lib/vite/traceViewer/uiMode.html +3 -3
  250. package/lib/zipBundleImpl.js +2 -2
  251. package/lib/zodBundle.js +39 -0
  252. package/lib/zodBundleImpl.js +40 -0
  253. package/package.json +6 -1
  254. package/types/protocol.d.ts +947 -51
  255. package/types/types.d.ts +854 -74
  256. package/lib/client/pageAgent.js +0 -64
  257. package/lib/mcpBundleImpl/index.js +0 -147
  258. package/lib/server/agent/actionRunner.js +0 -335
  259. package/lib/server/agent/actions.js +0 -128
  260. package/lib/server/agent/codegen.js +0 -111
  261. package/lib/server/agent/context.js +0 -150
  262. package/lib/server/agent/expectTools.js +0 -156
  263. package/lib/server/agent/pageAgent.js +0 -204
  264. package/lib/server/agent/performTools.js +0 -262
  265. package/lib/server/agent/tool.js +0 -109
  266. package/lib/server/dispatchers/pageAgentDispatcher.js +0 -96
  267. package/lib/vite/recorder/assets/index-BhTWtUlo.js +0 -193
  268. package/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js +0 -266
  269. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +0 -1
  270. package/lib/vite/traceViewer/uiMode.CQJ9SCIQ.js +0 -5
  271. /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
  272. /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,171 +15,120 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var screencast_exports = {};
30
20
  __export(screencast_exports, {
31
21
  Screencast: () => Screencast
32
22
  });
33
23
  module.exports = __toCommonJS(screencast_exports);
34
- var import_path = __toESM(require("path"));
35
24
  var import_utils = require("../utils");
36
25
  var import_utils2 = require("../utils");
37
- var import_videoRecorder = require("./videoRecorder");
38
- var import_page = require("./page");
39
- var import_registry = require("./registry");
40
26
  class Screencast {
41
27
  constructor(page) {
42
- this._videoRecorder = null;
43
- this._videoId = null;
44
- this._screencastClients = /* @__PURE__ */ new Set();
45
- // Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
46
- // When throttling for tracing, 200ms between frames, except for 10 frames around the action.
47
- this._frameThrottler = new FrameThrottler(10, 35, 200);
48
- this._frameListener = null;
49
- this._page = page;
50
- }
51
- stopFrameThrottler() {
52
- this._frameThrottler.dispose();
53
- }
54
- setOptions(options) {
55
- this._setOptions(options).catch((e) => import_utils2.debugLogger.log("error", e));
56
- this._frameThrottler.setThrottlingEnabled(!!options);
28
+ this._clients = /* @__PURE__ */ new Set();
29
+ this.page = page;
30
+ this.page.instrumentation.addListener(this, page.browserContext);
31
+ }
32
+ async handlePageOrContextClose() {
33
+ const clients = [...this._clients];
34
+ this._clients.clear();
35
+ for (const client of clients) {
36
+ if (client.gracefulClose)
37
+ await client.gracefulClose();
38
+ }
57
39
  }
58
- throttleFrameAck(ack) {
59
- this._frameThrottler.ack(ack);
40
+ dispose() {
41
+ for (const client of this._clients)
42
+ client.dispose();
43
+ this._clients.clear();
44
+ this.page.instrumentation.removeListener(this);
60
45
  }
61
- temporarilyDisableThrottling() {
62
- this._frameThrottler.recharge();
46
+ showActions(options) {
47
+ this._actions = options;
63
48
  }
64
- launchVideoRecorder() {
65
- const recordVideo = this._page.browserContext._options.recordVideo;
66
- if (!recordVideo)
67
- return void 0;
68
- (0, import_utils.assert)(!this._videoId);
69
- this._videoId = (0, import_utils.createGuid)();
70
- const outputFile = import_path.default.join(recordVideo.dir, this._videoId + ".webm");
71
- const videoOptions = {
72
- // validateBrowserContextOptions ensures correct video size.
73
- ...recordVideo.size,
74
- outputFile
75
- };
76
- const ffmpegPath = import_registry.registry.findExecutable("ffmpeg").executablePathOrDie(this._page.browserContext._browser.sdkLanguage());
77
- this._videoRecorder = new import_videoRecorder.VideoRecorder(ffmpegPath, videoOptions);
78
- this._frameListener = import_utils.eventsHelper.addEventListener(this._page, import_page.Page.Events.ScreencastFrame, (frame) => this._videoRecorder.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3));
79
- this._page.waitForInitializedOrError().then((p) => {
80
- if (p instanceof Error)
81
- this.stopVideoRecording().catch(() => {
82
- });
83
- });
84
- return videoOptions;
49
+ hideActions() {
50
+ this._actions = void 0;
85
51
  }
86
- async startVideoRecording(options) {
87
- const videoId = this._videoId;
88
- (0, import_utils.assert)(videoId);
89
- this._page.once(import_page.Page.Events.Close, () => this.stopVideoRecording().catch(() => {
90
- }));
91
- const gotFirstFrame = new Promise((f) => this._page.once(import_page.Page.Events.ScreencastFrame, f));
92
- await this._startScreencast(this._videoRecorder, {
93
- quality: 90,
94
- width: options.width,
95
- height: options.height
96
- });
97
- gotFirstFrame.then(() => {
98
- this._page.browserContext._browser._videoStarted(this._page.browserContext, videoId, options.outputFile, this._page.waitForInitializedOrError());
99
- });
52
+ addClient(client) {
53
+ this._clients.add(client);
54
+ if (this._clients.size === 1)
55
+ this._startScreencast(client.size, client.quality);
56
+ return { size: this._size };
100
57
  }
101
- async stopVideoRecording() {
102
- if (!this._videoId)
58
+ removeClient(client) {
59
+ if (!this._clients.has(client))
103
60
  return;
104
- if (this._frameListener)
105
- import_utils.eventsHelper.removeEventListeners([this._frameListener]);
106
- this._frameListener = null;
107
- const videoId = this._videoId;
108
- this._videoId = null;
109
- const videoRecorder = this._videoRecorder;
110
- this._videoRecorder = null;
111
- await this._stopScreencast(videoRecorder);
112
- await videoRecorder.stop();
113
- const video = this._page.browserContext._browser._takeVideo(videoId);
114
- video?.reportFinished();
115
- }
116
- async _setOptions(options) {
117
- if (options)
118
- await this._startScreencast(this, options);
119
- else
120
- await this._stopScreencast(this);
121
- }
122
- async _startScreencast(client, options) {
123
- this._screencastClients.add(client);
124
- if (this._screencastClients.size === 1) {
125
- await this._page.delegate.startScreencast({
126
- width: options.width,
127
- height: options.height,
128
- quality: options.quality
129
- });
61
+ this._clients.delete(client);
62
+ if (!this._clients.size)
63
+ this._stopScreencast();
64
+ }
65
+ size() {
66
+ return this._size;
67
+ }
68
+ _startScreencast(size, quality) {
69
+ this._size = size;
70
+ if (!this._size) {
71
+ const viewport = this.page.browserContext._options.viewport || { width: 800, height: 600 };
72
+ const scale = Math.min(1, 800 / Math.max(viewport.width, viewport.height));
73
+ this._size = {
74
+ width: Math.floor(viewport.width * scale),
75
+ height: Math.floor(viewport.height * scale)
76
+ };
130
77
  }
78
+ this._size = {
79
+ width: this._size.width & ~1,
80
+ height: this._size.height & ~1
81
+ };
82
+ this.page.delegate.startScreencast({
83
+ width: this._size.width,
84
+ height: this._size.height,
85
+ quality: quality ?? 90
86
+ });
131
87
  }
132
- async _stopScreencast(client) {
133
- this._screencastClients.delete(client);
134
- if (!this._screencastClients.size)
135
- await this._page.delegate.stopScreencast();
136
- }
137
- }
138
- class FrameThrottler {
139
- constructor(nonThrottledFrames, defaultInterval, throttlingInterval) {
140
- this._acks = [];
141
- this._throttlingEnabled = false;
142
- this._nonThrottledFrames = nonThrottledFrames;
143
- this._budget = nonThrottledFrames;
144
- this._defaultInterval = defaultInterval;
145
- this._throttlingInterval = throttlingInterval;
146
- this._tick();
88
+ _stopScreencast() {
89
+ this.page.delegate.stopScreencast();
147
90
  }
148
- dispose() {
149
- if (this._timeoutId) {
150
- clearTimeout(this._timeoutId);
151
- this._timeoutId = void 0;
91
+ onScreencastFrame(frame, ack) {
92
+ const asyncResults = [];
93
+ for (const client of this._clients) {
94
+ const result = client.onFrame(frame);
95
+ if (result)
96
+ asyncResults.push(result);
152
97
  }
153
- }
154
- setThrottlingEnabled(enabled) {
155
- this._throttlingEnabled = enabled;
156
- }
157
- recharge() {
158
- for (const ack of this._acks)
159
- ack();
160
- this._acks = [];
161
- this._budget = this._nonThrottledFrames;
162
- if (this._timeoutId) {
163
- clearTimeout(this._timeoutId);
164
- this._tick();
98
+ if (ack) {
99
+ if (!asyncResults.length)
100
+ ack();
101
+ else
102
+ Promise.race(asyncResults).then(ack);
165
103
  }
166
104
  }
167
- ack(ack) {
168
- if (!this._timeoutId) {
169
- ack();
105
+ async onBeforeCall(sdkObject, metadata, parentId) {
106
+ if (!this._actions)
170
107
  return;
171
- }
172
- this._acks.push(ack);
108
+ metadata.annotate = true;
173
109
  }
174
- _tick() {
175
- const ack = this._acks.shift();
176
- if (ack) {
177
- --this._budget;
178
- ack();
179
- }
180
- if (this._throttlingEnabled && this._budget <= 0) {
181
- this._timeoutId = setTimeout(() => this._tick(), this._throttlingInterval);
182
- } else {
183
- this._timeoutId = setTimeout(() => this._tick(), this._defaultInterval);
184
- }
110
+ async onBeforeInputAction(sdkObject, metadata) {
111
+ if (!this._actions)
112
+ return;
113
+ const page = sdkObject.attribution.page;
114
+ if (!page)
115
+ return;
116
+ const actionTitle = (0, import_utils.renderTitleForCall)(metadata);
117
+ const utility = await page.mainFrame()._utilityContext();
118
+ await utility.evaluate(async (options) => {
119
+ const { injected, duration } = options;
120
+ injected.setScreencastAnnotation(options);
121
+ await new Promise((f) => injected.utils.builtins.setTimeout(f, duration));
122
+ injected.setScreencastAnnotation(null);
123
+ }, {
124
+ injected: await utility.injectedScript(),
125
+ duration: this._actions?.duration ?? 500,
126
+ point: metadata.point,
127
+ box: metadata.box,
128
+ actionTitle,
129
+ position: this._actions?.position,
130
+ fontSize: this._actions?.fontSize
131
+ }).catch((e) => import_utils2.debugLogger.log("error", e));
185
132
  }
186
133
  }
187
134
  // Annotate the CommonJS export names for ESM import in node:
@@ -57,7 +57,7 @@ class Snapshotter {
57
57
  async resetForReuse() {
58
58
  if (this._initScript) {
59
59
  import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
60
- await this._context.removeInitScripts([this._initScript]);
60
+ await this._initScript.dispose();
61
61
  this._initScript = void 0;
62
62
  }
63
63
  }
@@ -69,7 +69,7 @@ class Snapshotter {
69
69
  ];
70
70
  const { javaScriptEnabled } = this._context._options;
71
71
  const initScriptSource = `(${import_snapshotterInjected.frameSnapshotStreamer})("${this._snapshotStreamer}", ${javaScriptEnabled || javaScriptEnabled === void 0})`;
72
- this._initScript = await this._context.addInitScript(void 0, initScriptSource);
72
+ this._initScript = await this._context.addInitScript(initScriptSource);
73
73
  await this._context.safeNonStallingEvaluateInAllFrames(initScriptSource, "main");
74
74
  }
75
75
  dispose() {
@@ -38,6 +38,7 @@ var import_snapshotter = require("./snapshotter");
38
38
  var import_protocolMetainfo = require("../../../utils/isomorphic/protocolMetainfo");
39
39
  var import_assert = require("../../../utils/isomorphic/assert");
40
40
  var import_time = require("../../../utils/isomorphic/time");
41
+ var import_manualPromise = require("../../../utils/isomorphic/manualPromise");
41
42
  var import_eventsHelper = require("../../utils/eventsHelper");
42
43
  var import_crypto = require("../../utils/crypto");
43
44
  var import_userAgent = require("../../utils/userAgent");
@@ -48,15 +49,14 @@ var import_errors = require("../../errors");
48
49
  var import_fileUtils = require("../../utils/fileUtils");
49
50
  var import_harTracer = require("../../har/harTracer");
50
51
  var import_instrumentation = require("../../instrumentation");
51
- var import_page = require("../../page");
52
52
  var import_progress = require("../../progress");
53
53
  const version = 8;
54
- const kScreencastOptions = { width: 800, height: 600, quality: 90 };
55
54
  class Tracing extends import_instrumentation.SdkObject {
56
55
  constructor(context, tracesDir) {
57
56
  super(context, "tracing");
58
57
  this._fs = new import_fileUtils.SerializedFS();
59
58
  this._screencastListeners = [];
59
+ this._pageTracingRecorders = /* @__PURE__ */ new Map();
60
60
  this._eventListeners = [];
61
61
  this._isStopping = false;
62
62
  this._allResources = /* @__PURE__ */ new Set();
@@ -219,10 +219,9 @@ class Tracing extends import_instrumentation.SdkObject {
219
219
  }
220
220
  _stopScreencast() {
221
221
  import_eventsHelper.eventsHelper.removeEventListeners(this._screencastListeners);
222
- if (!(this._context instanceof import_browserContext.BrowserContext))
223
- return;
224
- for (const page of this._context.pages())
225
- page.screencast.setOptions(null);
222
+ for (const recorder of this._pageTracingRecorders.values())
223
+ recorder.dispose();
224
+ this._pageTracingRecorders.clear();
226
225
  }
227
226
  _allocateNewTraceFile(state) {
228
227
  const suffix = state.chunkOrdinal ? `-chunk${state.chunkOrdinal}` : ``;
@@ -331,15 +330,27 @@ class Tracing extends import_instrumentation.SdkObject {
331
330
  await this._snapshotter?.captureSnapshot(sdkObject.attribution.page, metadata.id, snapshotName).catch(() => {
332
331
  });
333
332
  }
334
- _shouldCaptureSnapshot(sdkObject, metadata) {
335
- return !!this._snapshotter?.started() && shouldCaptureSnapshot(metadata) && !!sdkObject.attribution.page;
333
+ _shouldCaptureSnapshot(sdkObject, metadata, phase) {
334
+ if (!sdkObject.attribution.page || !this._snapshotter?.started())
335
+ return;
336
+ const metainfo = (0, import_protocolMetainfo.getMetainfo)(metadata);
337
+ if (!metainfo?.snapshot)
338
+ return false;
339
+ switch (phase) {
340
+ case "before":
341
+ return !metainfo.input || !!metainfo.isAutoWaiting;
342
+ case "input":
343
+ return !!metainfo.input;
344
+ case "after":
345
+ return true;
346
+ }
336
347
  }
337
348
  onBeforeCall(sdkObject, metadata, parentId) {
338
349
  const event = createBeforeActionTraceEvent(metadata, parentId ?? this._currentGroupId());
339
350
  if (!event)
340
351
  return Promise.resolve();
341
- sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
342
- if (this._shouldCaptureSnapshot(sdkObject, metadata))
352
+ this._temporarilyDisableThrottling(sdkObject.attribution.page);
353
+ if (this._shouldCaptureSnapshot(sdkObject, metadata, "before"))
343
354
  event.beforeSnapshot = `before@${metadata.id}`;
344
355
  this._state?.callIds.add(metadata.id);
345
356
  this._appendTraceEvent(event);
@@ -351,8 +362,8 @@ class Tracing extends import_instrumentation.SdkObject {
351
362
  const event = createInputActionTraceEvent(metadata);
352
363
  if (!event)
353
364
  return Promise.resolve();
354
- sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
355
- if (this._shouldCaptureSnapshot(sdkObject, metadata))
365
+ this._temporarilyDisableThrottling(sdkObject.attribution.page);
366
+ if (this._shouldCaptureSnapshot(sdkObject, metadata, "input"))
356
367
  event.inputSnapshot = `input@${metadata.id}`;
357
368
  this._appendTraceEvent(event);
358
369
  return this._captureSnapshot(event.inputSnapshot, sdkObject, metadata);
@@ -375,8 +386,8 @@ class Tracing extends import_instrumentation.SdkObject {
375
386
  const event = createAfterActionTraceEvent(metadata);
376
387
  if (!event)
377
388
  return Promise.resolve();
378
- sdkObject.attribution.page?.screencast.temporarilyDisableThrottling();
379
- if (this._shouldCaptureSnapshot(sdkObject, metadata))
389
+ this._temporarilyDisableThrottling(sdkObject.attribution.page);
390
+ if (this._shouldCaptureSnapshot(sdkObject, metadata, "after"))
380
391
  event.afterSnapshot = `after@${metadata.id}`;
381
392
  this._appendTraceEvent(event);
382
393
  return this._captureSnapshot(event.afterSnapshot, sdkObject, metadata);
@@ -483,26 +494,28 @@ class Tracing extends import_instrumentation.SdkObject {
483
494
  };
484
495
  this._appendTraceEvent(event);
485
496
  }
497
+ _temporarilyDisableThrottling(page) {
498
+ if (page)
499
+ this._pageTracingRecorders.get(page)?.temporarilyDisableThrottling();
500
+ }
486
501
  _startScreencastInPage(page) {
487
- page.screencast.setOptions(kScreencastOptions);
488
502
  const prefix = page.guid;
489
- this._screencastListeners.push(
490
- import_eventsHelper.eventsHelper.addEventListener(page, import_page.Page.Events.ScreencastFrame, (params) => {
491
- const suffix = params.timestamp || Date.now();
492
- const sha1 = `${prefix}-${suffix}.jpeg`;
493
- const event = {
494
- type: "screencast-frame",
495
- pageId: page.guid,
496
- sha1,
497
- width: params.width,
498
- height: params.height,
499
- timestamp: (0, import_time.monotonicTime)(),
500
- frameSwapWallTime: params.frameSwapWallTime
501
- };
502
- this._appendResource(sha1, params.buffer);
503
- this._appendTraceEvent(event);
504
- })
505
- );
503
+ const onFrame = (params) => {
504
+ const suffix = Date.now();
505
+ const sha1 = `${prefix}-${suffix}.jpeg`;
506
+ const event = {
507
+ type: "screencast-frame",
508
+ pageId: page.guid,
509
+ sha1,
510
+ width: params.viewportWidth,
511
+ height: params.viewportHeight,
512
+ timestamp: (0, import_time.monotonicTime)(),
513
+ frameSwapWallTime: params.frameSwapWallTime
514
+ };
515
+ this._appendResource(sha1, params.buffer);
516
+ this._appendTraceEvent(event);
517
+ };
518
+ this._pageTracingRecorders.set(page, new ScreencastTracingRecorder(page.screencast, onFrame));
506
519
  }
507
520
  _appendTraceEvent(event) {
508
521
  const visited = visitTraceEvent(event, this._state.traceSha1s);
@@ -545,10 +558,6 @@ function visitTraceEvent(object, sha1s) {
545
558
  }
546
559
  return object;
547
560
  }
548
- function shouldCaptureSnapshot(metadata) {
549
- const metainfo = import_protocolMetainfo.methodMetainfo.get(metadata.type + "." + metadata.method);
550
- return !!metainfo?.snapshot;
551
- }
552
561
  function createBeforeActionTraceEvent(metadata, parentId) {
553
562
  if (metadata.internal || metadata.method.startsWith("tracing"))
554
563
  return null;
@@ -598,6 +607,48 @@ function createAfterActionTraceEvent(metadata) {
598
607
  point: metadata.point
599
608
  };
600
609
  }
610
+ const throttledRate = 200;
611
+ const unthrottleDuration = 500;
612
+ class ScreencastTracingRecorder {
613
+ constructor(screencast, onFrame) {
614
+ this._unthrottledUntil = 0;
615
+ this._screencast = screencast;
616
+ this._client = {
617
+ onFrame: (frame) => {
618
+ const time = (0, import_time.monotonicTime)();
619
+ if (time < this._unthrottledUntil) {
620
+ onFrame(frame);
621
+ return;
622
+ }
623
+ if (this._pendingAck)
624
+ return;
625
+ onFrame(frame);
626
+ this._pendingAck = new import_manualPromise.ManualPromise();
627
+ this._timer = setTimeout(() => this._clearPendingAck(), throttledRate);
628
+ return this._pendingAck;
629
+ },
630
+ gracefulClose: () => this.dispose(),
631
+ dispose: () => this.dispose()
632
+ };
633
+ this._screencast.addClient(this._client);
634
+ }
635
+ dispose() {
636
+ this._screencast.removeClient(this._client);
637
+ this._clearPendingAck();
638
+ }
639
+ temporarilyDisableThrottling() {
640
+ this._unthrottledUntil = (0, import_time.monotonicTime)() + unthrottleDuration;
641
+ this._clearPendingAck();
642
+ }
643
+ _clearPendingAck() {
644
+ this._pendingAck?.resolve();
645
+ this._pendingAck = void 0;
646
+ if (this._timer) {
647
+ clearTimeout(this._timer);
648
+ this._timer = void 0;
649
+ }
650
+ }
651
+ }
601
652
  // Annotate the CommonJS export names for ESM import in node:
602
653
  0 && (module.exports = {
603
654
  Tracing
@@ -91,7 +91,7 @@ async function startTraceViewerServer(options) {
91
91
  });
92
92
  const transport = options?.transport || (options?.isServer ? new StdinServer() : void 0);
93
93
  if (transport)
94
- server.createWebSocket(transport);
94
+ server.createWebSocket(() => transport);
95
95
  const { host, port } = options || {};
96
96
  await server.start({ preferredPort: port, host });
97
97
  return server;
@@ -126,13 +126,12 @@ async function installRootRedirect(server, traceUrl, options) {
126
126
  return true;
127
127
  });
128
128
  }
129
- async function runTraceViewerApp(traceUrl, browserName, options, exitOnClose) {
129
+ async function runTraceViewerApp(traceUrl, browserName, options) {
130
130
  traceUrl = validateTraceUrlOrPath(traceUrl);
131
131
  const server = await startTraceViewerServer(options);
132
132
  await installRootRedirect(server, traceUrl, options);
133
133
  const page = await openTraceViewerApp(server.urlPrefix("precise"), browserName, options);
134
- if (exitOnClose)
135
- page.on("close", () => (0, import_utils.gracefullyProcessExitDoNotHang)(0));
134
+ page.on("close", () => (0, import_utils.gracefullyProcessExitDoNotHang)(0));
136
135
  return page;
137
136
  }
138
137
  async function runTraceInBrowser(traceUrl, options) {
@@ -119,6 +119,13 @@ const USKeyboardLayout = {
119
119
  "ArrowUp": { "keyCode": 38, "key": "ArrowUp" },
120
120
  "ArrowRight": { "keyCode": 39, "key": "ArrowRight" },
121
121
  "ArrowDown": { "keyCode": 40, "key": "ArrowDown" },
122
+ // Media keys
123
+ "AudioVolumeMute": { "keyCode": 173, "key": "AudioVolumeMute" },
124
+ "AudioVolumeDown": { "keyCode": 174, "key": "AudioVolumeDown" },
125
+ "AudioVolumeUp": { "keyCode": 175, "key": "AudioVolumeUp" },
126
+ "MediaTrackNext": { "keyCode": 176, "key": "MediaTrackNext" },
127
+ "MediaTrackPrevious": { "keyCode": 177, "key": "MediaTrackPrevious" },
128
+ "MediaPlayPause": { "keyCode": 179, "key": "MediaPlayPause" },
122
129
  // Numpad
123
130
  "NumLock": { "keyCode": 144, "key": "NumLock" },
124
131
  "NumpadDivide": { "keyCode": 111, "key": "/", "location": 3 },
@@ -37,7 +37,7 @@ var import_pixelmatch = __toESM(require("../../third_party/pixelmatch"));
37
37
  var import_utilsBundle = require("../../utilsBundle");
38
38
  var import_utilsBundle2 = require("../../utilsBundle");
39
39
  var import_utilsBundle3 = require("../../utilsBundle");
40
- var import_imageUtils = require("./imageUtils");
40
+ var import_imageUtils = require("../../utils/isomorphic/imageUtils");
41
41
  function getComparator(mimeType) {
42
42
  if (mimeType === "image/png")
43
43
  return compareImages.bind(null, "image/png");
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var disposable_exports = {};
20
+ __export(disposable_exports, {
21
+ disposeAll: () => disposeAll
22
+ });
23
+ module.exports = __toCommonJS(disposable_exports);
24
+ async function disposeAll(disposables) {
25
+ const copy = [...disposables];
26
+ disposables.length = 0;
27
+ await Promise.all(copy.map((d) => d.dispose()));
28
+ }
29
+ // Annotate the CommonJS export names for ESM import in node:
30
+ 0 && (module.exports = {
31
+ disposeAll
32
+ });
@@ -24,7 +24,9 @@ module.exports = __toCommonJS(eventsHelper_exports);
24
24
  class EventsHelper {
25
25
  static addEventListener(emitter, eventName, handler) {
26
26
  emitter.on(eventName, handler);
27
- return { emitter, eventName, handler };
27
+ return { emitter, eventName, handler, dispose: async () => {
28
+ emitter.removeListener(eventName, handler);
29
+ } };
28
30
  }
29
31
  static removeEventListeners(listeners) {
30
32
  for (const listener of listeners)
@@ -32,6 +32,7 @@ __export(fileUtils_exports, {
32
32
  canAccessFile: () => canAccessFile,
33
33
  copyFileAndMakeWritable: () => copyFileAndMakeWritable,
34
34
  existsAsync: () => existsAsync,
35
+ makeSocketPath: () => makeSocketPath,
35
36
  mkdirIfNeeded: () => mkdirIfNeeded,
36
37
  removeFolders: () => removeFolders,
37
38
  sanitizeForFilePath: () => sanitizeForFilePath,
@@ -39,9 +40,10 @@ __export(fileUtils_exports, {
39
40
  });
40
41
  module.exports = __toCommonJS(fileUtils_exports);
41
42
  var import_fs = __toESM(require("fs"));
43
+ var import_os = __toESM(require("os"));
42
44
  var import_path = __toESM(require("path"));
45
+ var import_crypto = require("./crypto");
43
46
  var import_manualPromise = require("../../utils/isomorphic/manualPromise");
44
- var import_zipBundle = require("../../zipBundle");
45
47
  const existsAsync = (path2) => new Promise((resolve) => import_fs.default.stat(path2, (err) => resolve(!err)));
46
48
  async function mkdirIfNeeded(filePath) {
47
49
  await import_fs.default.promises.mkdir(import_path.default.dirname(filePath), { recursive: true }).catch(() => {
@@ -72,6 +74,16 @@ function sanitizeForFilePath(s) {
72
74
  function toPosixPath(aPath) {
73
75
  return aPath.split(import_path.default.sep).join(import_path.default.posix.sep);
74
76
  }
77
+ function makeSocketPath(domain, name) {
78
+ const userNameHash = (0, import_crypto.calculateSha1)(process.env.USERNAME || process.env.USER || "default").slice(0, 8);
79
+ if (process.platform === "win32")
80
+ return `\\\\.\\pipe\\pw-${userNameHash}-${domain}-${name}`;
81
+ const baseDir = process.env.PLAYWRIGHT_SOCKETS_DIR || import_path.default.join(import_os.default.tmpdir(), `pw-${userNameHash}`);
82
+ const dir = import_path.default.join(baseDir, domain);
83
+ const result = import_path.default.join(dir, `${name}.sock`);
84
+ import_fs.default.mkdirSync(dir, { recursive: true });
85
+ return result;
86
+ }
75
87
  class SerializedFS {
76
88
  constructor() {
77
89
  this._buffers = /* @__PURE__ */ new Map();
@@ -165,7 +177,8 @@ class SerializedFS {
165
177
  return;
166
178
  }
167
179
  case "zip": {
168
- const zipFile = new import_zipBundle.yazl.ZipFile();
180
+ const { yazl } = await import("playwright-core/lib/zipBundle");
181
+ const zipFile = new yazl.ZipFile();
169
182
  const result = new import_manualPromise.ManualPromise();
170
183
  zipFile.on("error", (error) => result.reject(error));
171
184
  for (const entry of op.entries)
@@ -184,6 +197,7 @@ class SerializedFS {
184
197
  canAccessFile,
185
198
  copyFileAndMakeWritable,
186
199
  existsAsync,
200
+ makeSocketPath,
187
201
  mkdirIfNeeded,
188
202
  removeFolders,
189
203
  sanitizeForFilePath,