patchright-core 1.52.4 → 1.55.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 (218) hide show
  1. package/ThirdPartyNotices.txt +65 -123
  2. package/bin/reinstall_chrome_beta_mac.sh +1 -1
  3. package/bin/reinstall_chrome_stable_mac.sh +1 -1
  4. package/bin/reinstall_msedge_beta_mac.sh +1 -1
  5. package/bin/reinstall_msedge_dev_mac.sh +1 -1
  6. package/bin/reinstall_msedge_stable_mac.sh +1 -1
  7. package/browsers.json +14 -14
  8. package/index.js +1 -1
  9. package/lib/androidServerImpl.js +4 -2
  10. package/lib/browserServerImpl.js +47 -12
  11. package/lib/cli/program.js +116 -50
  12. package/lib/cli/programWithTestStub.js +1 -1
  13. package/lib/client/android.js +30 -34
  14. package/lib/client/browser.js +54 -17
  15. package/lib/client/browserContext.js +67 -71
  16. package/lib/client/browserType.js +25 -34
  17. package/lib/client/channelOwner.js +20 -24
  18. package/lib/client/connection.js +6 -10
  19. package/lib/client/electron.js +8 -3
  20. package/lib/client/elementHandle.js +18 -21
  21. package/lib/client/fetch.js +5 -3
  22. package/lib/client/frame.js +57 -35
  23. package/lib/client/input.js +3 -1
  24. package/lib/client/jsHandle.js +4 -0
  25. package/lib/client/localUtils.js +0 -1
  26. package/lib/client/locator.js +32 -28
  27. package/lib/client/network.js +5 -12
  28. package/lib/client/page.js +32 -32
  29. package/lib/client/playwright.js +6 -16
  30. package/lib/client/selectors.js +18 -38
  31. package/lib/client/timeoutSettings.js +12 -8
  32. package/lib/client/tracing.js +24 -20
  33. package/lib/client/waiter.js +2 -2
  34. package/lib/client/webSocket.js +4 -22
  35. package/lib/generated/bindingsControllerSource.js +28 -0
  36. package/lib/generated/clockSource.js +1 -1
  37. package/lib/generated/injectedScriptSource.js +1 -1
  38. package/lib/generated/pollingRecorderSource.js +1 -1
  39. package/lib/generated/storageScriptSource.js +28 -0
  40. package/lib/generated/utilityScriptSource.js +1 -1
  41. package/lib/generated/webSocketMockSource.js +12 -50
  42. package/lib/inProcessFactory.js +9 -6
  43. package/lib/outofprocess.js +0 -2
  44. package/lib/protocol/validator.js +423 -346
  45. package/lib/protocol/validatorPrimitives.js +18 -4
  46. package/lib/remote/playwrightConnection.js +29 -166
  47. package/lib/remote/playwrightServer.js +233 -35
  48. package/lib/server/android/android.js +97 -83
  49. package/lib/server/android/backendAdb.js +0 -2
  50. package/lib/server/bidi/bidiBrowser.js +139 -73
  51. package/lib/server/bidi/bidiChromium.js +23 -22
  52. package/lib/server/bidi/bidiExecutionContext.js +2 -1
  53. package/lib/server/bidi/bidiFirefox.js +17 -14
  54. package/lib/server/bidi/bidiInput.js +22 -22
  55. package/lib/server/bidi/bidiNetworkManager.js +8 -11
  56. package/lib/server/bidi/bidiPage.js +42 -86
  57. package/lib/server/bidi/third_party/bidiProtocol.js +5 -133
  58. package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
  59. package/lib/server/{dispatchers/selectorsDispatcher.js → bidi/third_party/bidiProtocolPermissions.js} +20 -18
  60. package/lib/server/browser.js +30 -21
  61. package/lib/server/browserContext.js +203 -165
  62. package/lib/server/browserType.js +109 -107
  63. package/lib/server/chromium/chromium.js +84 -69
  64. package/lib/server/chromium/chromiumSwitches.js +13 -20
  65. package/lib/server/chromium/crBrowser.js +74 -40
  66. package/lib/server/chromium/crConnection.js +8 -9
  67. package/lib/server/chromium/crCoverage.js +11 -8
  68. package/lib/server/chromium/crDragDrop.js +25 -20
  69. package/lib/server/chromium/crExecutionContext.js +2 -1
  70. package/lib/server/chromium/crInput.js +32 -29
  71. package/lib/server/chromium/crNetworkManager.js +45 -33
  72. package/lib/server/chromium/crPage.js +98 -73
  73. package/lib/server/chromium/crServiceWorker.js +13 -18
  74. package/lib/server/chromium/videoRecorder.js +10 -18
  75. package/lib/server/clock.js +51 -39
  76. package/lib/server/codegen/csharp.js +10 -5
  77. package/lib/server/codegen/java.js +1 -1
  78. package/lib/server/codegen/javascript.js +1 -1
  79. package/lib/server/codegen/jsonl.js +2 -1
  80. package/lib/server/codegen/language.js +22 -1
  81. package/lib/server/codegen/languages.js +4 -4
  82. package/lib/server/codegen/python.js +1 -1
  83. package/lib/server/cookieStore.js +3 -1
  84. package/lib/server/debugController.js +105 -71
  85. package/lib/server/debugger.js +6 -23
  86. package/lib/server/deviceDescriptorsSource.json +237 -127
  87. package/lib/server/dialog.js +50 -6
  88. package/lib/server/dispatchers/androidDispatcher.js +77 -62
  89. package/lib/server/dispatchers/artifactDispatcher.js +18 -18
  90. package/lib/server/dispatchers/browserContextDispatcher.js +141 -91
  91. package/lib/server/dispatchers/browserDispatcher.js +55 -88
  92. package/lib/server/dispatchers/browserTypeDispatcher.js +18 -9
  93. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -4
  94. package/lib/server/dispatchers/debugControllerDispatcher.js +12 -21
  95. package/lib/server/dispatchers/dialogDispatcher.js +4 -4
  96. package/lib/server/dispatchers/dispatcher.js +78 -53
  97. package/lib/server/dispatchers/electronDispatcher.js +19 -20
  98. package/lib/server/dispatchers/elementHandlerDispatcher.js +83 -93
  99. package/lib/server/dispatchers/frameDispatcher.js +99 -102
  100. package/lib/server/dispatchers/jsHandleDispatcher.js +21 -16
  101. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -4
  102. package/lib/server/dispatchers/localUtilsDispatcher.js +53 -59
  103. package/lib/server/dispatchers/networkDispatchers.js +41 -35
  104. package/lib/server/dispatchers/pageDispatcher.js +156 -107
  105. package/lib/server/dispatchers/playwrightDispatcher.js +37 -25
  106. package/lib/server/dispatchers/streamDispatcher.js +15 -8
  107. package/lib/server/dispatchers/tracingDispatcher.js +22 -13
  108. package/lib/server/dispatchers/webSocketRouteDispatcher.js +46 -35
  109. package/lib/server/dispatchers/writableStreamDispatcher.js +16 -10
  110. package/lib/server/dom.js +198 -266
  111. package/lib/server/download.js +3 -3
  112. package/lib/server/electron/electron.js +96 -103
  113. package/lib/server/electron/loader.js +1 -1
  114. package/lib/server/fetch.js +22 -41
  115. package/lib/server/fileUploadUtils.js +1 -1
  116. package/lib/server/firefox/ffBrowser.js +79 -55
  117. package/lib/server/firefox/ffExecutionContext.js +2 -1
  118. package/lib/server/firefox/ffInput.js +23 -23
  119. package/lib/server/firefox/ffNetworkManager.js +8 -6
  120. package/lib/server/firefox/ffPage.js +39 -36
  121. package/lib/server/firefox/firefox.js +9 -10
  122. package/lib/server/frameSelectors.js +65 -22
  123. package/lib/server/frames.js +516 -544
  124. package/lib/server/har/harRecorder.js +1 -1
  125. package/lib/server/har/harTracer.js +4 -2
  126. package/lib/server/helper.js +3 -7
  127. package/lib/server/index.js +0 -3
  128. package/lib/server/input.js +47 -54
  129. package/lib/server/instrumentation.js +8 -14
  130. package/lib/server/javascript.js +9 -17
  131. package/lib/server/launchApp.js +48 -30
  132. package/lib/server/localUtils.js +45 -38
  133. package/lib/server/network.js +44 -10
  134. package/lib/server/page.js +233 -178
  135. package/lib/server/pageBinding.js +6 -7
  136. package/lib/server/playwright.js +4 -14
  137. package/lib/server/progress.js +57 -49
  138. package/lib/server/recorder/recorderApp.js +298 -95
  139. package/lib/server/recorder/recorderRunner.js +23 -24
  140. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  141. package/lib/server/recorder/recorderUtils.js +67 -10
  142. package/lib/server/recorder.js +284 -146
  143. package/lib/server/registry/index.js +83 -48
  144. package/lib/server/registry/nativeDeps.js +175 -0
  145. package/lib/server/registry/oopDownloadBrowserMain.js +1 -1
  146. package/lib/server/screenshotter.js +84 -83
  147. package/lib/server/selectors.js +12 -12
  148. package/lib/server/socksClientCertificatesInterceptor.js +198 -136
  149. package/lib/server/trace/recorder/snapshotter.js +12 -19
  150. package/lib/server/trace/recorder/tracing.js +36 -27
  151. package/lib/server/trace/viewer/traceViewer.js +11 -20
  152. package/lib/server/transport.js +20 -22
  153. package/lib/server/utils/comparators.js +2 -2
  154. package/lib/server/utils/debug.js +3 -8
  155. package/lib/server/utils/debugLogger.js +8 -0
  156. package/lib/server/utils/hostPlatform.js +3 -1
  157. package/lib/server/utils/network.js +35 -25
  158. package/lib/server/utils/nodePlatform.js +1 -1
  159. package/lib/server/utils/processLauncher.js +4 -1
  160. package/lib/server/utils/wsServer.js +11 -17
  161. package/lib/server/webkit/webkit.js +5 -2
  162. package/lib/server/webkit/wkBrowser.js +51 -28
  163. package/lib/server/webkit/wkExecutionContext.js +2 -1
  164. package/lib/server/webkit/wkInput.js +25 -25
  165. package/lib/server/webkit/wkInterceptableRequest.js +1 -1
  166. package/lib/server/webkit/wkPage.js +80 -59
  167. package/lib/server/webkit/wkProvisionalPage.js +1 -1
  168. package/lib/server/webkit/wkWorkers.js +7 -7
  169. package/lib/utils/isomorphic/ariaSnapshot.js +13 -7
  170. package/lib/utils/isomorphic/cssParser.js +1 -2
  171. package/lib/utils/isomorphic/locatorGenerators.js +18 -0
  172. package/lib/utils/isomorphic/manualPromise.js +1 -2
  173. package/lib/utils/isomorphic/mimeType.js +1 -2
  174. package/lib/utils/isomorphic/multimap.js +1 -2
  175. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
  176. package/lib/utils/isomorphic/protocolFormatter.js +78 -0
  177. package/lib/utils/isomorphic/protocolMetainfo.js +318 -0
  178. package/lib/utils/isomorphic/selectorParser.js +3 -4
  179. package/lib/utils/isomorphic/stringUtils.js +3 -24
  180. package/lib/utils/isomorphic/time.js +9 -4
  181. package/lib/utils/isomorphic/timeoutRunner.js +3 -4
  182. package/lib/utils/isomorphic/traceUtils.js +2 -3
  183. package/lib/utils/isomorphic/urlMatch.js +21 -7
  184. package/lib/utils/isomorphic/utilityScriptSerializers.js +208 -205
  185. package/lib/utils.js +8 -2
  186. package/lib/utilsBundleImpl/index.js +160 -150
  187. package/lib/vite/htmlReport/index.html +17 -17
  188. package/lib/vite/recorder/assets/{codeMirrorModule-CXVeovup.js → codeMirrorModule-DzQ0k89p.js} +1 -1
  189. package/lib/vite/recorder/assets/{index-eHBmevrY.css → index-CI4HQ-Zb.css} +1 -1
  190. package/lib/vite/recorder/assets/index-D7C7daHH.js +184 -0
  191. package/lib/vite/recorder/index.html +3 -3
  192. package/lib/vite/traceViewer/assets/{codeMirrorModule-_GLjJL-7.js → codeMirrorModule-Di48jgWx.js} +1 -1
  193. package/lib/vite/traceViewer/assets/defaultSettingsView-szBn8781.js +256 -0
  194. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +1 -0
  195. package/lib/vite/traceViewer/index.BFsek2M6.css +1 -0
  196. package/lib/vite/traceViewer/index.DQvXoPLL.js +2 -0
  197. package/lib/vite/traceViewer/index.html +6 -6
  198. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  199. package/lib/vite/traceViewer/uiMode.dBV3oN9h.js +5 -0
  200. package/lib/vite/traceViewer/uiMode.html +4 -4
  201. package/lib/zipBundleImpl.js +4 -4
  202. package/package.json +1 -1
  203. package/types/protocol.d.ts +712 -107
  204. package/types/types.d.ts +148 -37
  205. package/lib/generated/consoleApiSource.js +0 -28
  206. package/lib/protocol/debug.js +0 -211
  207. package/lib/server/recorder/contextRecorder.js +0 -286
  208. package/lib/server/recorder/recorderCollection.js +0 -116
  209. package/lib/server/recorder/recorderFrontend.js +0 -16
  210. package/lib/server/storageScript.js +0 -154
  211. package/lib/server/timeoutSettings.js +0 -89
  212. package/lib/utils/isomorphic/builtins.js +0 -86
  213. package/lib/vite/recorder/assets/index-BsWQsSGl.js +0 -184
  214. package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +0 -265
  215. package/lib/vite/traceViewer/defaultSettingsView.QdHITyLI.css +0 -1
  216. package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
  217. package/lib/vite/traceViewer/index.cFZzK9RN.js +0 -2
  218. package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +0 -5
