patchright-core 1.58.2 → 1.59.1

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 (285) 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 +22 -61
  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/clientHelper.js +2 -1
  16. package/lib/client/clock.js +0 -1
  17. package/lib/client/{webSocket.js → connect.js} +57 -7
  18. package/lib/client/connection.js +8 -4
  19. package/lib/client/consoleMessage.js +3 -0
  20. package/lib/client/debugger.js +57 -0
  21. package/lib/client/dialog.js +8 -1
  22. package/lib/client/disposable.js +76 -0
  23. package/lib/client/electron.js +1 -0
  24. package/lib/client/elementHandle.js +1 -4
  25. package/lib/client/events.js +3 -3
  26. package/lib/client/fetch.js +0 -1
  27. package/lib/client/frame.js +10 -23
  28. package/lib/client/harRouter.js +13 -1
  29. package/lib/client/jsHandle.js +4 -8
  30. package/lib/client/locator.js +13 -44
  31. package/lib/client/network.js +15 -16
  32. package/lib/client/page.js +41 -75
  33. package/lib/client/platform.js +0 -3
  34. package/lib/client/screencast.js +88 -0
  35. package/lib/client/selectors.js +3 -1
  36. package/lib/client/tracing.js +11 -5
  37. package/lib/client/video.js +13 -20
  38. package/lib/client/worker.js +6 -6
  39. package/lib/generated/bindingsControllerSource.js +1 -1
  40. package/lib/generated/clockSource.js +1 -1
  41. package/lib/generated/injectedScriptSource.js +1 -1
  42. package/lib/generated/pollingRecorderSource.js +1 -1
  43. package/lib/generated/storageScriptSource.js +1 -1
  44. package/lib/generated/utilityScriptSource.js +1 -1
  45. package/lib/mcpBundle.js +0 -6
  46. package/lib/mcpBundleImpl.js +91 -0
  47. package/lib/protocol/validator.js +224 -138
  48. package/lib/protocol/validatorPrimitives.js +1 -1
  49. package/lib/remote/playwrightConnection.js +10 -8
  50. package/lib/remote/playwrightPipeServer.js +100 -0
  51. package/lib/remote/playwrightServer.js +13 -8
  52. package/lib/remote/playwrightWebSocketServer.js +73 -0
  53. package/lib/remote/serverTransport.js +96 -0
  54. package/lib/server/android/android.js +2 -2
  55. package/lib/server/bidi/bidiBrowser.js +30 -8
  56. package/lib/server/bidi/bidiChromium.js +18 -5
  57. package/lib/server/bidi/bidiNetworkManager.js +39 -11
  58. package/lib/server/bidi/bidiPage.js +31 -15
  59. package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
  60. package/lib/server/browser.js +84 -21
  61. package/lib/server/browserContext.js +110 -58
  62. package/lib/server/browserType.js +14 -12
  63. package/lib/server/chromium/chromium.js +15 -12
  64. package/lib/server/chromium/chromiumSwitches.js +14 -2
  65. package/lib/server/chromium/crBrowser.js +20 -17
  66. package/lib/server/chromium/crCoverage.js +1 -13
  67. package/lib/server/chromium/crDevTools.js +1 -0
  68. package/lib/server/chromium/crNetworkManager.js +12 -267
  69. package/lib/server/chromium/crPage.js +67 -199
  70. package/lib/server/chromium/crServiceWorker.js +7 -14
  71. package/lib/server/clock.js +33 -41
  72. package/lib/server/console.js +5 -1
  73. package/lib/server/debugController.js +12 -6
  74. package/lib/server/debugger.js +40 -47
  75. package/lib/server/deviceDescriptorsSource.json +137 -137
  76. package/lib/server/dispatchers/browserContextDispatcher.js +29 -30
  77. package/lib/server/dispatchers/browserDispatcher.js +11 -5
  78. package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
  79. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
  80. package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
  81. package/lib/server/dispatchers/dispatcher.js +1 -1
  82. package/lib/server/dispatchers/disposableDispatcher.js +39 -0
  83. package/lib/server/dispatchers/electronDispatcher.js +2 -1
  84. package/lib/server/dispatchers/frameDispatcher.js +6 -6
  85. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  86. package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
  87. package/lib/server/dispatchers/networkDispatchers.js +6 -5
  88. package/lib/server/dispatchers/pageDispatcher.js +101 -38
  89. package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
  90. package/lib/server/disposable.js +41 -0
  91. package/lib/server/dom.js +44 -26
  92. package/lib/server/download.js +3 -2
  93. package/lib/server/electron/electron.js +12 -7
  94. package/lib/server/firefox/ffBrowser.js +9 -19
  95. package/lib/server/firefox/ffInput.js +21 -5
  96. package/lib/server/firefox/ffNetworkManager.js +2 -2
  97. package/lib/server/firefox/ffPage.js +24 -27
  98. package/lib/server/frameSelectors.js +5 -172
  99. package/lib/server/frames.js +234 -687
  100. package/lib/server/har/harRecorder.js +2 -2
  101. package/lib/server/har/harTracer.js +5 -4
  102. package/lib/server/input.js +49 -4
  103. package/lib/server/instrumentation.js +5 -0
  104. package/lib/server/javascript.js +6 -26
  105. package/lib/server/launchApp.js +1 -3
  106. package/lib/server/localUtils.js +6 -6
  107. package/lib/server/network.js +9 -8
  108. package/lib/server/overlay.js +138 -0
  109. package/lib/server/page.js +157 -105
  110. package/lib/server/progress.js +6 -0
  111. package/lib/server/recorder/recorderApp.js +9 -8
  112. package/lib/server/recorder.js +76 -40
  113. package/lib/server/registry/index.js +55 -82
  114. package/lib/server/registry/nativeDeps.js +1 -0
  115. package/lib/server/screencast.js +90 -143
  116. package/lib/server/screenshotter.js +0 -6
  117. package/lib/server/trace/recorder/snapshotter.js +8 -17
  118. package/lib/server/trace/recorder/snapshotterInjected.js +82 -20
  119. package/lib/server/trace/recorder/tracing.js +87 -44
  120. package/lib/server/trace/viewer/traceViewer.js +3 -4
  121. package/lib/server/usKeyboardLayout.js +7 -0
  122. package/lib/server/utils/comparators.js +1 -1
  123. package/lib/server/utils/disposable.js +32 -0
  124. package/lib/server/utils/eventsHelper.js +3 -1
  125. package/lib/server/utils/fileUtils.js +16 -2
  126. package/lib/server/utils/happyEyeballs.js +15 -12
  127. package/lib/server/utils/hostPlatform.js +0 -15
  128. package/lib/server/utils/httpServer.js +5 -3
  129. package/lib/server/utils/network.js +2 -1
  130. package/lib/server/utils/nodePlatform.js +0 -6
  131. package/lib/server/utils/processLauncher.js +6 -5
  132. package/lib/server/utils/zipFile.js +2 -2
  133. package/lib/server/videoRecorder.js +82 -12
  134. package/lib/server/webkit/wkBrowser.js +1 -6
  135. package/lib/server/webkit/wkPage.js +27 -25
  136. package/lib/server/webkit/wkWorkers.js +2 -1
  137. package/lib/serverRegistry.js +156 -0
  138. package/lib/tools/backend/browserBackend.js +79 -0
  139. package/lib/tools/backend/common.js +63 -0
  140. package/lib/tools/backend/config.js +41 -0
  141. package/lib/tools/backend/console.js +66 -0
  142. package/lib/tools/backend/context.js +296 -0
  143. package/lib/tools/backend/cookies.js +152 -0
  144. package/lib/tools/backend/devtools.js +69 -0
  145. package/lib/tools/backend/dialogs.js +59 -0
  146. package/lib/tools/backend/evaluate.js +64 -0
  147. package/lib/tools/backend/files.js +60 -0
  148. package/lib/tools/backend/form.js +64 -0
  149. package/lib/tools/backend/keyboard.js +155 -0
  150. package/lib/tools/backend/logFile.js +95 -0
  151. package/lib/tools/backend/mouse.js +168 -0
  152. package/lib/tools/backend/navigate.js +106 -0
  153. package/lib/tools/backend/network.js +135 -0
  154. package/lib/tools/backend/pdf.js +48 -0
  155. package/lib/tools/backend/response.js +305 -0
  156. package/lib/tools/backend/route.js +140 -0
  157. package/lib/tools/backend/runCode.js +77 -0
  158. package/lib/tools/backend/screenshot.js +88 -0
  159. package/lib/tools/backend/sessionLog.js +74 -0
  160. package/lib/tools/backend/snapshot.js +208 -0
  161. package/lib/tools/backend/storage.js +68 -0
  162. package/lib/tools/backend/tab.js +445 -0
  163. package/lib/tools/backend/tabs.js +67 -0
  164. package/lib/tools/backend/tool.js +47 -0
  165. package/lib/tools/backend/tools.js +102 -0
  166. package/lib/tools/backend/tracing.js +78 -0
  167. package/lib/tools/backend/utils.js +83 -0
  168. package/lib/tools/backend/verify.js +151 -0
  169. package/lib/tools/backend/video.js +98 -0
  170. package/lib/tools/backend/wait.js +63 -0
  171. package/lib/tools/backend/webstorage.js +223 -0
  172. package/lib/tools/cli-client/cli.js +6 -0
  173. package/lib/tools/cli-client/help.json +399 -0
  174. package/lib/tools/cli-client/minimist.js +128 -0
  175. package/lib/tools/cli-client/program.js +350 -0
  176. package/lib/tools/cli-client/registry.js +176 -0
  177. package/lib/tools/cli-client/session.js +289 -0
  178. package/lib/tools/cli-client/skill/SKILL.md +328 -0
  179. package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
  180. package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
  181. package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
  182. package/lib/tools/cli-client/skill/references/running-code.md +231 -0
  183. package/lib/tools/cli-client/skill/references/session-management.md +169 -0
  184. package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
  185. package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
  186. package/lib/tools/cli-client/skill/references/tracing.md +139 -0
  187. package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
  188. package/lib/tools/cli-daemon/command.js +73 -0
  189. package/lib/tools/cli-daemon/commands.js +956 -0
  190. package/lib/tools/cli-daemon/daemon.js +157 -0
  191. package/lib/tools/cli-daemon/helpGenerator.js +177 -0
  192. package/lib/tools/cli-daemon/program.js +129 -0
  193. package/lib/tools/dashboard/appIcon.png +0 -0
  194. package/lib/tools/dashboard/dashboardApp.js +284 -0
  195. package/lib/tools/dashboard/dashboardController.js +296 -0
  196. package/lib/tools/exports.js +60 -0
  197. package/lib/tools/mcp/browserFactory.js +233 -0
  198. package/lib/tools/mcp/cdpRelay.js +352 -0
  199. package/lib/tools/mcp/cli-stub.js +7 -0
  200. package/lib/tools/mcp/config.d.js +16 -0
  201. package/lib/tools/mcp/config.js +446 -0
  202. package/lib/tools/mcp/configIni.js +189 -0
  203. package/lib/tools/mcp/extensionContextFactory.js +55 -0
  204. package/lib/tools/mcp/index.js +62 -0
  205. package/lib/tools/mcp/log.js +35 -0
  206. package/lib/tools/mcp/program.js +107 -0
  207. package/lib/tools/mcp/protocol.js +28 -0
  208. package/lib/tools/mcp/watchdog.js +44 -0
  209. package/lib/tools/trace/SKILL.md +171 -0
  210. package/lib/{server/trace/viewer/traceParser.js → tools/trace/installSkill.js} +15 -39
  211. package/lib/tools/trace/traceActions.js +142 -0
  212. package/lib/tools/trace/traceAttachments.js +69 -0
  213. package/lib/tools/trace/traceCli.js +87 -0
  214. package/lib/tools/trace/traceConsole.js +97 -0
  215. package/lib/tools/trace/traceErrors.js +55 -0
  216. package/lib/tools/trace/traceOpen.js +69 -0
  217. package/lib/tools/trace/traceParser.js +96 -0
  218. package/lib/tools/trace/traceRequests.js +182 -0
  219. package/lib/tools/trace/traceScreenshot.js +68 -0
  220. package/lib/tools/trace/traceSnapshot.js +149 -0
  221. package/lib/tools/trace/traceUtils.js +153 -0
  222. package/lib/tools/utils/connect.js +32 -0
  223. package/lib/tools/utils/mcp/http.js +152 -0
  224. package/lib/tools/utils/mcp/server.js +230 -0
  225. package/lib/tools/utils/mcp/tool.js +47 -0
  226. package/lib/tools/utils/socketConnection.js +108 -0
  227. package/lib/utils/isomorphic/formatUtils.js +64 -0
  228. package/lib/utils/isomorphic/jsonSchema.js +89 -0
  229. package/lib/utils/isomorphic/mimeType.js +7 -2
  230. package/lib/utils/isomorphic/protocolFormatter.js +2 -2
  231. package/lib/utils/isomorphic/protocolMetainfo.js +127 -106
  232. package/lib/utils/isomorphic/stringUtils.js +3 -3
  233. package/lib/utils/isomorphic/timeoutRunner.js +3 -3
  234. package/lib/utils/isomorphic/trace/snapshotRenderer.js +35 -42
  235. package/lib/utils/isomorphic/trace/traceLoader.js +15 -14
  236. package/lib/utils/isomorphic/trace/traceModel.js +3 -2
  237. package/lib/utils/isomorphic/trace/traceModernizer.js +1 -0
  238. package/lib/utils/isomorphic/urlMatch.js +54 -1
  239. package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
  240. package/lib/utils.js +6 -2
  241. package/lib/utilsBundle.js +3 -21
  242. package/lib/utilsBundleImpl/index.js +132 -133
  243. package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
  244. package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
  245. package/lib/vite/dashboard/index.html +28 -0
  246. package/lib/vite/htmlReport/index.html +2 -70
  247. package/lib/vite/htmlReport/report.css +1 -0
  248. package/lib/vite/htmlReport/report.js +72 -0
  249. package/lib/vite/recorder/assets/{codeMirrorModule-CFUTFUO7.js → codeMirrorModule-C8KMvO9L.js} +20 -20
  250. package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
  251. package/lib/vite/recorder/index.html +1 -1
  252. package/lib/vite/traceViewer/assets/{codeMirrorModule-BVA4h_ZY.js → codeMirrorModule-DS0FLvoc.js} +20 -20
  253. package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
  254. package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
  255. package/lib/vite/traceViewer/{index.BtyWtaE-.js → index.C5466mMT.js} +1 -1
  256. package/lib/vite/traceViewer/{index.BVu7tZDe.css → index.CzXZzn5A.css} +1 -1
  257. package/lib/vite/traceViewer/index.html +4 -4
  258. package/lib/vite/traceViewer/sw.bundle.js +4 -4
  259. package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
  260. package/lib/vite/traceViewer/uiMode.html +3 -3
  261. package/lib/zipBundleImpl.js +2 -2
  262. package/lib/zodBundle.js +39 -0
  263. package/lib/zodBundleImpl.js +40 -0
  264. package/package.json +6 -1
  265. package/types/protocol.d.ts +947 -51
  266. package/types/types.d.ts +854 -74
  267. package/lib/client/pageAgent.js +0 -64
  268. package/lib/mcpBundleImpl/index.js +0 -147
  269. package/lib/server/agent/actionRunner.js +0 -335
  270. package/lib/server/agent/actions.js +0 -128
  271. package/lib/server/agent/codegen.js +0 -111
  272. package/lib/server/agent/context.js +0 -150
  273. package/lib/server/agent/expectTools.js +0 -156
  274. package/lib/server/agent/pageAgent.js +0 -204
  275. package/lib/server/agent/performTools.js +0 -262
  276. package/lib/server/agent/tool.js +0 -109
  277. package/lib/server/dispatchers/pageAgentDispatcher.js +0 -96
  278. package/lib/server/pageBinding.js +0 -87
  279. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +0 -248
  280. package/lib/vite/recorder/assets/index-CVkBxsGf.js +0 -193
  281. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +0 -266
  282. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +0 -1
  283. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +0 -5
  284. /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
  285. /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
