patchright-core 1.57.0 → 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 (307) hide show
  1. package/ThirdPartyNotices.txt +2688 -297
  2. package/browsers.json +23 -22
  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 +48 -413
  8. package/lib/client/android.js +4 -4
  9. package/lib/client/api.js +3 -0
  10. package/lib/client/browser.js +11 -5
  11. package/lib/client/browserContext.js +20 -23
  12. package/lib/client/browserType.js +23 -54
  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 -0
  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 -1
  25. package/lib/client/events.js +3 -0
  26. package/lib/client/fetch.js +2 -4
  27. package/lib/client/frame.js +9 -13
  28. package/lib/client/harRouter.js +13 -1
  29. package/lib/client/jsHandle.js +4 -8
  30. package/lib/client/locator.js +13 -36
  31. package/lib/client/network.js +14 -11
  32. package/lib/client/page.js +44 -50
  33. package/lib/client/screencast.js +88 -0
  34. package/lib/client/selectors.js +3 -1
  35. package/lib/client/tracing.js +11 -5
  36. package/lib/client/video.js +13 -20
  37. package/lib/client/worker.js +6 -6
  38. package/lib/generated/bindingsControllerSource.js +1 -1
  39. package/lib/generated/clockSource.js +1 -1
  40. package/lib/generated/injectedScriptSource.js +1 -1
  41. package/lib/generated/pollingRecorderSource.js +1 -1
  42. package/lib/generated/storageScriptSource.js +1 -1
  43. package/lib/generated/utilityScriptSource.js +1 -1
  44. package/lib/mcpBundle.js +78 -0
  45. package/lib/mcpBundleImpl.js +91 -0
  46. package/lib/protocol/serializers.js +5 -0
  47. package/lib/protocol/validator.js +228 -58
  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 +14 -10
  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/artifact.js +1 -1
  56. package/lib/server/bidi/bidiBrowser.js +80 -14
  57. package/lib/server/bidi/bidiChromium.js +23 -14
  58. package/lib/server/bidi/bidiConnection.js +1 -0
  59. package/lib/server/bidi/bidiDeserializer.js +116 -0
  60. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  61. package/lib/server/bidi/bidiFirefox.js +6 -8
  62. package/lib/server/bidi/bidiNetworkManager.js +40 -12
  63. package/lib/server/bidi/bidiPage.js +67 -40
  64. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  65. package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
  66. package/lib/server/browser.js +84 -21
  67. package/lib/server/browserContext.js +137 -77
  68. package/lib/server/browserType.js +26 -16
  69. package/lib/server/chromium/chromium.js +28 -31
  70. package/lib/server/chromium/chromiumSwitches.js +16 -4
  71. package/lib/server/chromium/crBrowser.js +40 -27
  72. package/lib/server/chromium/crConnection.js +0 -5
  73. package/lib/server/chromium/crDevTools.js +1 -2
  74. package/lib/server/chromium/crNetworkManager.js +54 -229
  75. package/lib/server/chromium/crPage.js +74 -260
  76. package/lib/server/chromium/crServiceWorker.js +7 -14
  77. package/lib/server/clock.js +33 -41
  78. package/lib/server/codegen/javascript.js +6 -29
  79. package/lib/server/console.js +5 -1
  80. package/lib/server/debugController.js +12 -6
  81. package/lib/server/debugger.js +40 -47
  82. package/lib/server/deviceDescriptorsSource.json +137 -137
  83. package/lib/server/dispatchers/browserContextDispatcher.js +30 -30
  84. package/lib/server/dispatchers/browserDispatcher.js +11 -5
  85. package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
  86. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
  87. package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
  88. package/lib/server/dispatchers/dispatcher.js +7 -14
  89. package/lib/server/dispatchers/disposableDispatcher.js +39 -0
  90. package/lib/server/dispatchers/electronDispatcher.js +2 -1
  91. package/lib/server/dispatchers/frameDispatcher.js +7 -7
  92. package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
  93. package/lib/server/dispatchers/networkDispatchers.js +6 -5
  94. package/lib/server/dispatchers/pageDispatcher.js +101 -34
  95. package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
  96. package/lib/server/disposable.js +41 -0
  97. package/lib/server/dom.js +56 -29
  98. package/lib/server/download.js +3 -2
  99. package/lib/server/electron/electron.js +17 -9
  100. package/lib/server/firefox/ffBrowser.js +9 -29
  101. package/lib/server/firefox/ffConnection.js +0 -5
  102. package/lib/server/firefox/ffInput.js +21 -5
  103. package/lib/server/firefox/ffNetworkManager.js +4 -4
  104. package/lib/server/firefox/ffPage.js +27 -33
  105. package/lib/server/firefox/firefox.js +6 -8
  106. package/lib/server/frameSelectors.js +14 -169
  107. package/lib/server/frames.js +263 -551
  108. package/lib/server/har/harRecorder.js +2 -2
  109. package/lib/server/har/harTracer.js +5 -4
  110. package/lib/server/input.js +49 -4
  111. package/lib/server/instrumentation.js +8 -0
  112. package/lib/server/javascript.js +6 -22
  113. package/lib/server/launchApp.js +0 -1
  114. package/lib/server/localUtils.js +6 -6
  115. package/lib/server/network.js +59 -20
  116. package/lib/server/overlay.js +138 -0
  117. package/lib/server/page.js +179 -157
  118. package/lib/server/progress.js +32 -6
  119. package/lib/server/recorder/recorderApp.js +84 -104
  120. package/lib/server/recorder.js +76 -40
  121. package/lib/server/registry/browserFetcher.js +6 -4
  122. package/lib/server/registry/index.js +222 -226
  123. package/lib/server/registry/nativeDeps.js +1 -0
  124. package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
  125. package/lib/server/screencast.js +137 -0
  126. package/lib/server/trace/recorder/snapshotter.js +2 -2
  127. package/lib/server/trace/recorder/snapshotterInjected.js +21 -1
  128. package/lib/server/trace/recorder/tracing.js +98 -47
  129. package/lib/server/trace/viewer/traceViewer.js +24 -21
  130. package/lib/server/usKeyboardLayout.js +7 -0
  131. package/lib/server/utils/comparators.js +1 -1
  132. package/lib/server/utils/disposable.js +32 -0
  133. package/lib/server/utils/eventsHelper.js +3 -1
  134. package/lib/server/utils/expectUtils.js +87 -2
  135. package/lib/server/utils/fileUtils.js +16 -2
  136. package/lib/server/utils/happyEyeballs.js +15 -12
  137. package/lib/server/utils/httpServer.js +10 -23
  138. package/lib/server/utils/network.js +39 -29
  139. package/lib/server/utils/processLauncher.js +8 -6
  140. package/lib/server/utils/zipFile.js +2 -2
  141. package/lib/server/videoRecorder.js +194 -0
  142. package/lib/server/webkit/webkit.js +4 -6
  143. package/lib/server/webkit/wkBrowser.js +1 -10
  144. package/lib/server/webkit/wkConnection.js +1 -6
  145. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  146. package/lib/server/webkit/wkPage.js +88 -57
  147. package/lib/server/webkit/wkWorkers.js +2 -1
  148. package/lib/serverRegistry.js +156 -0
  149. package/lib/tools/backend/browserBackend.js +79 -0
  150. package/lib/tools/backend/common.js +63 -0
  151. package/lib/tools/backend/config.js +41 -0
  152. package/lib/tools/backend/console.js +66 -0
  153. package/lib/tools/backend/context.js +296 -0
  154. package/lib/tools/backend/cookies.js +152 -0
  155. package/lib/tools/backend/devtools.js +69 -0
  156. package/lib/tools/backend/dialogs.js +59 -0
  157. package/lib/tools/backend/evaluate.js +64 -0
  158. package/lib/tools/backend/files.js +60 -0
  159. package/lib/tools/backend/form.js +64 -0
  160. package/lib/tools/backend/keyboard.js +155 -0
  161. package/lib/tools/backend/logFile.js +95 -0
  162. package/lib/tools/backend/mouse.js +168 -0
  163. package/lib/tools/backend/navigate.js +106 -0
  164. package/lib/tools/backend/network.js +135 -0
  165. package/lib/tools/backend/pdf.js +48 -0
  166. package/lib/tools/backend/response.js +305 -0
  167. package/lib/tools/backend/route.js +140 -0
  168. package/lib/tools/backend/runCode.js +77 -0
  169. package/lib/tools/backend/screenshot.js +88 -0
  170. package/lib/tools/backend/sessionLog.js +74 -0
  171. package/lib/tools/backend/snapshot.js +208 -0
  172. package/lib/tools/backend/storage.js +68 -0
  173. package/lib/tools/backend/tab.js +445 -0
  174. package/lib/tools/backend/tabs.js +67 -0
  175. package/lib/tools/backend/tool.js +47 -0
  176. package/lib/tools/backend/tools.js +102 -0
  177. package/lib/tools/backend/tracing.js +78 -0
  178. package/lib/tools/backend/utils.js +83 -0
  179. package/lib/tools/backend/verify.js +151 -0
  180. package/lib/tools/backend/video.js +98 -0
  181. package/lib/tools/backend/wait.js +63 -0
  182. package/lib/tools/backend/webstorage.js +223 -0
  183. package/lib/tools/cli-client/cli.js +6 -0
  184. package/lib/tools/cli-client/help.json +399 -0
  185. package/lib/tools/cli-client/minimist.js +128 -0
  186. package/lib/tools/cli-client/program.js +350 -0
  187. package/lib/tools/cli-client/registry.js +176 -0
  188. package/lib/tools/cli-client/session.js +289 -0
  189. package/lib/tools/cli-client/skill/SKILL.md +328 -0
  190. package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
  191. package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
  192. package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
  193. package/lib/tools/cli-client/skill/references/running-code.md +231 -0
  194. package/lib/tools/cli-client/skill/references/session-management.md +169 -0
  195. package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
  196. package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
  197. package/lib/tools/cli-client/skill/references/tracing.md +139 -0
  198. package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
  199. package/lib/tools/cli-daemon/command.js +73 -0
  200. package/lib/tools/cli-daemon/commands.js +956 -0
  201. package/lib/tools/cli-daemon/daemon.js +157 -0
  202. package/lib/tools/cli-daemon/helpGenerator.js +177 -0
  203. package/lib/tools/cli-daemon/program.js +129 -0
  204. package/lib/tools/dashboard/appIcon.png +0 -0
  205. package/lib/tools/dashboard/dashboardApp.js +284 -0
  206. package/lib/tools/dashboard/dashboardController.js +296 -0
  207. package/lib/tools/exports.js +60 -0
  208. package/lib/tools/mcp/browserFactory.js +233 -0
  209. package/lib/tools/mcp/cdpRelay.js +352 -0
  210. package/lib/tools/mcp/cli-stub.js +7 -0
  211. package/lib/tools/mcp/config.d.js +16 -0
  212. package/lib/tools/mcp/config.js +446 -0
  213. package/lib/tools/mcp/configIni.js +189 -0
  214. package/lib/tools/mcp/extensionContextFactory.js +55 -0
  215. package/lib/tools/mcp/index.js +62 -0
  216. package/lib/tools/mcp/log.js +35 -0
  217. package/lib/tools/mcp/program.js +107 -0
  218. package/lib/tools/mcp/protocol.js +28 -0
  219. package/lib/tools/mcp/watchdog.js +44 -0
  220. package/lib/tools/trace/SKILL.md +171 -0
  221. package/lib/tools/trace/installSkill.js +48 -0
  222. package/lib/tools/trace/traceActions.js +142 -0
  223. package/lib/tools/trace/traceAttachments.js +69 -0
  224. package/lib/tools/trace/traceCli.js +87 -0
  225. package/lib/tools/trace/traceConsole.js +97 -0
  226. package/lib/tools/trace/traceErrors.js +55 -0
  227. package/lib/tools/trace/traceOpen.js +69 -0
  228. package/lib/tools/trace/traceParser.js +96 -0
  229. package/lib/tools/trace/traceRequests.js +182 -0
  230. package/lib/tools/trace/traceScreenshot.js +68 -0
  231. package/lib/tools/trace/traceSnapshot.js +149 -0
  232. package/lib/tools/trace/traceUtils.js +153 -0
  233. package/lib/tools/utils/connect.js +32 -0
  234. package/lib/tools/utils/mcp/http.js +152 -0
  235. package/lib/tools/utils/mcp/server.js +230 -0
  236. package/lib/tools/utils/mcp/tool.js +47 -0
  237. package/lib/tools/utils/socketConnection.js +108 -0
  238. package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
  239. package/lib/utils/isomorphic/formatUtils.js +64 -0
  240. package/lib/utils/isomorphic/jsonSchema.js +89 -0
  241. package/lib/utils/isomorphic/lruCache.js +51 -0
  242. package/lib/utils/isomorphic/mimeType.js +7 -2
  243. package/lib/utils/isomorphic/protocolFormatter.js +2 -2
  244. package/lib/utils/isomorphic/protocolMetainfo.js +127 -98
  245. package/lib/utils/isomorphic/stringUtils.js +49 -0
  246. package/lib/utils/isomorphic/timeoutRunner.js +3 -3
  247. package/lib/utils/isomorphic/trace/entries.js +16 -0
  248. package/lib/utils/isomorphic/trace/snapshotRenderer.js +492 -0
  249. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  250. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  251. package/lib/utils/isomorphic/trace/traceLoader.js +132 -0
  252. package/lib/utils/isomorphic/trace/traceModel.js +366 -0
  253. package/lib/utils/isomorphic/trace/traceModernizer.js +401 -0
  254. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  255. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  256. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  257. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  258. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  259. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  260. package/lib/utils/isomorphic/urlMatch.js +54 -1
  261. package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
  262. package/lib/utils/isomorphic/yaml.js +84 -0
  263. package/lib/utils.js +8 -2
  264. package/lib/utilsBundle.js +5 -26
  265. package/lib/utilsBundleImpl/index.js +172 -173
  266. package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
  267. package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
  268. package/lib/vite/dashboard/index.html +28 -0
  269. package/lib/vite/htmlReport/index.html +2 -70
  270. package/lib/vite/htmlReport/report.css +1 -0
  271. package/lib/vite/htmlReport/report.js +72 -0
  272. package/lib/vite/recorder/assets/codeMirrorModule-C8KMvO9L.js +32 -0
  273. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  274. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  275. package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
  276. package/lib/vite/recorder/index.html +2 -2
  277. package/lib/vite/traceViewer/assets/codeMirrorModule-DS0FLvoc.js +32 -0
  278. package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
  279. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  280. package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
  281. package/lib/vite/traceViewer/index.CzXZzn5A.css +1 -0
  282. package/lib/vite/traceViewer/index.Dtstcb7U.js +2 -0
  283. package/lib/vite/traceViewer/index.html +4 -4
  284. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  285. package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
  286. package/lib/vite/traceViewer/uiMode.html +3 -3
  287. package/lib/zipBundleImpl.js +2 -2
  288. package/lib/zodBundle.js +39 -0
  289. package/lib/zodBundleImpl.js +40 -0
  290. package/package.json +7 -1
  291. package/types/protocol.d.ts +1696 -221
  292. package/types/types.d.ts +879 -112
  293. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  294. package/lib/server/chromium/videoRecorder.js +0 -115
  295. package/lib/server/pageBinding.js +0 -87
  296. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  297. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +0 -248
  298. package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
  299. package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
  300. package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
  301. package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
  302. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
  303. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
  304. package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
  305. package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
  306. /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
  307. /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