@@ -35,7 +35,6 @@ __export(frames_exports, {
35
35
  module.exports = __toCommonJS(frames_exports);
36
36
  var import_crExecutionContext = require("./chromium/crExecutionContext");
37
37
  var import_dom = require("./dom");
38
- var import_crypto = __toESM(require("crypto"));
39
38
  var import_browserContext = require("./browserContext");
40
39
  var dom = __toESM(require("./dom"));
41
40
  var import_errors = require("./errors");
@@ -68,8 +67,6 @@ class FrameManager {
68
67
  this._consoleMessageTags = /* @__PURE__ */ new Map();
69
68
  this._signalBarriers = /* @__PURE__ */ new Set();
70
69
  this._webSockets = /* @__PURE__ */ new Map();
71
- this._openedDialogs = /* @__PURE__ */ new Set();
72
- this._closeAllOpeningDialogs = false;
73
70
  this._page = page;
74
71
  this._mainFrame = void 0;
75
72
  }
@@ -124,14 +121,15 @@ class FrameManager {
124
121
  return action();
125
122
  const barrier = new SignalBarrier(progress);
126
123
  this._signalBarriers.add(barrier);
127
- if (progress)
128
- progress.cleanupWhenAborted(() => this._signalBarriers.delete(barrier));
129
- const result = await action();
130
- await this._page._delegate.inputActionEpilogue();
131
- await barrier.waitFor();
132
- this._signalBarriers.delete(barrier);
133
- await new Promise((0, import_utils.makeWaitForNextTask)());
134
- return result;
124
+ try {
125
+ const result = await action();
126
+ await progress.race(this._page.delegate.inputActionEpilogue());
127
+ await barrier.waitFor();
128
+ await new Promise((0, import_utils.makeWaitForNextTask)());
129
+ return result;
130
+ } finally {
131
+ this._signalBarriers.delete(barrier);
132
+ }
135
133
  }
136
134
  frameWillPotentiallyRequestNavigation() {
137
135
  for (const barrier of this._signalBarriers)
@@ -236,17 +234,8 @@ class FrameManager {
236
234
  return;
237
235
  }
238
236
  this._page.emitOnContext(import_browserContext.BrowserContext.Events.Request, request);
239
- if (route) {
240
- const r = new network.Route(request, route);
241
- if (this._page._serverRequestInterceptor?.(r, request))
242
- return;
243
- if (this._page._clientRequestInterceptor?.(r, request))
244
- return;
245
- if (this._page._browserContext._requestInterceptor?.(r, request))
246
- return;
247
- r.continue({ isFallback: true }).catch(() => {
248
- });
249
- }
237
+ if (route)
238
+ new network.Route(request, route).handle([...this._page.requestInterceptors, ...this._page.browserContext.requestInterceptors]);
250
239
  }
251
240
  requestReceivedResponse(response) {
252
241
  if (response.request()._isFavicon)
@@ -272,26 +261,6 @@ class FrameManager {
272
261
  return;
273
262
  this._page.emitOnContext(import_browserContext.BrowserContext.Events.RequestFailed, request);
274
263
  }
275
- dialogDidOpen(dialog) {
276
- for (const frame of this._frames.values())
277
- frame._invalidateNonStallingEvaluations("JavaScript dialog interrupted evaluation");
278
- if (this._closeAllOpeningDialogs)
279
- dialog.close().then(() => {
280
- });
281
- else
282
- this._openedDialogs.add(dialog);
283
- }
284
- dialogWillClose(dialog) {
285
- this._openedDialogs.delete(dialog);
286
- }
287
- async closeOpenDialogs() {
288
- await Promise.all([...this._openedDialogs].map((dialog) => dialog.close())).catch(() => {
289
- });
290
- this._openedDialogs.clear();
291
- }
292
- setCloseAllOpeningDialogs(closeDialogs) {
293
- this._closeAllOpeningDialogs = closeDialogs;
294
- }
295
264
  removeChildFramesRecursively(frame) {
296
265
  for (const child of frame.childFrames())
297
266
  this._removeFramesRecursively(child);
@@ -459,7 +428,7 @@ class Frame extends import_instrumentation.SdkObject {
459
428
  async raceAgainstEvaluationStallingEvents(cb) {
460
429
  if (this._pendingDocument)
461
430
  throw new Error("Frame is currently attempting a navigation");
462
- if (this._page._frameManager._openedDialogs.size)
431
+ if (this._page.browserContext.dialogManager.hasOpenDialogsForPage(this._page))
463
432
  throw new Error("Open JavaScript dialog prevents evaluation");
464
433
  const promise = new import_manualPromise.ManualPromise();
465
434
  this._raceAgainstEvaluationStallingEventsPromises.add(promise);
@@ -506,7 +475,7 @@ class Frame extends import_instrumentation.SdkObject {
506
475
  this.emit(Frame.Events.RemoveLifecycle, "networkidle");
507
476
  }
508
477
  }
509
- async raceNavigationAction(progress, options, action) {
478
+ async raceNavigationAction(progress, action) {
510
479
  return import_utils.LongStandingScope.raceMultiple([
511
480
  this._detachedScope,
512
481
  this._page.openScope
@@ -515,30 +484,26 @@ class Frame extends import_instrumentation.SdkObject {
515
484
  const data = this._redirectedNavigations.get(e.documentId);
516
485
  if (data) {
517
486
  progress.log(`waiting for redirected navigation to "${data.url}"`);
518
- return data.gotoPromise;
487
+ return progress.race(data.gotoPromise);
519
488
  }
520
489
  }
521
490
  throw e;
522
491
  }));
523
492
  }
524
493
  redirectNavigation(url, documentId, referer) {
525
- const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), this);
494
+ const controller = new import_progress.ProgressController();
526
495
  const data = {
527
496
  url,
528
- gotoPromise: controller.run((progress) => this._gotoAction(progress, url, { referer }), 0)
497
+ gotoPromise: controller.run((progress) => this.gotoImpl(progress, url, { referer }), 0)
529
498
  };
530
499
  this._redirectedNavigations.set(documentId, data);
531
500
  data.gotoPromise.finally(() => this._redirectedNavigations.delete(documentId));
532
501
  }
533
- async goto(metadata, url, options = {}) {
534
- const constructedNavigationURL = (0, import_utils.constructURLBasedOnBaseURL)(this._page._browserContext._options.baseURL, url);
535
- const controller = new import_progress.ProgressController(metadata, this);
536
- return controller.run((progress) => this._goto(progress, constructedNavigationURL, options), this._page._timeoutSettings.navigationTimeout(options));
537
- }
538
- async _goto(progress, url, options) {
539
- return this.raceNavigationAction(progress, options, async () => this._gotoAction(progress, url, options));
502
+ async goto(progress, url, options = {}) {
503
+ const constructedNavigationURL = (0, import_utils.constructURLBasedOnBaseURL)(this._page.browserContext._options.baseURL, url);
504
+ return this.raceNavigationAction(progress, async () => this.gotoImpl(progress, constructedNavigationURL, options));
540
505
  }
541
- async _gotoAction(progress, url, options) {
506
+ async gotoImpl(progress, url, options) {
542
507
  const waitUntil = verifyLifecycle("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
543
508
  progress.log(`navigating to "${url}", waiting until "${waitUntil}"`);
544
509
  const headers = this._page.extraHTTPHeaders() || [];
@@ -553,7 +518,7 @@ class Frame extends import_instrumentation.SdkObject {
553
518
  const navigationEvents = [];
554
519
  const collectNavigations = (arg) => navigationEvents.push(arg);
555
520
  this.on(Frame.Events.InternalNavigation, collectNavigations);
556
- const navigateResult = await this._page._delegate.navigateFrame(this, url, referer).finally(
521
+ const navigateResult = await progress.race(this._page.delegate.navigateFrame(this, url, referer)).finally(
557
522
  () => this.off(Frame.Events.InternalNavigation, collectNavigations)
558
523
  );
559
524
  let event;
@@ -582,7 +547,7 @@ class Frame extends import_instrumentation.SdkObject {
582
547
  if (!this._firedLifecycleEvents.has(waitUntil))
583
548
  await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
584
549
  const request = event.newDocument ? event.newDocument.request : void 0;
585
- const response = request ? request._finalRequest().response() : null;
550
+ const response = request ? progress.race(request._finalRequest().response()) : null;
586
551
  return response;
587
552
  }
588
553
  async _waitForNavigation(progress, requiresNewDocument, options) {
@@ -601,7 +566,7 @@ class Frame extends import_instrumentation.SdkObject {
601
566
  if (!this._firedLifecycleEvents.has(waitUntil))
602
567
  await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
603
568
  const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : void 0;
604
- return request ? request._finalRequest().response() : null;
569
+ return request ? progress.race(request._finalRequest().response()) : null;
605
570
  }
606
571
  async _waitForLoadState(progress, state) {
607
572
  const waitUntil = verifyLifecycle("state", state);
@@ -609,13 +574,14 @@ class Frame extends import_instrumentation.SdkObject {
609
574
  await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
610
575
  }
611
576
  async frameElement() {
612
- return this._page._delegate.getFrameElement(this);
577
+ return this._page.delegate.getFrameElement(this);
613
578
  }
614
579
  async _context(world) {
580
+ if (this.isDetached()) throw new Error("Frame was detached");
615
581
  try {
616
- var client = this._page._delegate._sessionForFrame(this)._client;
582
+ var client = this._page.delegate._sessionForFrame(this)._client;
617
583
  } catch (e) {
618
- var client = this._page._delegate._mainFrameSession._client;
584
+ var client = this._page.delegate._mainFrameSession._client;
619
585
  }
620
586
  var iframeExecutionContextId = await this._getFrameMainFrameContextId(client);
621
587
  if (world == "main") {
@@ -623,7 +589,7 @@ class Frame extends import_instrumentation.SdkObject {
623
589
  var executionContextId = iframeExecutionContextId;
624
590
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
625
591
  this._iframeWorld = new import_dom.FrameExecutionContext(crContext, this, world);
626
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
592
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
627
593
  id: executionContextId,
628
594
  origin: world,
629
595
  name: world,
@@ -641,7 +607,7 @@ class Frame extends import_instrumentation.SdkObject {
641
607
  var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
642
608
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
643
609
  this._mainWorld = new import_dom.FrameExecutionContext(crContext, this, world);
644
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
610
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
645
611
  id: executionContextId,
646
612
  origin: world,
647
613
  name: world,
@@ -662,7 +628,7 @@ class Frame extends import_instrumentation.SdkObject {
662
628
  var executionContextId = result.executionContextId;
663
629
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
664
630
  this._isolatedWorld = new import_dom.FrameExecutionContext(crContext, this, world);
665
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
631
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
666
632
  id: executionContextId,
667
633
  origin: world,
668
634
  name: world,
@@ -692,16 +658,20 @@ class Frame extends import_instrumentation.SdkObject {
692
658
  return value;
693
659
  }
694
660
  async evaluateExpressionHandle(expression, options = {}, arg) {
695
- const context = await this._context(options.world ?? "main");
661
+ const context = await this._context(options.world ?? "utility");
696
662
  const value = await context.evaluateExpressionHandle(expression, options, arg);
697
663
  return value;
698
664
  }
699
665
  async querySelector(selector, options) {
700
- import_debugLogger.debugLogger.log("api", ` finding element using the selector "${selector}"`);
701
- return this.selectors.query(selector, options);
666
+ return this.querySelectorAll(selector, options).then((handles) => {
667
+ if (handles.length === 0)
668
+ return null;
669
+ if (handles.length > 1 && options?.strict)
670
+ throw new Error(`Strict mode: expected one element matching selector "${selector}", found ${handles.length}`);
671
+ return handles[0];
672
+ });
702
673
  }
703
- async waitForSelector(metadata, selector, options, scope) {
704
- const controller = new import_progress.ProgressController(metadata, this);
674
+ async waitForSelector(progress, selector, performActionPreChecksAndLog, options, scope) {
705
675
  if (options.visibility)
706
676
  throw new Error("options.visibility is not supported, did you mean options.state?");
707
677
  if (options.waitFor && options.waitFor !== "visible")
@@ -709,15 +679,8 @@ class Frame extends import_instrumentation.SdkObject {
709
679
  const { state = "visible" } = options;
710
680
  if (!["attached", "detached", "visible", "hidden"].includes(state))
711
681
  throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
712
- return controller.run(async (progress) => {
682
+ if (performActionPreChecksAndLog)
713
683
  progress.log(`waiting for ${this._asLocator(selector)}${state === "attached" ? "" : " to be " + state}`);
714
- return await this.waitForSelectorInternal(progress, selector, true, options, scope);
715
- }, this._page._timeoutSettings.timeout(options));
716
- }
717
- async waitForSelectorInternal(progress, selector, performActionPreChecks, options, scope) {
718
- const {
719
- state = "visible"
720
- } = options;
721
684
  const promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, async (handle) => {
722
685
  const attached = !!handle;
723
686
  var visible = false;
@@ -725,15 +688,11 @@ class Frame extends import_instrumentation.SdkObject {
725
688
  if (handle.parentNode.constructor.name == "ElementHandle") {
726
689
  visible = await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
727
690
  return handle2 ? injected.utils.isElementVisible(handle2) : false;
728
- }, {
729
- handle
730
- });
691
+ }, { handle });
731
692
  } else {
732
693
  visible = await handle.parentNode.evaluate((injected, { handle: handle2 }) => {
733
694
  return handle2 ? injected.utils.isElementVisible(handle2) : false;
734
- }, {
735
- handle
736
- });
695
+ }, { handle });
737
696
  }
738
697
  }
739
698
  const success = {
@@ -742,12 +701,8 @@ class Frame extends import_instrumentation.SdkObject {
742
701
  visible,
743
702
  hidden: !visible
744
703
  }[state];
745
- if (!success) {
746
- return "internal:continuepolling";
747
- }
748
- if (options.omitReturnValue) {
749
- return null;
750
- }
704
+ if (!success) return "internal:continuepolling";
705
+ if (options.omitReturnValue) return null;
751
706
  const element = state === "attached" || state === "visible" ? handle : null;
752
707
  if (!element) return null;
753
708
  if (options.__testHookBeforeAdoptNode) await options.__testHookBeforeAdoptNode();
@@ -759,24 +714,30 @@ class Frame extends import_instrumentation.SdkObject {
759
714
  }, "returnOnNotResolved");
760
715
  return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
761
716
  }
762
- async dispatchEvent(metadata, selector, type, eventInit = {}, options = {}, scope) {
763
- await this._callOnElementOnceMatches(metadata, selector, (injectedScript, element, data) => {
717
+ async dispatchEvent(progress, selector, type, eventInit = {}, options, scope) {
718
+ await this._callOnElementOnceMatches(progress, selector, (injectedScript, element, data) => {
764
719
  injectedScript.dispatchEvent(element, data.type, data.eventInit);
765
720
  }, { type, eventInit }, { mainWorld: true, ...options }, scope);
766
721
  }
767
722
  async evalOnSelector(selector, strict, expression, isFunction, arg, scope) {
768
723
  const handle = await this.selectors.query(selector, { strict }, scope);
769
724
  if (!handle)
770
- throw new Error(`Failed to find element matching selector "${selector}"`);
771
- const result = await handle.evaluateExpression(expression, { isFunction }, arg);
725
+ throw new Error("Failed to find element matching selector " + selector);
726
+ const result = await handle.evaluateExpression(expression, { isFunction }, arg, true);
772
727
  handle.dispose();
773
728
  return result;
774
729
  }
775
- async evalOnSelectorAll(selector, expression, isFunction, arg, scope) {
776
- const arrayHandle = await this.selectors.queryArrayInMainWorld(selector, scope);
777
- const result = await arrayHandle.evaluateExpression(expression, { isFunction }, arg);
778
- arrayHandle.dispose();
779
- return result;
730
+ async evalOnSelectorAll(selector, expression, isFunction, arg, scope, isolatedContext) {
731
+ try {
732
+ isolatedContext = this.selectors._parseSelector(selector, { strict: false }).world !== "main" && isolatedContext;
733
+ const arrayHandle = await this.selectors.queryArrayInMainWorld(selector, scope, isolatedContext);
734
+ const result = await arrayHandle.evaluateExpression(expression, { isFunction }, arg, isolatedContext);
735
+ arrayHandle.dispose();
736
+ return result;
737
+ } catch (e) {
738
+ if ("JSHandles can be evaluated only in the context they were created!" === e.message) return await this.evalOnSelectorAll(selector, expression, isFunction, arg, scope, isolatedContext);
739
+ throw e;
740
+ }
780
741
  }
781
742
  async maskSelectors(selectors, color) {
782
743
  const context = await this._utilityContext();
@@ -786,25 +747,30 @@ class Frame extends import_instrumentation.SdkObject {
786
747
  }, { parsed: selectors, color });
787
748
  }
788
749
  async querySelectorAll(selector) {
789
- return this.selectors.queryAll(selector);
790
- }
791
- async queryCount(selector) {
792
- const custom_metadata = {
793
- "internal": false,
794
- "log": []
750
+ const metadata = { internal: false, log: [], method: "querySelectorAll" };
751
+ const progress = {
752
+ log: (message) => metadata.log.push(message),
753
+ metadata,
754
+ race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
795
755
  };
796
- const controller = new import_progress.ProgressController(custom_metadata, this);
797
- const resultPromise = await controller.run(async (progress) => {
798
- progress.log("waiting for " + this._asLocator(selector));
799
- const promise = await this._retryWithProgressIfNotConnected(progress, selector, false, false, async (result) => {
800
- if (!result) return 0;
801
- const handle = result[0];
802
- const handles = result[1];
803
- return handle ? handles.length : 0;
804
- }, "returnAll");
805
- return promise;
806
- }, 1e4);
807
- return resultPromise ? resultPromise : 0;
756
+ return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
757
+ if (!result || !result[0]) return [];
758
+ return result[1];
759
+ }, "returnAll", null);
760
+ }
761
+ async queryCount(selector, options) {
762
+ const metadata = { internal: false, log: [], method: "queryCount" };
763
+ const progress = {
764
+ log: (message) => metadata.log.push(message),
765
+ metadata,
766
+ race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
767
+ };
768
+ return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
769
+ if (!result) return 0;
770
+ const handle = result[0];
771
+ const handles = result[1];
772
+ return handle ? handles.length : 0;
773
+ }, "returnAll", null);
808
774
  }
809
775
  async content() {
810
776
  try {
@@ -818,44 +784,26 @@ class Frame extends import_instrumentation.SdkObject {
818
784
  return retVal;
819
785
  });
820
786
  } catch (e) {
821
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_protocolError.isSessionClosedError)(e))
787
+ if (this.isNonRetriableError(e))
822
788
  throw e;
823
789
  throw new Error(`Unable to retrieve content because the page is navigating and changing the content.`);
824
790
  }
825
791
  }
826
- async setContent(metadata, html, options = {}) {
827
- const controller = new import_progress.ProgressController(metadata, this);
828
- return controller.run(async (progress) => {
829
- await this.raceNavigationAction(progress, options, async () => {
830
- const waitUntil = options.waitUntil === void 0 ? "load" : options.waitUntil;
831
- progress.log(`setting frame content, waiting until "${waitUntil}"`);
832
- const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
833
- const bindingName = "_tagDebug" + import_crypto.default.randomBytes(20).toString("hex");
834
- const context = await this._utilityContext();
835
- await this._page._delegate._mainFrameSession._client.send("Runtime.addBinding", { name: bindingName });
836
- const lifecyclePromise = new Promise(async (resolve, reject) => {
837
- await this._page.exposeBinding(bindingName, false, (tag2) => {
838
- this._onClearLifecycle();
839
- this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
840
- });
841
- });
842
- const contentPromise = context.evaluate(({ html: html2, tag: tag2, bindingName: bindingName2 }) => {
843
- document.open();
844
- var _tagDebug = window[bindingName2].bind({});
845
- delete window[bindingName2];
846
- _tagDebug('{ "name": "' + bindingName2 + '", "seq": 1, "serializedArgs": ["' + tag2 + '"] }');
847
- console.debug(tag2);
848
- document.write(html2);
849
- document.close();
850
- }, {
851
- html,
852
- tag,
853
- bindingName
854
- });
855
- await Promise.all([contentPromise, lifecyclePromise]);
856
- return null;
792
+ async setContent(progress, html, options) {
793
+ await this.raceNavigationAction(progress, async () => {
794
+ const waitUntil = options.waitUntil === void 0 ? "load" : options.waitUntil;
795
+ progress.log(`setting frame content, waiting until "${waitUntil}"`);
796
+ const lifecyclePromise = new Promise((resolve, reject) => {
797
+ this._onClearLifecycle();
798
+ this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
799
+ });
800
+ const setContentPromise = this._page.delegate._mainFrameSession._client.send("Page.setDocumentContent", {
801
+ frameId: this._id,
802
+ html
857
803
  });
858
- }, this._page._timeoutSettings.navigationTimeout(options));
804
+ await Promise.all([setContentPromise, lifecyclePromise]);
805
+ return null;
806
+ });
859
807
  }
860
808
  name() {
861
809
  return this._name || "";
@@ -887,7 +835,7 @@ class Frame extends import_instrumentation.SdkObject {
887
835
  if (url !== null)
888
836
  return (await context.evaluateHandle(addScriptUrl, { url, type })).asElement();
889
837
  const result = (await context.evaluateHandle(addScriptContent, { content, type })).asElement();
890
- if (this._page._delegate.cspErrorsAsynchronousForInlineScripts)
838
+ if (this._page.delegate.cspErrorsAsynchronousForInlineScripts)
891
839
  await context.evaluate(() => true);
892
840
  return result;
893
841
  });
@@ -961,7 +909,7 @@ class Frame extends import_instrumentation.SdkObject {
961
909
  let cspMessage;
962
910
  const actionPromise = func().then((r) => result = r).catch((e) => error = e);
963
911
  const errorPromise = new Promise((resolve) => {
964
- listeners.push(import_eventsHelper.eventsHelper.addEventListener(this._page._browserContext, import_browserContext.BrowserContext.Events.Console, (message) => {
912
+ listeners.push(import_eventsHelper.eventsHelper.addEventListener(this._page.browserContext, import_browserContext.BrowserContext.Events.Console, (message) => {
965
913
  if (message.page() !== this._page || message.type() !== "error")
966
914
  return;
967
915
  if (message.text().includes("Content-Security-Policy") || message.text().includes("Content Security Policy")) {
@@ -979,34 +927,33 @@ class Frame extends import_instrumentation.SdkObject {
979
927
  return result;
980
928
  }
981
929
  async retryWithProgressAndTimeouts(progress, timeouts, action) {
982
- const continuePolling3 = Symbol("continuePolling");
930
+ const continuePolling = Symbol("continuePolling");
983
931
  timeouts = [0, ...timeouts];
984
932
  let timeoutIndex = 0;
985
- while (progress.isRunning()) {
933
+ while (true) {
986
934
  const timeout = timeouts[Math.min(timeoutIndex++, timeouts.length - 1)];
987
935
  if (timeout) {
988
936
  const actionPromise = new Promise((f) => setTimeout(f, timeout));
989
- await import_utils.LongStandingScope.raceMultiple([
937
+ await progress.race(import_utils.LongStandingScope.raceMultiple([
990
938
  this._page.openScope,
991
939
  this._detachedScope
992
- ], actionPromise);
940
+ ], actionPromise));
993
941
  }
994
- progress.throwIfAborted();
995
942
  try {
996
- const result = await action(continuePolling3);
997
- if (result === continuePolling3)
943
+ const result = await action(continuePolling);
944
+ if (result === continuePolling)
998
945
  continue;
999
946
  return result;
1000
947
  } catch (e) {
1001
- if (this._isErrorThatCannotBeRetried(e))
948
+ if (this.isNonRetriableError(e))
1002
949
  throw e;
1003
950
  continue;
1004
951
  }
1005
952
  }
1006
- progress.throwIfAborted();
1007
- return void 0;
1008
953
  }
1009
- _isErrorThatCannotBeRetried(e) {
954
+ isNonRetriableError(e) {
955
+ if ((0, import_progress.isAbortError)(e))
956
+ return true;
1010
957
  if (js.isJavaScriptErrorInEvaluate(e) || (0, import_protocolError.isSessionClosedError)(e))
1011
958
  return true;
1012
959
  if (dom.isNonRecoverableDOMError(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
@@ -1017,178 +964,116 @@ class Frame extends import_instrumentation.SdkObject {
1017
964
  }
1018
965
  async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action, returnAction) {
1019
966
  progress.log("waiting for " + this._asLocator(selector));
1020
- return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling3) => {
1021
- if (performActionPreChecks) await this._page.performActionPreChecks(progress);
1022
- const resolved = await this.selectors.resolveInjectedForSelector(selector, {
1023
- strict
1024
- });
1025
- progress.throwIfAborted();
1026
- if (!resolved) {
1027
- if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1028
- const result2 = await action(null);
1029
- return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1030
- }
1031
- return continuePolling3;
1032
- }
1033
- try {
1034
- var client = this._page._delegate._sessionForFrame(resolved.frame)._client;
1035
- } catch (e) {
1036
- var client = this._page._delegate._mainFrameSession._client;
1037
- }
1038
- var context = await resolved.frame._context("main");
1039
- const documentNode = await client.send("Runtime.evaluate", {
1040
- expression: "document",
1041
- serializationOptions: {
1042
- serialization: "idOnly"
1043
- },
1044
- contextId: context.delegate._contextId
1045
- });
1046
- const documentScope = new dom.ElementHandle(context, documentNode.result.objectId);
1047
- const currentScopingElements = await this._customFindElementsByParsed(resolved, client, context, documentScope, progress, resolved.info.parsed);
1048
- if (currentScopingElements.length == 0) {
1049
- if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1050
- const result2 = await action(null);
1051
- return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1052
- }
1053
- return continuePolling3;
1054
- }
1055
- const resultElement = currentScopingElements[0];
1056
- if (currentScopingElements.length > 1) {
1057
- if (resolved.info.strict) {
1058
- await resolved.injected.evaluateHandle((injected, {
1059
- info,
1060
- elements
1061
- }) => {
1062
- throw injected.strictModeViolationError(info.parsed, elements);
1063
- }, {
1064
- info: resolved.info,
1065
- elements: currentScopingElements
1066
- });
1067
- }
1068
- progress.log(" locator resolved to " + currentScopingElements.length + " elements. Proceeding with the first one: " + resultElement.preview());
1069
- } else if (resultElement) {
1070
- progress.log(" locator resolved to " + resultElement.preview());
1071
- }
1072
- try {
1073
- var result = null;
1074
- if (returnAction === "returnAll") {
1075
- result = await action([resultElement, currentScopingElements]);
1076
- } else {
1077
- result = await action(resultElement);
1078
- }
1079
- if (result === "error:notconnected") {
1080
- progress.log("element was detached from the DOM, retrying");
1081
- return continuePolling3;
1082
- } else if (result === "internal:continuepolling") {
1083
- return continuePolling3;
1084
- }
1085
- return result;
1086
- } finally {
1087
- }
967
+ return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
968
+ return this._retryWithoutProgress(progress, selector, strict, performActionPreChecks, action, returnAction, continuePolling);
1088
969
  });
1089
970
  }
1090
971
  async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
1091
972
  return await this._retryWithProgressIfNotConnected(progress, selector, true, true, async (handle) => {
1092
- await handle._frame.rafrafTimeout(timeout);
1093
- return await this._page._screenshotter.screenshotElement(progress, handle, options);
973
+ await handle._frame.rafrafTimeout(progress, timeout);
974
+ return await this._page.screenshotter.screenshotElement(progress, handle, options);
1094
975
  });
1095
976
  }
1096
- async click(metadata, selector, options) {
1097
- const controller = new import_progress.ProgressController(metadata, this);
1098
- return controller.run(async (progress) => {
1099
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
1100
- }, this._page._timeoutSettings.timeout(options));
1101
- }
1102
- async dblclick(metadata, selector, options = {}) {
1103
- const controller = new import_progress.ProgressController(metadata, this);
1104
- return controller.run(async (progress) => {
1105
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._dblclick(progress, options)));
1106
- }, this._page._timeoutSettings.timeout(options));
1107
- }
1108
- async dragAndDrop(metadata, source, target, options = {}) {
1109
- const controller = new import_progress.ProgressController(metadata, this);
1110
- await controller.run(async (progress) => {
1111
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force, async (handle) => {
1112
- return handle._retryPointerAction(progress, "move and down", false, async (point) => {
1113
- await this._page.mouse.move(point.x, point.y);
1114
- await this._page.mouse.down();
1115
- }, {
1116
- ...options,
1117
- waitAfter: "disabled",
1118
- position: options.sourcePosition,
1119
- timeout: progress.timeUntilDeadline()
1120
- });
1121
- }));
1122
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
1123
- return handle._retryPointerAction(progress, "move and up", false, async (point) => {
1124
- await this._page.mouse.move(point.x, point.y);
1125
- await this._page.mouse.up();
1126
- }, {
1127
- ...options,
1128
- waitAfter: "disabled",
1129
- position: options.targetPosition,
1130
- timeout: progress.timeUntilDeadline()
1131
- });
1132
- }));
1133
- }, this._page._timeoutSettings.timeout(options));
977
+ async click(progress, selector, options) {
978
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
979
+ }
980
+ async dblclick(progress, selector, options) {
981
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._dblclick(progress, options)));
982
+ }
983
+ async dragAndDrop(progress, source, target, options) {
984
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force, async (handle) => {
985
+ return handle._retryPointerAction(progress, "move and down", false, async (point) => {
986
+ await this._page.mouse.move(progress, point.x, point.y);
987
+ await this._page.mouse.down(progress);
988
+ }, {
989
+ ...options,
990
+ waitAfter: "disabled",
991
+ position: options.sourcePosition
992
+ });
993
+ }));
994
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
995
+ return handle._retryPointerAction(progress, "move and up", false, async (point) => {
996
+ await this._page.mouse.move(progress, point.x, point.y);
997
+ await this._page.mouse.up(progress);
998
+ }, {
999
+ ...options,
1000
+ waitAfter: "disabled",
1001
+ position: options.targetPosition
1002
+ });
1003
+ }));
1134
1004
  }
1135
- async tap(metadata, selector, options) {
1136
- if (!this._page._browserContext._options.hasTouch)
1005
+ async tap(progress, selector, options) {
1006
+ if (!this._page.browserContext._options.hasTouch)
1137
1007
  throw new Error("The page does not support tap. Use hasTouch context option to enable touch support.");
1138
- const controller = new import_progress.ProgressController(metadata, this);
1139
- return controller.run(async (progress) => {
1140
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._tap(progress, options)));
1141
- }, this._page._timeoutSettings.timeout(options));
1142
- }
1143
- async fill(metadata, selector, value, options) {
1144
- const controller = new import_progress.ProgressController(metadata, this);
1145
- return controller.run(async (progress) => {
1146
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._fill(progress, value, options)));
1147
- }, this._page._timeoutSettings.timeout(options));
1148
- }
1149
- async focus(metadata, selector, options = {}) {
1150
- const controller = new import_progress.ProgressController(metadata, this);
1151
- await controller.run(async (progress) => {
1152
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._focus(progress)));
1153
- }, this._page._timeoutSettings.timeout(options));
1154
- }
1155
- async blur(metadata, selector, options = {}) {
1156
- const controller = new import_progress.ProgressController(metadata, this);
1157
- await controller.run(async (progress) => {
1158
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
1159
- }, this._page._timeoutSettings.timeout(options));
1160
- }
1161
- async textContent(metadata, selector, options = {}, scope) {
1162
- return this._callOnElementOnceMatches(metadata, selector, (injected, element) => element.textContent, void 0, options, scope);
1163
- }
1164
- async innerText(metadata, selector, options = {}, scope) {
1165
- return this._callOnElementOnceMatches(metadata, selector, (injectedScript, element) => {
1008
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._tap(progress, options)));
1009
+ }
1010
+ async fill(progress, selector, value, options) {
1011
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._fill(progress, value, options)));
1012
+ }
1013
+ async focus(progress, selector, options) {
1014
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._focus(progress)));
1015
+ }
1016
+ async blur(progress, selector, options) {
1017
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
1018
+ }
1019
+ async resolveSelector(progress, selector, options = {}) {
1020
+ const element = await progress.race(this.selectors.query(selector, options));
1021
+ if (!element)
1022
+ throw new Error(`No element matching ${selector}`);
1023
+ const generated = await progress.race(element.evaluateInUtility(async ([injected, node]) => {
1024
+ return injected.generateSelectorSimple(node);
1025
+ }, {}));
1026
+ if (!generated)
1027
+ throw new Error(`Unable to generate locator for ${selector}`);
1028
+ let frame = element._frame;
1029
+ const result = [generated];
1030
+ while (frame?.parentFrame()) {
1031
+ const frameElement = await progress.race(frame.frameElement());
1032
+ if (frameElement) {
1033
+ const generated2 = await progress.race(frameElement.evaluateInUtility(async ([injected, node]) => {
1034
+ return injected.generateSelectorSimple(node);
1035
+ }, {}));
1036
+ frameElement.dispose();
1037
+ if (generated2 === "error:notconnected" || !generated2)
1038
+ throw new Error(`Unable to generate locator for ${selector}`);
1039
+ result.push(generated2);
1040
+ }
1041
+ frame = frame.parentFrame();
1042
+ }
1043
+ const resolvedSelector = result.reverse().join(" >> internal:control=enter-frame >> ");
1044
+ return { resolvedSelector };
1045
+ }
1046
+ async textContent(progress, selector, options, scope) {
1047
+ return this._callOnElementOnceMatches(progress, selector, (injected, element) => element.textContent, void 0, options, scope);
1048
+ }
1049
+ async innerText(progress, selector, options, scope) {
1050
+ return this._callOnElementOnceMatches(progress, selector, (injectedScript, element) => {
1166
1051
  if (element.namespaceURI !== "http://www.w3.org/1999/xhtml")
1167
1052
  throw injectedScript.createStacklessError("Node is not an HTMLElement");
1168
1053
  return element.innerText;
1169
1054
  }, void 0, options, scope);
1170
1055
  }