@@ -36,6 +36,7 @@ var import_eventsHelper = require("../utils/eventsHelper");
36
36
  var import_cookieStore = require("../cookieStore");
37
37
  var network = __toESM(require("../network"));
38
38
  var bidi = __toESM(require("./third_party/bidiProtocol"));
39
+ const REQUEST_BODY_HEADERS = /* @__PURE__ */ new Set(["content-encoding", "content-language", "content-location", "content-type"]);
39
40
  class BidiNetworkManager {
40
41
  constructor(bidiSession, page) {
41
42
  this._userRequestInterceptionEnabled = false;
@@ -64,12 +65,38 @@ class BidiNetworkManager {
64
65
  return;
65
66
  if (redirectedFrom)
66
67
  this._deleteRequest(redirectedFrom._id);
68
+ if (param.request.method === "OPTIONS") {
69
+ const requestHeaders = Object.fromEntries(param.request.headers.map((h) => [h.name.toLowerCase(), bidiBytesValueToString(h.value)]));
70
+ if (param.initiator?.type === "preflight" || requestHeaders["access-control-request-method"]) {
71
+ if (param.intercepts) {
72
+ const responseHeaders = [
73
+ { name: "Access-Control-Allow-Origin", value: requestHeaders["origin"] || "*" },
74
+ { name: "Access-Control-Allow-Methods", value: requestHeaders["access-control-request-method"] },
75
+ { name: "Access-Control-Allow-Credentials", value: "true" }
76
+ ];
77
+ if (requestHeaders["access-control-request-headers"])
78
+ responseHeaders.push({ name: "Access-Control-Allow-Headers", value: requestHeaders["access-control-request-headers"] });
79
+ this._session.sendMayFail("network.provideResponse", {
80
+ request: param.request.request,
81
+ statusCode: 204,
82
+ headers: toBidiHeaders(responseHeaders)
83
+ });
84
+ }
85
+ return;
86
+ }
87
+ }
67
88
  let route;
89
+ let headersOverride;
68
90
  if (param.intercepts) {
69
91
  if (redirectedFrom) {
70
92
  let params = {};
71
- if (redirectedFrom._originalRequestRoute?._alreadyContinuedHeaders)
72
- params = toBidiRequestHeaders(redirectedFrom._originalRequestRoute._alreadyContinuedHeaders ?? []);
93
+ if (redirectedFrom._originalRequestRoute?._alreadyContinuedHeaders) {
94
+ const originalHeaders = fromBidiHeaders(param.request.headers);
95
+ headersOverride = network.applyHeadersOverrides(originalHeaders, redirectedFrom._originalRequestRoute._alreadyContinuedHeaders);
96
+ if (redirectedFrom.request.method() === "POST" && param.request.method === "GET")
97
+ headersOverride = headersOverride.filter(({ name }) => !REQUEST_BODY_HEADERS.has(name.toLowerCase()));
98
+ params = toBidiRequestHeaders(headersOverride);
99
+ }
73
100
  this._session.sendMayFail("network.continueRequest", {
74
101
  request: param.request.request,
75
102
  ...params
@@ -78,7 +105,7 @@ class BidiNetworkManager {
78
105
  route = new BidiRouteImpl(this._session, param.request.request);
79
106
  }
80
107
  }
81
- const request = new BidiRequest(frame, redirectedFrom, param, route);
108
+ const request = new BidiRequest(frame, redirectedFrom, param, route, headersOverride);
82
109
  this._requests.set(request._id, request);
83
110
  this._page.frameManager.requestStarted(request.request, route);
84
111
  }
@@ -111,6 +138,7 @@ class BidiNetworkManager {
111
138
  const response = new network.Response(request.request, params.response.status, params.response.statusText, fromBidiHeaders(params.response.headers), timing, getResponseBody, false);
112
139
  response._serverAddrFinished();
113
140
  response._securityDetailsFinished();
141
+ response._setHttpVersion(params.response.protocol);
114
142
  response.setRawResponseHeaders(null);
115
143
  response.setResponseHeadersSize(params.response.headersSize);
116
144
  this._page.frameManager.requestReceivedResponse(response);
@@ -130,7 +158,6 @@ class BidiNetworkManager {
130
158
  this._deleteRequest(request._id);
131
159
  response._requestFinished(responseEndTime);
132
160
  }
133
- response._setHttpVersion(params.response.protocol);
134
161
  this._page.frameManager.reportRequestFinished(request.request, response);
135
162
  }
136
163
  _onFetchError(params) {
@@ -194,13 +221,13 @@ class BidiNetworkManager {
194
221
  this._protocolRequestInterceptionEnabled = enabled;
195
222
  if (initial && !enabled)
196
223
  return;
197
- const cachePromise = this._session.send("network.setCacheBehavior", { cacheBehavior: enabled ? "bypass" : "default" });
224
+ const contexts = [this._page.delegate._session.sessionId];
225
+ const cachePromise = this._session.send("network.setCacheBehavior", { cacheBehavior: enabled ? "bypass" : "default", contexts });
198
226
  let interceptPromise = Promise.resolve(void 0);
199
227
  if (enabled) {
200
228
  interceptPromise = this._session.send("network.addIntercept", {
201
- phases: [bidi.Network.InterceptPhase.AuthRequired, bidi.Network.InterceptPhase.BeforeRequestSent],
202
- urlPatterns: [{ type: "pattern" }]
203
- // urlPatterns: [{ type: 'string', pattern: '*' }],
229
+ phases: [bidi.Network.InterceptPhase.BeforeRequestSent],
230
+ contexts
204
231
  }).then((r) => {
205
232
  this._intercepId = r.intercept;
206
233
  });
@@ -212,7 +239,7 @@ class BidiNetworkManager {
212
239
  }
213
240
  }
214
241
  class BidiRequest {
215
- constructor(frame, redirectedFrom, payload, route) {
242
+ constructor(frame, redirectedFrom, payload, route, headersOverride) {
216
243
  this._id = payload.request.request;
217
244
  if (redirectedFrom)
218
245
  redirectedFrom._redirectedTo = this;
@@ -227,7 +254,7 @@ class BidiRequest {
227
254
  resourceTypeFromBidi(payload.request.destination, payload.request.initiatorType, payload.initiator?.type),
228
255
  payload.request.method,
229
256
  postDataBuffer,
230
- fromBidiHeaders(payload.request.headers)
257
+ headersOverride || fromBidiHeaders(payload.request.headers)
231
258
  );
232
259
  this.request.setRawRequestHeaders(null);
233
260
  this.request._setBodySize(payload.request.bodySize || 0);
@@ -269,11 +296,12 @@ class BidiRouteImpl {
269
296
  }
270
297
  async fulfill(response) {
271
298
  const base64body = response.isBase64 ? response.body : Buffer.from(response.body).toString("base64");
299
+ const headers = response.headers.filter((h) => h.name.toLowerCase() !== "content-encoding");
272
300
  await this._session.sendMayFail("network.provideResponse", {
273
301
  request: this._requestId,
274
302
  statusCode: response.status,
275
303
  reasonPhrase: network.statusText(response.status),
276
- ...toBidiResponseHeaders(response.headers),
304
+ ...toBidiResponseHeaders(headers),
277
305
  body: { type: "base64", value: base64body }
278
306
  });
279
307
  }
@@ -51,12 +51,13 @@ class BidiPage {
51
51
  this._realmToWorkerContext = /* @__PURE__ */ new Map();
52
52
  this._sessionListeners = [];
53
53
  this._initScriptIds = /* @__PURE__ */ new Map();
54
+ this._fragmentNavigations = /* @__PURE__ */ new Set();
54
55
  this._session = bidiSession;
55
56
  this._opener = opener;
56
57
  this.rawKeyboard = new import_bidiInput.RawKeyboardImpl(bidiSession);
57
58
  this.rawMouse = new import_bidiInput.RawMouseImpl(bidiSession);
58
59
  this.rawTouchscreen = new import_bidiInput.RawTouchscreenImpl(bidiSession);
59
- this._realmToContext = /* @__PURE__ */ new Map();
60
+ this._contextIdToContext = /* @__PURE__ */ new Map();
60
61
  this._page = new import_page.Page(this, browserContext);
61
62
  this._browserContext = browserContext;
62
63
  this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page);
@@ -102,9 +103,9 @@ class BidiPage {
102
103
  return this._page.frameManager.frameAttached(frameId, parentFrameId);
103
104
  }
104
105
  _removeContextsForFrame(frame, notifyFrame) {
105
- for (const [contextId, context] of this._realmToContext) {
106
+ for (const [contextId, context] of this._contextIdToContext) {
106
107
  if (context.frame === frame) {
107
- this._realmToContext.delete(contextId);
108
+ this._contextIdToContext.delete(contextId);
108
109
  if (notifyFrame)
109
110
  frame._contextDestroyed(context);
110
111
  }
@@ -119,7 +120,7 @@ class BidiPage {
119
120
  this._page.addWorker(realmInfo.realm, worker);
120
121
  return;
121
122
  }
122
- if (this._realmToContext.has(realmInfo.realm))
123
+ if (this._contextIdToContext.has(realmInfo.realm))
123
124
  return;
124
125
  if (realmInfo.type !== "window")
125
126
  return;
@@ -138,7 +139,7 @@ class BidiPage {
138
139
  const delegate = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
139
140
  const context = new dom.FrameExecutionContext(delegate, frame, worldName);
140
141
  frame._contextCreated(worldName, context);
141
- this._realmToContext.set(realmInfo.realm, context);
142
+ this._contextIdToContext.set(realmInfo.realm, context);
142
143
  }
143
144
  async _touchUtilityWorld(context) {
144
145
  await this._session.sendMayFail("script.evaluate", {
@@ -156,9 +157,9 @@ class BidiPage {
156
157
  });
157
158
  }
158
159
  _onRealmDestroyed(params) {
159
- const context = this._realmToContext.get(params.realm);
160
+ const context = this._contextIdToContext.get(params.realm);
160
161
  if (context) {
161
- this._realmToContext.delete(params.realm);
162
+ this._contextIdToContext.delete(params.realm);
162
163
  context.frame._contextDestroyed(context);
163
164
  return true;
164
165
  }
@@ -204,6 +205,8 @@ class BidiPage {
204
205
  this._page.frameManager.frameAbortedNavigation(params.context, "Navigation failed", params.navigation || void 0);
205
206
  }
206
207
  _onFragmentNavigated(params) {
208
+ if (params.navigation)
209
+ this._fragmentNavigations.add(params.navigation);
207
210
  this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
208
211
  }
209
212
  _onHistoryUpdated(params) {
@@ -229,7 +232,7 @@ class BidiPage {
229
232
  originPage = this._opener._page.initializedOrUndefined();
230
233
  if (!originPage)
231
234
  return;
232
- this._browserContext._browser._downloadCreated(originPage, event.navigation, event.url, event.suggestedFilename);
235
+ this._browserContext._browser._downloadCreated(originPage, event.navigation, event.url, event.suggestedFilename, event.suggestedFilename);
233
236
  }
234
237
  _onDownloadEnded(event) {
235
238
  if (!event.navigation)
@@ -260,12 +263,13 @@ ${params.stackTrace?.callFrames.map((f) => {
260
263
  if (params.type !== "console")
261
264
  return;
262
265
  const entry = params;
263
- const context = this._realmToContext.get(params.source.realm) ?? this._realmToWorkerContext.get(params.source.realm);
266
+ const context = this._contextIdToContext.get(params.source.realm) ?? this._realmToWorkerContext.get(params.source.realm);
264
267
  if (!context)
265
268
  return;
266
269
  const callFrame = params.stackTrace?.callFrames[0];
267
270
  const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
268
- this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location);
271
+ const type = entry.method === "warn" ? "warning" : entry.method;
272
+ this._page.addConsoleMessage(null, type, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, void 0, params.timestamp);
269
273
  }
270
274
  async _onFileDialogOpened(params) {
271
275
  if (!params.element)
@@ -285,6 +289,10 @@ ${params.stackTrace?.callFrames.map((f) => {
285
289
  context: frame._id,
286
290
  url
287
291
  });
292
+ if (navigation && this._fragmentNavigations.has(navigation)) {
293
+ this._fragmentNavigations.delete(navigation);
294
+ return {};
295
+ }
288
296
  return { newDocumentId: navigation || void 0 };
289
297
  }
290
298
  async updateExtraHTTPHeaders() {
@@ -365,7 +373,13 @@ ${params.stackTrace?.callFrames.map((f) => {
365
373
  }).then(() => true).catch(() => false);
366
374
  }
367
375
  async requestGC() {
368
- throw new Error("Method not implemented.");
376
+ const result = await this._session.send("script.evaluate", {
377
+ expression: "TestUtils.gc()",
378
+ target: { context: this._session.sessionId },
379
+ awaitPromise: true
380
+ });
381
+ if (result.type === "exception")
382
+ throw new Error("Method not implemented.");
369
383
  }
370
384
  async _onScriptMessage(event) {
371
385
  if (event.channel !== kPlaywrightBindingChannel)
@@ -373,7 +387,7 @@ ${params.stackTrace?.callFrames.map((f) => {
373
387
  const pageOrError = await this._page.waitForInitializedOrError();
374
388
  if (pageOrError instanceof Error)
375
389
  return;
376
- const context = this._realmToContext.get(event.source.realm);
390
+ const context = this._contextIdToContext.get(event.source.realm);
377
391
  if (!context)
378
392
  return;
379
393
  if (event.data.type !== "string")
@@ -422,7 +436,7 @@ ${params.stackTrace?.callFrames.map((f) => {
422
436
  context: this._session.sessionId,
423
437
  format: {
424
438
  type: `image/${format === "png" ? "png" : "jpeg"}`,
425
- quality: quality ? quality / 100 : 0.8
439
+ quality: quality !== void 0 ? quality / 100 : void 0
426
440
  },
427
441
  origin: documentRect ? "document" : "viewport",
428
442
  clip: {
@@ -495,9 +509,9 @@ ${params.stackTrace?.callFrames.map((f) => {
495
509
  throw e;
496
510
  });
497
511
  }
498
- async startScreencast(options) {
512
+ startScreencast(options) {
499
513
  }
500
- async stopScreencast() {
514
+ stopScreencast() {
501
515
  }
502
516
  rafCountForStablePosition() {
503
517
  return 1;
@@ -572,6 +586,8 @@ ${params.stackTrace?.callFrames.map((f) => {
572
586
  shouldToggleStyleSheetToSyncAnimations() {
573
587
  return true;
574
588
  }
589
+ async setDockTile(image) {
590
+ }
575
591
  }
576
592
  function toBidiExecutionContext(executionContext) {
577
593
  return executionContext.delegate;
@@ -223,7 +223,9 @@ function defaultProfilePreferences(extraPrefs) {
223
223
  // Disable browser animations (tabs, fullscreen, sliding alerts)
224
224
  "toolkit.cosmeticAnimations.enabled": false,
225
225
  // Prevent starting into safe mode after application crashes
226
- "toolkit.startup.max_resumed_crashes": -1
226
+ "toolkit.startup.max_resumed_crashes": -1,
227
+ // Enable TestUtils
228
+ "dom.testing.testutils.enabled": true
227
229
  };
228
230
  return Object.assign(defaultPrefs, extraPrefs);
229
231
  }
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,29 +17,42 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
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
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var browser_exports = {};
20
30
  __export(browser_exports, {
21
- Browser: () => Browser
31
+ Browser: () => Browser,
32
+ BrowserServer: () => BrowserServer
22
33
  });
23
34
  module.exports = __toCommonJS(browser_exports);
24
- var import_artifact = require("./artifact");
35
+ var import_fs = __toESM(require("fs"));
25
36
  var import_browserContext = require("./browserContext");
26
37
  var import_download = require("./download");
27
38
  var import_instrumentation = require("./instrumentation");
28
- var import_page = require("./page");
29
39
  var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
40
+ var import_playwrightPipeServer = require("../remote/playwrightPipeServer");
41
+ var import_playwrightWebSocketServer = require("../remote/playwrightWebSocketServer");
42
+ var import_serverRegistry = require("../serverRegistry");
43
+ var import_fileUtils = require("./utils/fileUtils");
44
+ var import_utils = require("../utils");
30
45
  class Browser extends import_instrumentation.SdkObject {
31
46
  constructor(parent, options) {
32
47
  super(parent, "browser");
33
48
  this._downloads = /* @__PURE__ */ new Map();
34
49
  this._defaultContext = null;
35
50
  this._startedClosing = false;
36
- this._idToVideo = /* @__PURE__ */ new Map();
37
51
  this._isCollocatedWithServer = true;
38
52
  this.attribution.browser = this;
39
53
  this.options = options;
40
54
  this.instrumentation.onBrowserOpen(this);
55
+ this._server = new BrowserServer(this);
41
56
  }
42
57
  static {
43
58
  this.Events = {
@@ -88,8 +103,8 @@ class Browser extends import_instrumentation.SdkObject {
88
103
  contextForReuse() {
89
104
  return this._contextForReuse?.context;
90
105
  }
91
- _downloadCreated(page, uuid, url, suggestedFilename) {
92
- const download = new import_download.Download(page, this.options.downloadsPath || "", uuid, url, suggestedFilename);
106
+ _downloadCreated(page, uuid, url, suggestedFilename, downloadFilename) {
107
+ const download = new import_download.Download(page, this.options.downloadsPath || "", uuid, url, suggestedFilename, downloadFilename);
93
108
  this._downloads.set(uuid, download);
94
109
  }
95
110
  _downloadFilenameSuggested(uuid, suggestedFilename) {
@@ -105,27 +120,19 @@ class Browser extends import_instrumentation.SdkObject {
105
120
  download.artifact.reportFinished(error ? new Error(error) : void 0);
106
121
  this._downloads.delete(uuid);
107
122
  }
108
- _videoStarted(context, videoId, path, pageOrError) {
109
- const artifact = new import_artifact.Artifact(context, path);
110
- this._idToVideo.set(videoId, { context, artifact });
111
- pageOrError.then((page) => {
112
- if (page instanceof import_page.Page) {
113
- page.video = artifact;
114
- page.emitOnContext(import_browserContext.BrowserContext.Events.VideoStarted, artifact);
115
- page.emit(import_page.Page.Events.Video, artifact);
116
- }
117
- });
123
+ async startServer(title, options) {
124
+ return await this._server.start(title, options);
118
125
  }
119
- _takeVideo(videoId) {
120
- const video = this._idToVideo.get(videoId);
121
- this._idToVideo.delete(videoId);
122
- return video?.artifact;
126
+ async stopServer() {
127
+ await this._server.stop();
123
128
  }
124
129
  _didClose() {
125
130
  for (const context of this.contexts())
126
131
  context._browserClosed();
127
132
  if (this._defaultContext)
128
133
  this._defaultContext._browserClosed();
134
+ this.stopServer().catch(() => {
135
+ });
129
136
  this.emit(Browser.Events.Disconnected);
130
137
  this.instrumentation.onBrowserClose(this);
131
138
  }
@@ -143,7 +150,63 @@ class Browser extends import_instrumentation.SdkObject {
143
150
  await this.options.browserProcess.kill();
144
151
  }
145
152
  }
153
+ class BrowserServer {
154
+ constructor(browser) {
155
+ this._isStarted = false;
156
+ this._browser = browser;
157
+ }
158
+ async start(title, options) {
159
+ if (this._isStarted)
160
+ throw new Error(`Server is already started.`);
161
+ this._isStarted = true;
162
+ let endpoint;
163
+ if (options.host !== void 0 || options.port !== void 0) {
164
+ this._wsServer = new import_playwrightWebSocketServer.PlaywrightWebSocketServer(this._browser, "/");
165
+ endpoint = await this._wsServer.listen(options.port ?? 0, options.host, (0, import_utils.createGuid)());
166
+ } else {
167
+ this._pipeServer = new import_playwrightPipeServer.PlaywrightPipeServer(this._browser);
168
+ this._pipeSocketPath = await this._socketPath();
169
+ await this._pipeServer.listen(this._pipeSocketPath);
170
+ endpoint = this._pipeSocketPath;
171
+ }
172
+ const browserInfo = {
173
+ guid: this._browser.guid,
174
+ browserName: this._browser.options.browserType,
175
+ launchOptions: asClientLaunchOptions(this._browser.options.originalLaunchOptions),
176
+ userDataDir: this._browser.options.userDataDir
177
+ };
178
+ await import_serverRegistry.serverRegistry.create(browserInfo, {
179
+ title,
180
+ endpoint,
181
+ workspaceDir: options.workspaceDir,
182
+ metadata: options.metadata
183
+ });
184
+ return { endpoint };
185
+ }
186
+ async stop() {
187
+ if (!this._browser.options.userDataDir)
188
+ await import_serverRegistry.serverRegistry.delete(this._browser.guid);
189
+ if (this._pipeSocketPath && process.platform !== "win32")
190
+ await import_fs.default.promises.unlink(this._pipeSocketPath).catch(() => {
191
+ });
192
+ await this._pipeServer?.close();
193
+ await this._wsServer?.close();
194
+ this._pipeServer = void 0;
195
+ this._wsServer = void 0;
196
+ this._isStarted = false;
197
+ }
198
+ async _socketPath() {
199
+ return (0, import_fileUtils.makeSocketPath)("browser", this._browser.guid.slice(0, 14));
200
+ }
201
+ }
202
+ function asClientLaunchOptions(serverOptions) {
203
+ return {
204
+ ...serverOptions,
205
+ env: serverOptions.env ? Object.fromEntries(serverOptions.env.map(({ name, value }) => [name, value])) : void 0
206
+ };
207
+ }
146
208
  // Annotate the CommonJS export names for ESM import in node:
147
209
  0 && (module.exports = {
148
- Browser
210
+ Browser,
211
+ BrowserServer
149
212
  });