@@ -35,7 +35,6 @@ module.exports = __toCommonJS(ffBrowser_exports);
35
35
  var import_utils = require("../../utils");
36
36
  var import_browser = require("../browser");
37
37
  var import_browserContext = require("../browserContext");
38
- var import_errors = require("../errors");
39
38
  var network = __toESM(require("../network"));
40
39
  var import_ffConnection = require("./ffConnection");
41
40
  var import_ffPage = require("./ffPage");
@@ -54,7 +53,6 @@ class FFBrowser extends import_browser.Browser {
54
53
  this.session.on("Browser.detachedFromTarget", this._onDetachedFromTarget.bind(this));
55
54
  this.session.on("Browser.downloadCreated", this._onDownloadCreated.bind(this));
56
55
  this.session.on("Browser.downloadFinished", this._onDownloadFinished.bind(this));
57
- this.session.on("Browser.videoRecordingFinished", this._onVideoRecordingFinished.bind(this));
58
56
  }
59
57
  static async connect(parent, transport, options) {
60
58
  const connection = new import_ffConnection.FFConnection(transport, options.protocolLogger, options.browserLogsCollector);
@@ -129,7 +127,7 @@ class FFBrowser extends import_browser.Browser {
129
127
  ffPage._page.frameManager.frameAbortedNavigation(payload.frameId, "Download is starting");
130
128
  let originPage = ffPage._page.initializedOrUndefined();
131
129
  if (!originPage) {
132
- ffPage._markAsError(new Error("Starting new page download"));
130
+ ffPage._reportAsNew(new Error("Starting new page download"));
133
131
  if (ffPage._opener)
134
132
  originPage = ffPage._opener._page.initializedOrUndefined();
135
133
  }
@@ -141,13 +139,7 @@ class FFBrowser extends import_browser.Browser {
141
139
  const error = payload.canceled ? "canceled" : payload.error;
142
140
  this._downloadFinished(payload.uuid, error);
143
141
  }
144
- _onVideoRecordingFinished(payload) {
145
- this._takeVideo(payload.screencastId)?.reportFinished();
146
- }
147
142
  _onDisconnect() {
148
- for (const video of this._idToVideo.values())
149
- video.artifact.reportFinished(new import_errors.TargetClosedError());
150
- this._idToVideo.clear();
151
143
  for (const ffPage of this._ffPages.values())
152
144
  ffPage.didClose();
153
145
  this._ffPages.clear();
@@ -177,8 +169,11 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
177
169
  promises.push(this.doUpdateDefaultViewport());
178
170
  if (this._options.hasTouch)
179
171
  promises.push(this._browser.session.send("Browser.setTouchOverride", { browserContextId, hasTouch: true }));
180
- if (this._options.userAgent)
172
+ if (this._options.userAgent) {
181
173
  promises.push(this._browser.session.send("Browser.setUserAgentOverride", { browserContextId, userAgent: this._options.userAgent }));
174
+ const { navigatorPlatform } = (0, import_browserContext.calculateUserAgentEmulation)(this._options);
175
+ promises.push(this._browser.session.send("Browser.setPlatformOverride", { browserContextId, platform: navigatorPlatform || null }));
176
+ }
182
177
  if (this._options.bypassCSP)
183
178
  promises.push(this._browser.session.send("Browser.setBypassCSP", { browserContextId, bypassCSP: true }));
184
179
  if (this._options.ignoreHTTPSErrors || this._options.internalIgnoreHTTPSErrors)
@@ -198,18 +193,6 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
198
193
  if (this._options.offline)
199
194
  promises.push(this.doUpdateOffline());
200
195
  promises.push(this.doUpdateDefaultEmulatedMedia());
201
- if (this._options.recordVideo) {
202
- promises.push(this._ensureVideosPath().then(() => {
203
- return this._browser.session.send("Browser.setVideoRecordingOptions", {
204
- // validateBrowserContextOptions ensures correct video size.
205
- options: {
206
- ...this._options.recordVideo.size,
207
- dir: this._options.recordVideo.dir
208
- },
209
- browserContextId: this._browserContextId
210
- });
211
- }));
212
- }
213
196
  const proxy = this._options.proxyOverride || this._options.proxy;
214
197
  if (proxy) {
215
198
  promises.push(this._browser.session.send("Browser.setContextProxy", {
@@ -276,7 +259,8 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
276
259
  ["geolocation", "geo"],
277
260
  ["persistent-storage", "persistent-storage"],
278
261
  ["push", "push"],
279
- ["notifications", "desktop-notification"]
262
+ ["notifications", "desktop-notification"],
263
+ ["screen-wake-lock", "screen-wake-lock"]
280
264
  ]);
281
265
  const filtered = permissions.map((permission) => {
282
266
  const protocolPermission = webPermissionToProtocol.get(permission);
@@ -302,6 +286,8 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
302
286
  }
303
287
  async setUserAgent(userAgent) {
304
288
  await this._browser.session.send("Browser.setUserAgentOverride", { browserContextId: this._browserContextId, userAgent: userAgent || null });
289
+ const { navigatorPlatform } = (0, import_browserContext.calculateUserAgentEmulation)({ userAgent });
290
+ await this._browser.session.send("Browser.setPlatformOverride", { browserContextId: this._browserContextId, platform: navigatorPlatform || null });
305
291
  }
306
292
  async doUpdateOffline() {
307
293
  await this._browser.session.send("Browser.setOnlineOverride", { browserContextId: this._browserContextId, override: this._options.offline ? "offline" : "online" });
@@ -379,12 +365,6 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
379
365
  }
380
366
  async doClose(reason) {
381
367
  if (!this._browserContextId) {
382
- if (this._options.recordVideo) {
383
- await this._browser.session.send("Browser.setVideoRecordingOptions", {
384
- options: void 0,
385
- browserContextId: this._browserContextId
386
- });
387
- }
388
368
  await this._browser.close({ reason });
389
369
  } else {
390
370
  await this._browser.session.send("Browser.removeBrowserContext", { browserContextId: this._browserContextId });
@@ -90,11 +90,6 @@ class FFSession extends import_events.EventEmitter {
90
90
  this._connection = connection;
91
91
  this._sessionId = sessionId;
92
92
  this._rawSend = rawSend;
93
- this.on = super.on;
94
- this.addListener = super.addListener;
95
- this.off = super.removeListener;
96
- this.removeListener = super.removeListener;
97
- this.once = super.once;
98
93
  }
99
94
  markAsCrashed() {
100
95
  this._crashed = true;
@@ -23,6 +23,20 @@ __export(ffInput_exports, {
23
23
  RawTouchscreenImpl: () => RawTouchscreenImpl
24
24
  });
25
25
  module.exports = __toCommonJS(ffInput_exports);
26
+ const kFirefoxKeyOverrides = /* @__PURE__ */ new Map([
27
+ ["AudioVolumeMute", { code: "VolumeMute", keyCodeWithoutLocation: 181 }],
28
+ ["AudioVolumeDown", { code: "VolumeDown", keyCodeWithoutLocation: 182 }],
29
+ ["AudioVolumeUp", { code: "VolumeUp", keyCodeWithoutLocation: 183 }]
30
+ ]);
31
+ function toFirefoxKeyDescription(description) {
32
+ const override = kFirefoxKeyOverrides.get(description.key);
33
+ if (!override)
34
+ return description;
35
+ return {
36
+ ...description,
37
+ ...override
38
+ };
39
+ }
26
40
  function toModifiersMask(modifiers) {
27
41
  let mask = 0;
28
42
  if (modifiers.has("Alt"))
@@ -59,13 +73,14 @@ class RawKeyboardImpl {
59
73
  this._client = client;
60
74
  }
61
75
  async keydown(progress, modifiers, keyName, description, autoRepeat) {
62
- let text = description.text;
76
+ const keyDescription = toFirefoxKeyDescription(description);
77
+ let text = keyDescription.text;
63
78
  if (text === "\r")
64
79
  text = "";
65
- const { code, key, location } = description;
80
+ const { code, key, location } = keyDescription;
66
81
  await progress.race(this._client.send("Page.dispatchKeyEvent", {
67
82
  type: "keydown",
68
- keyCode: description.keyCodeWithoutLocation,
83
+ keyCode: keyDescription.keyCodeWithoutLocation,
69
84
  code,
70
85
  key,
71
86
  repeat: autoRepeat,
@@ -74,11 +89,12 @@ class RawKeyboardImpl {
74
89
  }));
75
90
  }
76
91
  async keyup(progress, modifiers, keyName, description) {
77
- const { code, key, location } = description;
92
+ const keyDescription = toFirefoxKeyDescription(description);
93
+ const { code, key, location } = keyDescription;
78
94
  await progress.race(this._client.send("Page.dispatchKeyEvent", {
79
95
  type: "keyup",
80
96
  key,
81
- keyCode: description.keyCodeWithoutLocation,
97
+ keyCode: keyDescription.keyCodeWithoutLocation,
82
98
  code,
83
99
  location,
84
100
  repeat: false
@@ -133,8 +133,7 @@ class FFNetworkManager {
133
133
  this._requests.delete(request._id);
134
134
  response._requestFinished(responseEndTime);
135
135
  }
136
- if (event.protocolVersion)
137
- response._setHttpVersion(event.protocolVersion);
136
+ response._setHttpVersion(event.protocolVersion ?? null);
138
137
  this._page.frameManager.reportRequestFinished(request.request, response);
139
138
  }
140
139
  _onRequestFailed(event) {
@@ -147,6 +146,7 @@ class FFNetworkManager {
147
146
  response.setTransferSize(null);
148
147
  response.setEncodedBodySize(null);
149
148
  response._requestFinished(-1);
149
+ response._setHttpVersion(null);
150
150
  }
151
151
  request.request._setFailureText(event.errorCode);
152
152
  this._page.frameManager.requestFailed(request.request, event.errorCode === "NS_BINDING_ABORTED");
@@ -170,9 +170,9 @@ const causeToResourceType = {
170
170
  TYPE_FONT: "font",
171
171
  TYPE_MEDIA: "media",
172
172
  TYPE_WEBSOCKET: "websocket",
173
- TYPE_CSP_REPORT: "other",
173
+ TYPE_CSP_REPORT: "cspreport",
174
174
  TYPE_XSLT: "other",
175
- TYPE_BEACON: "other",
175
+ TYPE_BEACON: "beacon",
176
176
  TYPE_FETCH: "fetch",
177
177
  TYPE_IMAGESET: "image",
178
178
  TYPE_WEB_MANIFEST: "manifest"
@@ -41,9 +41,9 @@ var import_ffConnection = require("./ffConnection");
41
41
  var import_ffExecutionContext = require("./ffExecutionContext");
42
42
  var import_ffInput = require("./ffInput");
43
43
  var import_ffNetworkManager = require("./ffNetworkManager");
44
- var import_debugLogger = require("../utils/debugLogger");
45
44
  var import_stackTrace = require("../../utils/isomorphic/stackTrace");
46
45
  var import_errors = require("../errors");
46
+ var import_videoRecorder = require("../videoRecorder");
47
47
  const UTILITY_WORLD_NAME = "__playwright_utility_world__";
48
48
  class FFPage {
49
49
  constructor(session, browserContext, opener) {
@@ -83,22 +83,20 @@ class FFPage {
83
83
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.workerDestroyed", this._onWorkerDestroyed.bind(this)),
84
84
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.dispatchMessageFromWorker", this._onDispatchMessageFromWorker.bind(this)),
85
85
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.crashed", this._onCrashed.bind(this)),
86
- import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.videoRecordingStarted", this._onVideoRecordingStarted.bind(this)),
87
86
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketCreated", this._onWebSocketCreated.bind(this)),
88
87
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketClosed", this._onWebSocketClosed.bind(this)),
89
88
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameReceived", this._onWebSocketFrameReceived.bind(this)),
90
89
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameSent", this._onWebSocketFrameSent.bind(this)),
91
90
  import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.screencastFrame", this._onScreencastFrame.bind(this))
92
91
  ];
93
- this._session.once("Page.ready", () => {
94
- if (this._reportedAsNew)
95
- return;
96
- this._reportedAsNew = true;
97
- this._page.reportAsNew(this._opener?._page);
98
- });
99
- this.addInitScript(new import_page.InitScript(""), UTILITY_WORLD_NAME).catch((e) => this._markAsError(e));
100
- }
101
- async _markAsError(error) {
92
+ const promises = [];
93
+ if (!this._page.isStorageStatePage)
94
+ (0, import_videoRecorder.startAutomaticVideoRecording)(this._page);
95
+ promises.push(new Promise((f) => this._session.once("Page.ready", f)));
96
+ Promise.all(promises).then(() => this._reportAsNew(), (error) => this._reportAsNew(error));
97
+ this.addInitScript(new import_page.InitScript(this._page, ""), UTILITY_WORLD_NAME).catch((e) => this._reportAsNew(e));
98
+ }
99
+ _reportAsNew(error) {
102
100
  if (this._reportedAsNew)
103
101
  return;
104
102
  this._reportedAsNew = true;
@@ -200,7 +198,8 @@ class FFPage {
200
198
  const context = this._contextIdToContext.get(executionContextId);
201
199
  if (!context)
202
200
  return;
203
- this._page.addConsoleMessage(null, type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
201
+ const timestamp = Date.now();
202
+ this._page.addConsoleMessage(null, type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location, void 0, timestamp);
204
203
  }
205
204
  _onDialogOpened(params) {
206
205
  this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
@@ -250,7 +249,7 @@ class FFPage {
250
249
  workerSession.on("Runtime.console", (event2) => {
251
250
  const { type, args, location } = event2;
252
251
  const context = worker.existingExecutionContext;
253
- this._page.addConsoleMessage(worker, type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
252
+ this._page.addConsoleMessage(worker, type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location, void 0, Date.now());
254
253
  });
255
254
  }
256
255
  _onWorkerDestroyed(event) {
@@ -272,11 +271,8 @@ class FFPage {
272
271
  this._session.markAsCrashed();
273
272
  this._page._didCrash();
274
273
  }
275
- _onVideoRecordingStarted(event) {
276
- this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this._page.waitForInitializedOrError());
277
- }
278
274
  didClose() {
279
- this._markAsError(new import_errors.TargetClosedError());
275
+ this._reportAsNew(new import_errors.TargetClosedError(this._page.closeReason()));
280
276
  this._session.dispose();
281
277
  import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
282
278
  this._networkManager.dispose();
@@ -417,26 +413,22 @@ class FFPage {
417
413
  throw e;
418
414
  });
419
415
  }
420
- async setScreencastOptions(options) {
421
- if (options) {
422
- const { screencastId } = await this._session.send("Page.startScreencast", options);
423
- this._screencastId = screencastId;
424
- } else {
425
- await this._session.send("Page.stopScreencast");
426
- }
416
+ startScreencast(options) {
417
+ this._session.sendMayFail("Page.startScreencast", { width: options.width, height: options.height, quality: options.quality });
418
+ }
419
+ stopScreencast() {
420
+ this._session.sendMayFail("Page.stopScreencast");
427
421
  }
428
422
  _onScreencastFrame(event) {
429
- if (!this._screencastId)
430
- return;
431
- const screencastId = this._screencastId;
432
- this._page.throttleScreencastFrameAck(() => {
433
- this._session.send("Page.screencastFrameAck", { screencastId }).catch((e) => import_debugLogger.debugLogger.log("error", e));
434
- });
435
423
  const buffer = Buffer.from(event.data, "base64");
436
- this._page.emit(import_page2.Page.Events.ScreencastFrame, {
424
+ this._page.screencast.onScreencastFrame({
437
425
  buffer,
438
- width: event.deviceWidth,
439
- height: event.deviceHeight
426
+ frameSwapWallTime: event.timestamp * 1e3,
427
+ // timestamp is in seconds, we need to convert to milliseconds.
428
+ viewportWidth: event.deviceWidth,
429
+ viewportHeight: event.deviceHeight
430
+ }, () => {
431
+ this._session.sendMayFail("Page.screencastFrameAck");
440
432
  });
441
433
  }
442
434
  rafCountForStablePosition() {
@@ -489,6 +481,8 @@ class FFPage {
489
481
  shouldToggleStyleSheetToSyncAnimations() {
490
482
  return false;
491
483
  }
484
+ async setDockTile(image) {
485
+ }
492
486
  }
493
487
  function webSocketId(frameId, wsid) {
494
488
  return `${frameId}---${wsid}`;
@@ -56,15 +56,13 @@ class Firefox extends import_browserType.BrowserType {
56
56
  connectToTransport(transport, options) {
57
57
  return import_ffBrowser.FFBrowser.connect(this.attribution.playwright, transport, options);
58
58
  }
59
- doRewriteStartupLog(error) {
60
- if (!error.logs)
61
- return error;
62
- if (error.logs.includes(`as root in a regular user's session is not supported.`))
63
- error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
59
+ doRewriteStartupLog(logs) {
60
+ if (logs.includes(`as root in a regular user's session is not supported.`))
61
+ logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
64
62
  Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? " in your GitHub Actions workflow file" : ""} when running Playwright.`, 1);
65
- if (error.logs.includes("no DISPLAY environment variable specified"))
66
- error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
67
- return error;
63
+ if (logs.includes("no DISPLAY environment variable specified"))
64
+ logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
65
+ return logs;
68
66
  }
69
67
  amendEnvironment(env) {
70
68
  if (!import_path.default.isAbsolute(import_os.default.homedir()))
@@ -21,7 +21,6 @@ __export(frameSelectors_exports, {
21
21
  FrameSelectors: () => FrameSelectors
22
22
  });
23
23
  module.exports = __toCommonJS(frameSelectors_exports);
24
- var import_dom = require("./dom");
25
24
  var import_utils = require("../utils");
26
25
  var import_selectorParser = require("../utils/isomorphic/selectorParser");
27
26
  class FrameSelectors {
@@ -46,12 +45,14 @@ class FrameSelectors {
46
45
  }
47
46
  return adoptIfNeeded(elementHandle, await resolved.frame._mainContext());
48
47
  }
49
- async queryArrayInMainWorld(selector, scope, isolatedContext) {
50
- const resolved = await this.resolveInjectedForSelector(selector, { mainWorld: !isolatedContext }, scope);
48
+ async queryArrayInMainWorld(selector, scope) {
49
+ const resolved = await this.resolveInjectedForSelector(selector, { mainWorld: true }, scope);
51
50
  if (!resolved)
52
51
  throw new Error(`Failed to find frame for selector "${selector}"`);
53
52
  return await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
54
- return injected.querySelectorAll(info.parsed, scope2 || document);
53
+ const elements = injected.querySelectorAll(info.parsed, scope2 || document);
54
+ injected.checkDeprecatedSelectorUsage(info.parsed, elements);
55
+ return elements;
55
56
  }, { info: resolved.info, scope: resolved.scope });
56
57
  }
57
58
  async queryCount(selector, options) {
@@ -60,7 +61,9 @@ class FrameSelectors {
60
61
  throw new Error(`Failed to find frame for selector "${selector}"`);
61
62
  await options.__testHookBeforeQuery?.();
62
63
  return await resolved.injected.evaluate((injected, { info }) => {
63
- return injected.querySelectorAll(info.parsed, document).length;
64
+ const elements = injected.querySelectorAll(info.parsed, document);
65
+ injected.checkDeprecatedSelectorUsage(info.parsed, elements);
66
+ return elements.length;
64
67
  }, { info: resolved.info });
65
68
  }
66
69
  async queryAll(selector, scope) {
@@ -68,7 +71,9 @@ class FrameSelectors {
68
71
  if (!resolved)
69
72
  return [];
70
73
  const arrayHandle = await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
71
- return injected.querySelectorAll(info.parsed, scope2 || document);
74
+ const elements = injected.querySelectorAll(info.parsed, scope2 || document);
75
+ injected.checkDeprecatedSelectorUsage(info.parsed, elements);
76
+ return elements;
72
77
  }, { info: resolved.info, scope: resolved.scope });
73
78
  const properties = await arrayHandle.getProperties();
74
79
  arrayHandle.dispose();
@@ -118,29 +123,9 @@ class FrameSelectors {
118
123
  throw injected.createStacklessError(`Selector "${selectorString}" resolved to ${injected.previewNode(element2)}, <iframe> was expected`);
119
124
  return element2;
120
125
  }, { info, scope: i === 0 ? scope : void 0, selectorString: (0, import_selectorParser.stringifySelector)(info.parsed) });
121
- let element = handle.asElement();
122
- if (!element) {
123
- try {
124
- var client = frame._page.delegate._sessionForFrame(frame)._client;
125
- } catch (e) {
126
- var client = frame._page.delegate._mainFrameSession._client;
127
- }
128
- var mainContext = await frame._context("main");
129
- const documentNode = await client.send("Runtime.evaluate", {
130
- expression: "document",
131
- serializationOptions: {
132
- serialization: "idOnly"
133
- },
134
- contextId: mainContext.delegate._contextId
135
- });
136
- const documentScope = new import_dom.ElementHandle(mainContext, documentNode.result.objectId);
137
- var check = await this._customFindFramesByParsed(injectedScript, client, mainContext, documentScope, info.parsed);
138
- if (check.length > 0) {
139
- element = check[0];
140
- } else {
141
- return null;
142
- }
143
- }
126
+ const element = handle.asElement();
127
+ if (!element)
128
+ return null;
144
129
  const maybeFrame = await frame._page.delegate.getContentFrame(element);
145
130
  element.dispose();
146
131
  if (!maybeFrame)
@@ -161,146 +146,6 @@ class FrameSelectors {
161
146
  const injected = await context.injectedScript();
162
147
  return { injected, info: resolved.info, frame: resolved.frame, scope: resolved.scope };
163
148
  }
164
- async _customFindFramesByParsed(injected, client, context, documentScope, parsed) {
165
- var parsedEdits = { ...parsed };
166
- var currentScopingElements = [documentScope];
167
- while (parsed.parts.length > 0) {
168
- var part = parsed.parts.shift();
169
- parsedEdits.parts = [part];
170
- var elements = [];
171
- var elementsIndexes = [];
172
- if (part.name == "nth") {
173
- const partNth = Number(part.body);
174
- if (partNth > currentScopingElements.length || partNth < -currentScopingElements.length) {
175
- return continuePolling;
176
- } else {
177
- currentScopingElements = [currentScopingElements.at(partNth)];
178
- continue;
179
- }
180
- } else if (part.name == "internal:or") {
181
- var orredElements = await this._customFindFramesByParsed(injected, client, context, documentScope, part.body.parsed);
182
- elements = currentScopingElements.concat(orredElements);
183
- } else if (part.name == "internal:and") {
184
- var andedElements = await this._customFindFramesByParsed(injected, client, context, documentScope, part.body.parsed);
185
- const backendNodeIds = new Set(andedElements.map((item) => item.backendNodeId));
186
- elements = currentScopingElements.filter((item) => backendNodeIds.has(item.backendNodeId));
187
- } else {
188
- for (const scope of currentScopingElements) {
189
- const describedScope = await client.send("DOM.describeNode", {
190
- objectId: scope._objectId,
191
- depth: -1,
192
- pierce: true
193
- });
194
- var queryingElements = [];
195
- let findClosedShadowRoots2 = function(node, results = []) {
196
- if (!node || typeof node !== "object") return results;
197
- if (node.shadowRoots && Array.isArray(node.shadowRoots)) {
198
- for (const shadowRoot2 of node.shadowRoots) {
199
- if (shadowRoot2.shadowRootType === "closed" && shadowRoot2.backendNodeId) {
200
- results.push(shadowRoot2.backendNodeId);
201
- }
202
- findClosedShadowRoots2(shadowRoot2, results);
203
- }
204
- }
205
- if (node.nodeName !== "IFRAME" && node.children && Array.isArray(node.children)) {
206
- for (const child of node.children) {
207
- findClosedShadowRoots2(child, results);
208
- }
209
- }
210
- return results;
211
- };
212
- var findClosedShadowRoots = findClosedShadowRoots2;
213
- var shadowRootBackendIds = findClosedShadowRoots2(describedScope.node);
214
- var shadowRoots = [];
215
- for (var shadowRootBackendId of shadowRootBackendIds) {
216
- var resolvedShadowRoot = await client.send("DOM.resolveNode", {
217
- backendNodeId: shadowRootBackendId,
218
- contextId: context.delegate._contextId
219
- });
220
- shadowRoots.push(new import_dom.ElementHandle(context, resolvedShadowRoot.object.objectId));
221
- }
222
- for (var shadowRoot of shadowRoots) {
223
- const shadowElements = await shadowRoot.evaluateHandleInUtility(([injected2, node, { parsed: parsed2 }]) => {
224
- const elements2 = injected2.querySelectorAll(parsed2, node);
225
- return elements2;
226
- }, {
227
- parsed: parsedEdits
228
- });
229
- const shadowElementsAmount = await shadowElements.getProperty("length");
230
- queryingElements.push([shadowElements, shadowElementsAmount, shadowRoot]);
231
- }
232
- const rootElements = await scope.evaluateHandleInUtility(([injected2, node, { parsed: parsed2 }]) => {
233
- const elements2 = injected2.querySelectorAll(parsed2, node);
234
- return elements2;
235
- }, {
236
- parsed: parsedEdits
237
- });
238
- const rootElementsAmount = await rootElements.getProperty("length");
239
- queryingElements.push([rootElements, rootElementsAmount, injected]);
240
- for (var queryedElement of queryingElements) {
241
- var elementsToCheck = queryedElement[0];
242
- var elementsAmount = await queryedElement[1].jsonValue();
243
- var parentNode = queryedElement[2];
244
- for (var i = 0; i < elementsAmount; i++) {
245
- if (parentNode.constructor.name == "ElementHandle") {
246
- var elementToCheck = await parentNode.evaluateHandleInUtility(([injected2, node, { index, elementsToCheck: elementsToCheck2 }]) => {
247
- return elementsToCheck2[index];
248
- }, { index: i, elementsToCheck });
249
- } else {
250
- var elementToCheck = await parentNode.evaluateHandle((injected2, { index, elementsToCheck: elementsToCheck2 }) => {
251
- return elementsToCheck2[index];
252
- }, { index: i, elementsToCheck });
253
- }
254
- elementToCheck.parentNode = parentNode;
255
- var resolvedElement = await client.send("DOM.describeNode", {
256
- objectId: elementToCheck._objectId,
257
- depth: -1
258
- });
259
- elementToCheck.backendNodeId = resolvedElement.node.backendNodeId;
260
- elementToCheck.nodePosition = this._findElementPositionInDomTree(elementToCheck, describedScope.node, context, "");
261
- elements.push(elementToCheck);
262
- }
263
- }
264
- }
265
- }
266
- const getParts = (pos) => (pos?.match(/../g) || []).map(Number);
267
- elements.sort((a, b) => {
268
- const partA = getParts(a.nodePosition);
269
- const partB = getParts(b.nodePosition);
270
- const maxLength = Math.max(partA.length, partB.length);
271
- for (let i2 = 0; i2 < maxLength; i2++) {
272
- const aVal = partA[i2] ?? -1;
273
- const bVal = partB[i2] ?? -1;
274
- if (aVal !== bVal) return aVal - bVal;
275
- }
276
- return 0;
277
- });
278
- currentScopingElements = Array.from(
279
- new Map(elements.map((e) => [e.nodePosition, e])).values()
280
- );
281
- }
282
- return currentScopingElements;
283
- }
284
- _findElementPositionInDomTree(element, queryingElement, documentScope, currentIndex) {
285
- if (element.backendNodeId === queryingElement.backendNodeId) {
286
- return currentIndex;
287
- }
288
- for (const child of queryingElement.children || []) {
289
- const childrenNodeIndex = queryingElement.children.indexOf(child);
290
- const childIndex = this._findElementPositionInDomTree(element, child, documentScope, currentIndex + childrenNodeIndex.toString());
291
- if (childIndex !== null) return childIndex;
292
- }
293
- if (queryingElement.shadowRoots && Array.isArray(queryingElement.shadowRoots)) {
294
- for (const shadowRoot of queryingElement.shadowRoots) {
295
- if (shadowRoot.shadowRootType === "closed" && shadowRoot.backendNodeId) {
296
- const shadowRootHandle = new import_dom.ElementHandle(documentScope, shadowRoot.backendNodeId);
297
- const childIndex = this._findElementPositionInDomTree(element, shadowRootHandle, documentScope, currentIndex);
298
- if (childIndex !== null) return childIndex;
299
- }
300
- }
301
- }
302
- return null;
303
- }
304
149
  }
305
150
  async function adoptIfNeeded(handle, context) {
306
151
  if (handle._context === context)