1171
- async innerHTML(metadata, selector, options = {}, scope) {
1172
- return this._callOnElementOnceMatches(metadata, selector, (injected, element) => element.innerHTML, void 0, options, scope);
1056
+ async innerHTML(progress, selector, options, scope) {
1057
+ return this._callOnElementOnceMatches(progress, selector, (injected, element) => element.innerHTML, void 0, options, scope);
1173
1058
  }
1174
- async getAttribute(metadata, selector, name, options = {}, scope) {
1175
- return this._callOnElementOnceMatches(metadata, selector, (injected, element, data) => element.getAttribute(data.name), { name }, options, scope);
1059
+ async getAttribute(progress, selector, name, options, scope) {
1060
+ return this._callOnElementOnceMatches(progress, selector, (injected, element, data) => element.getAttribute(data.name), { name }, options, scope);
1176
1061
  }
1177
- async inputValue(metadata, selector, options = {}, scope) {
1178
- return this._callOnElementOnceMatches(metadata, selector, (injectedScript, node) => {
1062
+ async inputValue(progress, selector, options, scope) {
1063
+ return this._callOnElementOnceMatches(progress, selector, (injectedScript, node) => {
1179
1064
  const element = injectedScript.retarget(node, "follow-label");
1180
1065
  if (!element || element.nodeName !== "INPUT" && element.nodeName !== "TEXTAREA" && element.nodeName !== "SELECT")
1181
1066
  throw injectedScript.createStacklessError("Node is not an <input>, <textarea> or <select> element");
1182
1067
  return element.value;
1183
1068
  }, void 0, options, scope);
1184
1069
  }
1185
- async highlight(selector) {
1186
- const resolved = await this.selectors.resolveInjectedForSelector(selector);
1070
+ async highlight(progress, selector) {
1071
+ const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector));
1187
1072
  if (!resolved)
1188
1073
  return;
1189
- return await resolved.injected.evaluate((injected, { info }) => {
1074
+ return await progress.race(resolved.injected.evaluate((injected, { info }) => {
1190
1075
  return injected.highlight(info.parsed);
1191
- }, { info: resolved.info });
1076
+ }, { info: resolved.info }));
1192
1077
  }
1193
1078
  async hideHighlight() {
1194
1079
  return this.raceAgainstEvaluationStallingEvents(async () => {
@@ -1199,28 +1084,48 @@ class Frame extends import_instrumentation.SdkObject {
1199
1084
  });
1200
1085
  });
1201
1086
  }
1202
- async _elementState(metadata, selector, state, options = {}, scope) {
1203
- const result = await this._callOnElementOnceMatches(metadata, selector, (injected, element, data) => {
1087
+ async _elementState(progress, selector, state, options, scope) {
1088
+ const result = await this._callOnElementOnceMatches(progress, selector, (injected, element, data) => {
1204
1089
  return injected.elementState(element, data.state);
1205
1090
  }, { state }, options, scope);
1206
1091
  if (result.received === "error:notconnected")
1207
1092
  dom.throwElementIsNotAttached();
1208
1093
  return result.matches;
1209
1094
  }
1210
- async isVisible(metadata, selector, options = {}, scope) {
1211
- const controller = new import_progress.ProgressController(metadata, this);
1212
- return controller.run(async (progress) => {
1213
- progress.log(` checking visibility of ${this._asLocator(selector)}`);
1214
- return await this.isVisibleInternal(selector, options, scope);
1215
- }, this._page._timeoutSettings.timeout({}));
1095
+ async isVisible(progress, selector, options = {}, scope) {
1096
+ progress.log(` checking visibility of ${this._asLocator(selector)}`);
1097
+ return await this.isVisibleInternal(progress, selector, options, scope);
1216
1098
  }
1217
- async isVisibleInternal(selector, options = {}, scope) {
1099
+ async isVisibleInternal(progress, selector, options = {}, scope) {
1218
1100
  try {
1219
- const custom_metadata = { "internal": false, "log": [] };
1220
- const controller = new import_progress.ProgressController(custom_metadata, this);
1221
- return await controller.run(async (progress) => {
1222
- progress.log("waiting for " + this._asLocator(selector));
1223
- const promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, false, async (handle) => {
1101
+ const metadata = { internal: false, log: [], method: "isVisible" };
1102
+ const progress2 = {
1103
+ log: (message) => metadata.log.push(message),
1104
+ metadata,
1105
+ race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
1106
+ };
1107
+ progress2.log("waiting for " + this._asLocator(selector));
1108
+ if (selector === ":scope") {
1109
+ const scopeParentNode = scope.parentNode || scope;
1110
+ if (scopeParentNode.constructor.name == "ElementHandle") {
1111
+ return await scopeParentNode.evaluateInUtility(([injected, node, { scope: handle2 }]) => {
1112
+ const state = handle2 ? injected.elementState(handle2, "visible") : {
1113
+ matches: false,
1114
+ received: "error:notconnected"
1115
+ };
1116
+ return state.matches;
1117
+ }, { scope });
1118
+ } else {
1119
+ return await scopeParentNode.evaluate((injected, node, { scope: handle2 }) => {
1120
+ const state = handle2 ? injected.elementState(handle2, "visible") : {
1121
+ matches: false,
1122
+ received: "error:notconnected"
1123
+ };
1124
+ return state.matches;
1125
+ }, { scope });
1126
+ }
1127
+ } else {
1128
+ return await this._retryWithoutProgress(progress2, selector, options.strict, false, async (handle) => {
1224
1129
  if (!handle) return false;
1225
1130
  if (handle.parentNode.constructor.name == "ElementHandle") {
1226
1131
  return await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
@@ -1239,227 +1144,215 @@ class Frame extends import_instrumentation.SdkObject {
1239
1144
  return state.matches;
1240
1145
  }, { handle });
1241
1146
  }
1242
- }, "returnOnNotResolved");
1243
- return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1244
- }, 1e4) || false;
1147
+ }, "returnOnNotResolved", null);
1148
+ }
1245
1149
  } catch (e) {
1246
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e) || (0, import_protocolError.isSessionClosedError)(e)) throw e;
1150
+ if (this.isNonRetriableError(e)) throw e;
1247
1151
  return false;
1248
1152
  }
1249
1153
  }
1250
- async isHidden(metadata, selector, options = {}, scope) {
1251
- return !await this.isVisible(metadata, selector, options, scope);
1154
+ async isHidden(progress, selector, options = {}, scope) {
1155
+ return !await this.isVisible(progress, selector, options, scope);
1252
1156
  }
1253
- async isDisabled(metadata, selector, options = {}, scope) {
1254
- return this._elementState(metadata, selector, "disabled", options, scope);
1157
+ async isDisabled(progress, selector, options, scope) {
1158
+ return this._elementState(progress, selector, "disabled", options, scope);
1255
1159
  }
1256
- async isEnabled(metadata, selector, options = {}, scope) {
1257
- return this._elementState(metadata, selector, "enabled", options, scope);
1160
+ async isEnabled(progress, selector, options, scope) {
1161
+ return this._elementState(progress, selector, "enabled", options, scope);
1258
1162
  }
1259
- async isEditable(metadata, selector, options = {}, scope) {
1260
- return this._elementState(metadata, selector, "editable", options, scope);
1163
+ async isEditable(progress, selector, options, scope) {
1164
+ return this._elementState(progress, selector, "editable", options, scope);
1261
1165
  }
1262
- async isChecked(metadata, selector, options = {}, scope) {
1263
- return this._elementState(metadata, selector, "checked", options, scope);
1166
+ async isChecked(progress, selector, options, scope) {
1167
+ return this._elementState(progress, selector, "checked", options, scope);
1264
1168
  }
1265
- async hover(metadata, selector, options = {}) {
1266
- const controller = new import_progress.ProgressController(metadata, this);
1267
- return controller.run(async (progress) => {
1268
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._hover(progress, options)));
1269
- }, this._page._timeoutSettings.timeout(options));
1169
+ async hover(progress, selector, options) {
1170
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._hover(progress, options)));
1270
1171
  }
1271
- async selectOption(metadata, selector, elements, values, options = {}) {
1272
- const controller = new import_progress.ProgressController(metadata, this);
1273
- return controller.run(async (progress) => {
1274
- return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._selectOption(progress, elements, values, options));
1275
- }, this._page._timeoutSettings.timeout(options));
1172
+ async selectOption(progress, selector, elements, values, options) {
1173
+ return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._selectOption(progress, elements, values, options));
1276
1174
  }
1277
- async setInputFiles(metadata, selector, params) {
1175
+ async setInputFiles(progress, selector, params) {
1278
1176
  const inputFileItems = await (0, import_fileUploadUtils.prepareFilesForUpload)(this, params);
1279
- const controller = new import_progress.ProgressController(metadata, this);
1280
- return controller.run(async (progress) => {
1281
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
1282
- }, this._page._timeoutSettings.timeout(params));
1283
- }
1284
- async type(metadata, selector, text, options = {}) {
1285
- const controller = new import_progress.ProgressController(metadata, this);
1286
- return controller.run(async (progress) => {
1287
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._type(progress, text, options)));
1288
- }, this._page._timeoutSettings.timeout(options));
1289
- }
1290
- async press(metadata, selector, key, options = {}) {
1291
- const controller = new import_progress.ProgressController(metadata, this);
1292
- return controller.run(async (progress) => {
1293
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._press(progress, key, options)));
1294
- }, this._page._timeoutSettings.timeout(options));
1295
- }
1296
- async check(metadata, selector, options = {}) {
1297
- const controller = new import_progress.ProgressController(metadata, this);
1298
- return controller.run(async (progress) => {
1299
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, true, options)));
1300
- }, this._page._timeoutSettings.timeout(options));
1301
- }
1302
- async uncheck(metadata, selector, options = {}) {
1303
- const controller = new import_progress.ProgressController(metadata, this);
1304
- return controller.run(async (progress) => {
1305
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, false, options)));
1306
- }, this._page._timeoutSettings.timeout(options));
1307
- }
1308
- async waitForTimeout(metadata, timeout) {
1309
- const controller = new import_progress.ProgressController(metadata, this);
1310
- return controller.run(async () => {
1311
- await new Promise((resolve) => setTimeout(resolve, timeout));
1312
- });
1177
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
1313
1178
  }
1314
- async ariaSnapshot(metadata, selector, options = {}) {
1315
- const controller = new import_progress.ProgressController(metadata, this);
1316
- return controller.run(async (progress) => {
1317
- return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => handle.ariaSnapshot(options));
1318
- }, this._page._timeoutSettings.timeout(options));
1179
+ async type(progress, selector, text, options) {
1180
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._type(progress, text, options)));
1319
1181
  }
1320
- async expect(metadata, selector, options) {
1321
- const result = await this._expectImpl(metadata, selector, options);
1322
- if (result.matches === options.isNot)
1323
- metadata.error = { error: { name: "Expect", message: "Expect failed" } };
1324
- return result;
1182
+ async press(progress, selector, key, options) {
1183
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._press(progress, key, options)));
1184
+ }
1185
+ async check(progress, selector, options) {
1186
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, true, options)));
1187
+ }
1188
+ async uncheck(progress, selector, options) {
1189
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, false, options)));
1190
+ }
1191
+ async waitForTimeout(progress, timeout) {
1192
+ return progress.wait(timeout);
1193
+ }
1194
+ async ariaSnapshot(progress, selector) {
1195
+ return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => progress.race(handle.ariaSnapshot()));
1325
1196
  }
1326
- async _expectImpl(metadata, selector, options) {
1197
+ async expect(progress, selector, options, timeout) {
1198
+ progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${timeout ? ` with timeout ${timeout}ms` : ""}`);
1327
1199
  const lastIntermediateResult = { isSet: false };
1200
+ const fixupMetadataError = (result) => {
1201
+ if (result.matches === options.isNot)
1202
+ progress.metadata.error = { error: { name: "Expect", message: "Expect failed" } };
1203
+ };
1328
1204
  try {
1329
- let timeout = this._page._timeoutSettings.timeout(options);
1330
- const start = timeout > 0 ? (0, import_utils.monotonicTime)() : 0;
1331
- await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1332
- progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ""}`);
1205
+ if (selector)
1333
1206
  progress.log(`waiting for ${this._asLocator(selector)}`);
1334
- await this._page.performActionPreChecks(progress);
1335
- }, timeout);
1207
+ await this._page.performActionPreChecks(progress);
1336
1208
  try {
1337
- const resultOneShot = await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1338
- return await this._expectInternal(progress, selector, options, lastIntermediateResult);
1339
- });
1209
+ const resultOneShot = await this._expectInternal(progress, selector, options, lastIntermediateResult, true);
1340
1210
  if (resultOneShot.matches !== options.isNot)
1341
1211
  return resultOneShot;
1342
1212
  } catch (e) {
1343
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
1213
+ if (this.isNonRetriableError(e))
1344
1214
  throw e;
1345
1215
  }
1346
- if (timeout > 0) {
1347
- const elapsed = (0, import_utils.monotonicTime)() - start;
1348
- timeout -= elapsed;
1349
- }
1350
- if (timeout < 0)
1351
- return { matches: options.isNot, log: (0, import_callLog.compressCallLog)(metadata.log), timedOut: true, received: lastIntermediateResult.received };
1352
- return await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1353
- return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling3) => {
1354
- await this._page.performActionPreChecks(progress);
1355
- const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult);
1356
- if (matches === options.isNot) {
1357
- return continuePolling3;
1358
- }
1359
- return { matches, received };
1360
- });
1361
- }, timeout);
1216
+ const result = await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling) => {
1217
+ await this._page.performActionPreChecks(progress);
1218
+ const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult, false);
1219
+ if (matches === options.isNot) {
1220
+ return continuePolling;
1221
+ }
1222
+ return { matches, received };
1223
+ });
1224
+ fixupMetadataError(result);
1225
+ return result;
1362
1226
  } catch (e) {
1363
1227
  if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
1364
1228
  throw e;
1365
- const result = { matches: options.isNot, log: (0, import_callLog.compressCallLog)(metadata.log) };
1229
+ const result = { matches: options.isNot, log: (0, import_callLog.compressCallLog)(progress.metadata.log) };
1366
1230
  if (lastIntermediateResult.isSet)
1367
1231
  result.received = lastIntermediateResult.received;
1368
1232
  if (e instanceof import_errors.TimeoutError)
1369
1233
  result.timedOut = true;
1234
+ fixupMetadataError(result);
1370
1235
  return result;
1371
1236
  }
1372
1237
  }
1373
- async _expectInternal(progress, selector, options, lastIntermediateResult) {
1374
- progress.log("waiting for " + this._asLocator(selector));
1238
+ async _expectInternal(progress, selector, options, lastIntermediateResult, noAbort) {
1239
+ const race = (p) => noAbort ? p : progress.race(p);
1375
1240
  const isArray = options.expression === "to.have.count" || options.expression.endsWith(".array");
1376
- const promise = await this._retryWithProgressIfNotConnected(progress, selector, !isArray, false, async (result) => {
1377
- const handle = result[0];
1378
- const handles = result[1];
1379
- if (handle.parentNode.constructor.name == "ElementHandle") {
1380
- return await handle.parentNode.evaluateInUtility(async ([injected, node, { handle: handle2, options: options2, handles: handles2 }]) => {
1381
- return await injected.expect(handle2, options2, handles2);
1382
- }, { handle, options, handles });
1241
+ var log, matches, received, missingReceived;
1242
+ if (selector) {
1243
+ const { frame, info } = await race(this.selectors.resolveFrameForSelector(selector, { strict: true }));
1244
+ const action = async (result) => {
1245
+ if (!result) {
1246
+ if (options.expectedNumber === 0)
1247
+ return { matches: true };
1248
+ if (!options.isNot && options.expression === "to.be.hidden")
1249
+ return { matches: true };
1250
+ if (options.isNot && options.expression === "to.be.visible")
1251
+ return { matches: false };
1252
+ if (!options.isNot && options.expression === "to.be.detached")
1253
+ return { matches: true };
1254
+ if (options.isNot && options.expression === "to.be.attached")
1255
+ return { matches: false };
1256
+ if (options.isNot && options.expression === "to.be.in.viewport")
1257
+ return { matches: false };
1258
+ return { matches: options.isNot, missingReceived: true };
1259
+ }
1260
+ const handle = result[0];
1261
+ const handles = result[1];
1262
+ if (handle.parentNode.constructor.name == "ElementHandle") {
1263
+ return await handle.parentNode.evaluateInUtility(async ([injected, node, { handle: handle2, options: options2, handles: handles2 }]) => {
1264
+ return await injected.expect(handle2, options2, handles2);
1265
+ }, { handle, options, handles });
1266
+ } else {
1267
+ return await handle.parentNode.evaluate(async (injected, { handle: handle2, options: options2, handles: handles2 }) => {
1268
+ return await injected.expect(handle2, options2, handles2);
1269
+ }, { handle, options, handles });
1270
+ }
1271
+ };
1272
+ if (noAbort) {
1273
+ var { log, matches, received, missingReceived } = await this._retryWithoutProgress(progress, selector, !isArray, false, action, "returnAll", null);
1383
1274
  } else {
1384
- return await handle.parentNode.evaluate(async (injected, { handle: handle2, options: options2, handles: handles2 }) => {
1385
- return await injected.expect(handle2, options2, handles2);
1386
- }, { handle, options, handles });
1275
+ var { log, matches, received, missingReceived } = await race(this._retryWithProgressIfNotConnected(progress, selector, !isArray, false, action, "returnAll"));
1387
1276
  }
1388
- }, "returnAll");
1389
- var matches = false;
1390
- var received = 0;
1391
- var missingReceived = null;
1392
- if (promise) {
1393
- matches = promise.matches;
1394
- received = promise.received;
1395
- missingReceived = promise.missingReceived;
1396
- } else if (options.expectedNumber === 0) {
1397
- matches = true;
1277
+ } else {
1278
+ const world = options.expression === "to.have.property" ? "main" : "utility";
1279
+ const context = await race(this._context(world));
1280
+ const injected = await race(context.injectedScript());
1281
+ var { matches, received, missingReceived } = await race(injected.evaluate(async (injected2, { options: options2, callId }) => {
1282
+ return { ...await injected2.expect(void 0, options2, []) };
1283
+ }, { options, callId: progress.metadata.id }));
1398
1284
  }
1285
+ if (log)
1286
+ progress.log(log);
1399
1287
  if (matches === options.isNot) {
1400
1288
  lastIntermediateResult.received = missingReceived ? "<element(s) not found>" : received;
1401
1289
  lastIntermediateResult.isSet = true;
1402
- if (!missingReceived && !Array.isArray(received)) progress.log(' unexpected value "' + renderUnexpectedValue(options.expression, received) + '"');
1290
+ if (!missingReceived && !Array.isArray(received))
1291
+ progress.log(` unexpected value "${renderUnexpectedValue(options.expression, received)}"`);
1403
1292
  }
1404
- return {
1405
- matches,
1406
- received
1407
- };
1293
+ return { matches, received };
1408
1294
  }
1409
- async _waitForFunctionExpression(metadata, expression, isFunction, arg, options, world = "main") {
1410
- const controller = new import_progress.ProgressController(metadata, this);
1295
+ async waitForFunctionExpression(progress, expression, isFunction, arg, options, world = "main") {
1411
1296
  if (typeof options.pollingInterval === "number")
1412
1297
  (0, import_utils.assert)(options.pollingInterval > 0, "Cannot poll with non-positive interval: " + options.pollingInterval);
1413
1298
  expression = js.normalizeEvaluationExpression(expression, isFunction);
1414
- return controller.run(async (progress) => {
1415
- return this.retryWithProgressAndTimeouts(progress, [100], async () => {
1416
- const context = world === "main" ? await this._mainContext() : await this._utilityContext();
1417
- const injectedScript = await context.injectedScript();
1418
- const handle = await injectedScript.evaluateHandle((injected, { expression: expression2, isFunction: isFunction2, polling, arg: arg2 }) => {
1419
- const predicate = () => {
1420
- let result2 = globalThis.eval(expression2);
1421
- if (isFunction2 === true) {
1299
+ return this.retryWithProgressAndTimeouts(progress, [100], async () => {
1300
+ const context = world === "main" ? await progress.race(this._mainContext()) : await progress.race(this._utilityContext());
1301
+ const injectedScript = await progress.race(context.injectedScript());
1302
+ const handle = await progress.race(injectedScript.evaluateHandle((injected, { expression: expression2, isFunction: isFunction2, polling, arg: arg2 }) => {
1303
+ let evaledExpression;
1304
+ const predicate = () => {
1305
+ let result2 = evaledExpression ?? globalThis.eval(expression2);
1306
+ if (isFunction2 === true) {
1307
+ evaledExpression = result2;
1308
+ result2 = result2(arg2);
1309
+ } else if (isFunction2 === false) {
1310
+ result2 = result2;
1311
+ } else {
1312
+ if (typeof result2 === "function") {
1313
+ evaledExpression = result2;
1422
1314
  result2 = result2(arg2);
1423
- } else if (isFunction2 === false) {
1424
- result2 = result2;
1425
- } else {
1426
- if (typeof result2 === "function")
1427
- result2 = result2(arg2);
1428
1315
  }
1429
- return result2;
1430
- };
1431
- let fulfill;
1432
- let reject;
1433
- let aborted = false;
1434
- const result = new Promise((f, r) => {
1435
- fulfill = f;
1436
- reject = r;
1437
- });
1438
- const next = () => {
1439
- if (aborted)
1316
+ }
1317
+ return result2;
1318
+ };
1319
+ let fulfill;
1320
+ let reject;
1321
+ let aborted = false;
1322
+ const result = new Promise((f, r) => {
1323
+ fulfill = f;
1324
+ reject = r;
1325
+ });
1326
+ const next = () => {
1327
+ if (aborted)
1328
+ return;
1329
+ try {
1330
+ const success = predicate();
1331
+ if (success) {
1332
+ fulfill(success);
1440
1333
  return;
1441
- try {
1442
- const success = predicate();
1443
- if (success) {
1444
- fulfill(success);
1445
- return;
1446
- }
1447
- if (typeof polling !== "number")
1448
- injected.utils.builtins.requestAnimationFrame(next);
1449
- else
1450
- injected.utils.builtins.setTimeout(next, polling);
1451
- } catch (e) {
1452
- reject(e);
1453
1334
  }
1454
- };
1455
- next();
1456
- return { result, abort: () => aborted = true };
1457
- }, { expression, isFunction, polling: options.pollingInterval, arg });
1458
- progress.cleanupWhenAborted(() => handle.evaluate((h) => h.abort()).catch(() => {
1459
- }));
1460
- return handle.evaluateHandle((h) => h.result);
1461
- });
1462
- }, this._page._timeoutSettings.timeout(options));
1335
+ if (typeof polling !== "number")
1336
+ injected.utils.builtins.requestAnimationFrame(next);
1337
+ else
1338
+ injected.utils.builtins.setTimeout(next, polling);
1339
+ } catch (e) {
1340
+ reject(e);
1341
+ }
1342
+ };
1343
+ next();
1344
+ return { result, abort: () => aborted = true };
1345
+ }, { expression, isFunction, polling: options.pollingInterval, arg }));
1346
+ try {
1347
+ return await progress.race(handle.evaluateHandle((h) => h.result));
1348
+ } catch (error) {
1349
+ await handle.evaluate((h) => h.abort()).catch(() => {
1350
+ });
1351
+ throw error;
1352
+ } finally {
1353
+ handle.dispose();
1354
+ }
1355
+ });
1463
1356
  }
1464
1357
  async waitForFunctionValueInUtility(progress, pageFunction) {
1465
1358
  const expression = `() => {
@@ -1468,25 +1361,25 @@ class Frame extends import_instrumentation.SdkObject {
1468
1361
  return result;
1469
1362
  return JSON.stringify(result);
1470
1363
  }`;
1471
- const handle = await this._waitForFunctionExpression((0, import_instrumentation.serverSideCallMetadata)(), expression, true, void 0, { timeout: progress.timeUntilDeadline() }, "utility");
1364
+ const handle = await this.waitForFunctionExpression(progress, expression, true, void 0, {}, "utility");
1472
1365
  return JSON.parse(handle.rawValue());
1473
1366
  }
1474
1367
  async title() {
1475
1368
  const context = await this._utilityContext();
1476
1369
  return context.evaluate(() => document.title);
1477
1370
  }
1478
- async rafrafTimeout(timeout) {
1371
+ async rafrafTimeout(progress, timeout) {
1479
1372
  if (timeout === 0)
1480
1373
  return;
1481
- const context = await this._utilityContext();
1374
+ const context = await progress.race(this._utilityContext());
1482
1375
  await Promise.all([
1483
1376
  // wait for double raf
1484
- context.evaluate(() => new Promise((x) => {
1377
+ progress.race(context.evaluate(() => new Promise((x) => {
1485
1378
  requestAnimationFrame(() => {
1486
1379
  requestAnimationFrame(x);
1487
1380
  });
1488
- })),
1489
- new Promise((fulfill) => setTimeout(fulfill, timeout))
1381
+ }))),
1382
+ progress.wait(timeout)
1490
1383
  ]);
1491
1384
  }
1492
1385
  _onDetached() {
@@ -1501,16 +1394,39 @@ class Frame extends import_instrumentation.SdkObject {
1501
1394
  this._parentFrame._childFrames.delete(this);
1502
1395
  this._parentFrame = null;
1503
1396
  }
1504
- async _callOnElementOnceMatches(metadata, selector, body, taskData, options = {}, scope) {
1397
+ async _callOnElementOnceMatches(progress, selector, body, taskData, options, scope) {
1505
1398
  const callbackText = body.toString();
1506
- const controller = new import_progress.ProgressController(metadata, this);
1507
- return controller.run(async (progress) => {
1508
- progress.log("waiting for " + this._asLocator(selector));
1509
- const promise = this._retryWithProgressIfNotConnected(progress, selector, false, false, async (handle) => {
1399
+ progress.log("waiting for " + this._asLocator(selector));
1400
+ var promise;
1401
+ if (selector === ":scope") {
1402
+ const scopeParentNode = scope.parentNode || scope;
1403
+ if (scopeParentNode.constructor.name == "ElementHandle") {
1404
+ promise = scopeParentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }]) => {
1405
+ const callback = injected.eval(callbackText2);
1406
+ const haha = callback(injected, handle2, taskData2);
1407
+ return haha;
1408
+ }, {
1409
+ callbackText,
1410
+ scope,
1411
+ taskData
1412
+ });
1413
+ } else {
1414
+ promise = scopeParentNode.evaluate((injected, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }) => {
1415
+ const callback = injected.eval(callbackText2);
1416
+ return callback(injected, handle2, taskData2);
1417
+ }, {
1418
+ callbackText,
1419
+ scope,
1420
+ taskData
1421
+ });
1422
+ }
1423
+ } else {
1424
+ promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, false, async (handle) => {
1510
1425
  if (handle.parentNode.constructor.name == "ElementHandle") {
1511
1426
  return await handle.parentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, handle: handle2, taskData: taskData2 }]) => {
1512
1427
  const callback = injected.eval(callbackText2);
1513
- return callback(injected, handle2, taskData2);
1428
+ const haha = callback(injected, handle2, taskData2);
1429
+ return haha;
1514
1430
  }, {
1515
1431
  callbackText,
1516
1432
  handle,
@@ -1527,8 +1443,8 @@ class Frame extends import_instrumentation.SdkObject {
1527
1443
  });
1528
1444
  }
1529
1445
  });
1530
- return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1531
- }, this._page._timeoutSettings.timeout(options));
1446
+ }
1447
+ return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1532
1448
  }
1533
1449
  _setContext(world, context) {
1534
1450
  const data = this._contextData.get(world);
@@ -1573,35 +1489,12 @@ class Frame extends import_instrumentation.SdkObject {
1573
1489
  async extendInjectedScript(source, arg) {
1574
1490
  const context = await this._context("main");
1575
1491
  const injectedScriptHandle = await context.injectedScript();
1576
- return injectedScriptHandle.evaluateHandle((injectedScript, { source: source2, arg: arg2 }) => {
1577
- return injectedScript.extend(source2, arg2);
1492
+ await injectedScriptHandle.evaluate((injectedScript, { source: source2, arg: arg2 }) => {
1493
+ injectedScript.extend(source2, arg2);
1578
1494
  }, { source, arg });
1579
1495
  }
1580
- async resetStorageForCurrentOriginBestEffort(newStorage) {
1581
- const context = await this._utilityContext();
1582
- await context.evaluate(async ({ ls }) => {
1583
- sessionStorage.clear();
1584
- localStorage.clear();
1585
- for (const entry of ls || [])
1586
- localStorage[entry.name] = entry.value;
1587
- const registrations = navigator.serviceWorker ? await navigator.serviceWorker.getRegistrations() : [];
1588
- await Promise.all(registrations.map(async (r) => {
1589
- if (!r.installing && !r.waiting && !r.active)
1590
- r.unregister().catch(() => {
1591
- });
1592
- else
1593
- await r.unregister().catch(() => {
1594
- });
1595
- }));
1596
- for (const db of await indexedDB.databases?.() || []) {
1597
- if (db.name)
1598
- indexedDB.deleteDatabase(db.name);
1599
- }
1600
- }, { ls: newStorage?.localStorage }).catch(() => {
1601
- });
1602
- }
1603
1496
  _asLocator(selector) {
1604
- return (0, import_utils.asLocator)(this._page.attribution.playwright.options.sdkLanguage, selector);
1497
+ return (0, import_utils.asLocator)(this._page.browserContext._browser.sdkLanguage(), selector);
1605
1498
  }
1606
1499
  async _getFrameMainFrameContextId(client) {
1607
1500
  try {
@@ -1622,6 +1515,82 @@ class Frame extends import_instrumentation.SdkObject {
1622
1515
  }
1623
1516
  return 0;
1624
1517
  }
1518
+ async _retryWithoutProgress(progress, selector, strict, performActionPreChecks, action, returnAction, continuePolling) {
1519
+ if (performActionPreChecks) await this._page.performActionPreChecks(progress);
1520
+ const resolved = await this.selectors.resolveInjectedForSelector(selector, { strict });
1521
+ if (!resolved) {
1522
+ if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1523
+ const result2 = await action(null);
1524
+ return result2 === "internal:continuepolling" ? continuePolling : result2;
1525
+ }
1526
+ return continuePolling;
1527
+ }
1528
+ try {
1529
+ var client = this._page.delegate._sessionForFrame(resolved.frame)._client;
1530
+ } catch (e) {
1531
+ var client = this._page.delegate._mainFrameSession._client;
1532
+ }
1533
+ var utilityContext = await resolved.frame._utilityContext();
1534
+ var mainContext = await resolved.frame._mainContext();
1535
+ const documentNode = await client._sendMayFail("Runtime.evaluate", {
1536
+ expression: "document",
1537
+ serializationOptions: {
1538
+ serialization: "idOnly"
1539
+ },
1540
+ contextId: utilityContext.delegate._contextId
1541
+ });
1542
+ if (!documentNode) return continuePolling;
1543
+ const documentScope = new dom.ElementHandle(utilityContext, documentNode.result.objectId);
1544
+ let currentScopingElements;
1545
+ try {
1546
+ currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext, documentScope, progress, resolved.info.parsed);
1547
+ } catch (e) {
1548
+ if ("JSHandles can be evaluated only in the context they were created!" === e.message) return continuePolling3;
1549
+ await progress.race(resolved.injected.evaluateHandle((injected, { error }) => {
1550
+ throw error;
1551
+ }, { error: e }));
1552
+ }
1553
+ if (currentScopingElements.length == 0) {
1554
+ if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1555
+ const result2 = await action(null);
1556
+ return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1557
+ }
1558
+ return continuePolling;
1559
+ }
1560
+ const resultElement = currentScopingElements[0];
1561
+ if (currentScopingElements.length > 1) {
1562
+ if (resolved.info.strict) {
1563
+ await progress.race(resolved.injected.evaluateHandle((injected, {
1564
+ info,
1565
+ elements
1566
+ }) => {
1567
+ throw injected.strictModeViolationError(info.parsed, elements);
1568
+ }, {
1569
+ info: resolved.info,
1570
+ elements: currentScopingElements
1571
+ }));
1572
+ }
1573
+ progress.log(" locator resolved to " + currentScopingElements.length + " elements. Proceeding with the first one: " + resultElement.preview());
1574
+ } else if (resultElement) {
1575
+ progress.log(" locator resolved to " + resultElement.preview());
1576
+ }
1577
+ try {
1578
+ var result = null;
1579
+ if (returnAction === "returnAll") {
1580
+ result = await action([resultElement, currentScopingElements]);
1581
+ } else {
1582
+ result = await action(resultElement);
1583
+ }
1584
+ if (result === "error:notconnected") {
1585
+ progress.log("element was detached from the DOM, retrying");
1586
+ return continuePolling;
1587
+ } else if (result === "internal:continuepolling") {
1588
+ return continuePolling;
1589
+ }
1590
+ return result;
1591
+ } finally {
1592
+ }
1593
+ }
1625
1594
  async _customFindElementsByParsed(resolved, client, context, documentScope, progress, parsed) {
1626
1595
  var parsedEdits = { ...parsed };
1627
1596
  var currentScopingElements = [documentScope];
@@ -1632,8 +1601,9 @@ class Frame extends import_instrumentation.SdkObject {
1632
1601
  var elementsIndexes = [];
1633
1602
  if (part.name == "nth") {
1634
1603
  const partNth = Number(part.body);
1635
- if (partNth > currentScopingElements.length || partNth < -currentScopingElements.length) {
1636
- return continuePolling;
1604
+ if (currentScopingElements.length == 0) return [];
1605
+ if (partNth > currentScopingElements.length - 1 || partNth < -(currentScopingElements.length - 1)) {
1606
+ throw new Error("Can't query n-th element");
1637
1607
  } else {
1638
1608
  currentScopingElements = [currentScopingElements.at(partNth)];
1639
1609
  continue;
@@ -1701,7 +1671,7 @@ class Frame extends import_instrumentation.SdkObject {
1701
1671
  callId: progress.metadata.id
1702
1672
  });
1703
1673
  const rootElementsAmount = await rootElements.getProperty("length");
1704
- queryingElements.push([rootElements, rootElementsAmount, resolved.injected]);
1674
+ queryingElements.push([rootElements, rootElementsAmount, scope]);
1705
1675
  for (var queryedElement of queryingElements) {
1706
1676
  var elementsToCheck = queryedElement[0];
1707
1677
  var elementsAmount = await queryedElement[1].jsonValue();
@@ -1730,6 +1700,7 @@ class Frame extends import_instrumentation.SdkObject {
1730
1700
  currentScopingElements = [];
1731
1701
  for (var element of elements) {
1732
1702
  var elemIndex = element.backendNodeId;
1703
+ if (elementsIndexes.includes(elemIndex)) continue;
1733
1704
  var elemPos = elementsIndexes.findIndex((index) => index > elemIndex);
1734
1705
  if (elemPos === -1) {
1735
1706
  currentScopingElements.push(element);
@@ -1752,26 +1723,27 @@ class SignalBarrier {
1752
1723
  }
1753
1724
  waitFor() {
1754
1725
  this.release();
1755
- return this._promise;
1726
+ return this._progress.race(this._promise);
1756
1727
  }
1757
- async addFrameNavigation(frame) {
1728
+ addFrameNavigation(frame) {
1758
1729
  if (frame.parentFrame())
1759
1730
  return;
1760
1731
  this.retain();
1761
- const waiter = import_helper.helper.waitForEvent(null, frame, Frame.Events.InternalNavigation, (e) => {
1732
+ const waiter = import_helper.helper.waitForEvent(this._progress, frame, Frame.Events.InternalNavigation, (e) => {
1762
1733
  if (!e.isPublic)
1763
1734
  return false;
1764
1735
  if (!e.error && this._progress)
1765
1736
  this._progress.log(` navigated to "${frame._url}"`);
1766
1737
  return true;
1767
1738
  });
1768
- await import_utils.LongStandingScope.raceMultiple([
1739
+ import_utils.LongStandingScope.raceMultiple([
1769
1740
  frame._page.openScope,
1770
1741
  frame._detachedScope
1771
1742
  ], waiter.promise).catch(() => {
1743
+ }).finally(() => {
1744
+ waiter.dispose();
1745
+ this.release();
1772
1746
  });
1773
- waiter.dispose();
1774
- this.release();
1775
1747
  }
1776
1748
  retain() {
1777
1749
  ++this._protectCount;