patchright-core 1.52.5 → 1.55.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +54 -32
  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 +30 -26
  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 +421 -345
  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 +43 -31
  72. package/lib/server/chromium/crPage.js +98 -72
  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 +98 -101
  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 +63 -20
  123. package/lib/server/frames.js +495 -555
  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 +8 -16
  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 +232 -177
  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 +128 -17
  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,14 +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) {
615
580
  if (this.isDetached()) throw new Error("Frame was detached");
616
581
  try {
617
- var client = this._page._delegate._sessionForFrame(this)._client;
582
+ var client = this._page.delegate._sessionForFrame(this)._client;
618
583
  } catch (e) {
619
- var client = this._page._delegate._mainFrameSession._client;
584
+ var client = this._page.delegate._mainFrameSession._client;
620
585
  }
621
586
  var iframeExecutionContextId = await this._getFrameMainFrameContextId(client);
622
587
  if (world == "main") {
@@ -624,7 +589,7 @@ class Frame extends import_instrumentation.SdkObject {
624
589
  var executionContextId = iframeExecutionContextId;
625
590
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
626
591
  this._iframeWorld = new import_dom.FrameExecutionContext(crContext, this, world);
627
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
592
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
628
593
  id: executionContextId,
629
594
  origin: world,
630
595
  name: world,
@@ -642,7 +607,7 @@ class Frame extends import_instrumentation.SdkObject {
642
607
  var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
643
608
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
644
609
  this._mainWorld = new import_dom.FrameExecutionContext(crContext, this, world);
645
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
610
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
646
611
  id: executionContextId,
647
612
  origin: world,
648
613
  name: world,
@@ -663,7 +628,7 @@ class Frame extends import_instrumentation.SdkObject {
663
628
  var executionContextId = result.executionContextId;
664
629
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
665
630
  this._isolatedWorld = new import_dom.FrameExecutionContext(crContext, this, world);
666
- this._page._delegate._mainFrameSession._onExecutionContextCreated({
631
+ this._page.delegate._mainFrameSession._onExecutionContextCreated({
667
632
  id: executionContextId,
668
633
  origin: world,
669
634
  name: world,
@@ -693,16 +658,20 @@ class Frame extends import_instrumentation.SdkObject {
693
658
  return value;
694
659
  }
695
660
  async evaluateExpressionHandle(expression, options = {}, arg) {
696
- const context = await this._context(options.world ?? "main");
661
+ const context = await this._context(options.world ?? "utility");
697
662
  const value = await context.evaluateExpressionHandle(expression, options, arg);
698
663
  return value;
699
664
  }
700
665
  async querySelector(selector, options) {
701
- import_debugLogger.debugLogger.log("api", ` finding element using the selector "${selector}"`);
702
- 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
+ });
703
673
  }
704
- async waitForSelector(metadata, selector, options, scope) {
705
- const controller = new import_progress.ProgressController(metadata, this);
674
+ async waitForSelector(progress, selector, performActionPreChecksAndLog, options, scope) {
706
675
  if (options.visibility)
707
676
  throw new Error("options.visibility is not supported, did you mean options.state?");
708
677
  if (options.waitFor && options.waitFor !== "visible")
@@ -710,15 +679,8 @@ class Frame extends import_instrumentation.SdkObject {
710
679
  const { state = "visible" } = options;
711
680
  if (!["attached", "detached", "visible", "hidden"].includes(state))
712
681
  throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
713
- return controller.run(async (progress) => {
682
+ if (performActionPreChecksAndLog)
714
683
  progress.log(`waiting for ${this._asLocator(selector)}${state === "attached" ? "" : " to be " + state}`);
715
- return await this.waitForSelectorInternal(progress, selector, true, options, scope);
716
- }, this._page._timeoutSettings.timeout(options));
717
- }
718
- async waitForSelectorInternal(progress, selector, performActionPreChecks, options, scope) {
719
- const {
720
- state = "visible"
721
- } = options;
722
684
  const promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, async (handle) => {
723
685
  const attached = !!handle;
724
686
  var visible = false;
@@ -726,15 +688,11 @@ class Frame extends import_instrumentation.SdkObject {
726
688
  if (handle.parentNode.constructor.name == "ElementHandle") {
727
689
  visible = await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
728
690
  return handle2 ? injected.utils.isElementVisible(handle2) : false;
729
- }, {
730
- handle
731
- });
691
+ }, { handle });
732
692
  } else {
733
693
  visible = await handle.parentNode.evaluate((injected, { handle: handle2 }) => {
734
694
  return handle2 ? injected.utils.isElementVisible(handle2) : false;
735
- }, {
736
- handle
737
- });
695
+ }, { handle });
738
696
  }
739
697
  }
740
698
  const success = {
@@ -743,12 +701,8 @@ class Frame extends import_instrumentation.SdkObject {
743
701
  visible,
744
702
  hidden: !visible
745
703
  }[state];
746
- if (!success) {
747
- return "internal:continuepolling";
748
- }
749
- if (options.omitReturnValue) {
750
- return null;
751
- }
704
+ if (!success) return "internal:continuepolling";
705
+ if (options.omitReturnValue) return null;
752
706
  const element = state === "attached" || state === "visible" ? handle : null;
753
707
  if (!element) return null;
754
708
  if (options.__testHookBeforeAdoptNode) await options.__testHookBeforeAdoptNode();
@@ -760,8 +714,8 @@ class Frame extends import_instrumentation.SdkObject {
760
714
  }, "returnOnNotResolved");
761
715
  return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
762
716
  }
763
- async dispatchEvent(metadata, selector, type, eventInit = {}, options = {}, scope) {
764
- 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) => {
765
719
  injectedScript.dispatchEvent(element, data.type, data.eventInit);
766
720
  }, { type, eventInit }, { mainWorld: true, ...options }, scope);
767
721
  }
@@ -775,6 +729,7 @@ class Frame extends import_instrumentation.SdkObject {
775
729
  }
776
730
  async evalOnSelectorAll(selector, expression, isFunction, arg, scope, isolatedContext) {
777
731
  try {
732
+ isolatedContext = this.selectors._parseSelector(selector, { strict: false }).world !== "main" && isolatedContext;
778
733
  const arrayHandle = await this.selectors.queryArrayInMainWorld(selector, scope, isolatedContext);
779
734
  const result = await arrayHandle.evaluateExpression(expression, { isFunction }, arg, isolatedContext);
780
735
  arrayHandle.dispose();
@@ -792,26 +747,30 @@ class Frame extends import_instrumentation.SdkObject {
792
747
  }, { parsed: selectors, color });
793
748
  }
794
749
  async querySelectorAll(selector) {
795
- return this.selectors.queryAll(selector);
796
- }
797
- async queryCount(selector) {
798
- const customMetadata = {
799
- "internal": false,
800
- "log": [],
801
- "method": "queryCount"
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])
802
755
  };
803
- const controller = new import_progress.ProgressController(customMetadata, this);
804
- const resultPromise = await controller.run(async (progress) => {
805
- progress.log("waiting for " + this._asLocator(selector));
806
- const promise = await this._retryWithProgressIfNotConnected(progress, selector, null, false, async (result) => {
807
- if (!result) return 0;
808
- const handle = result[0];
809
- const handles = result[1];
810
- return handle ? handles.length : 0;
811
- }, "returnAll");
812
- return promise;
813
- }, 1e4);
814
- 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);
815
774
  }
816
775
  async content() {
817
776
  try {
@@ -825,44 +784,26 @@ class Frame extends import_instrumentation.SdkObject {
825
784
  return retVal;
826
785
  });
827
786
  } catch (e) {
828
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_protocolError.isSessionClosedError)(e))
787
+ if (this.isNonRetriableError(e))
829
788
  throw e;
830
789
  throw new Error(`Unable to retrieve content because the page is navigating and changing the content.`);
831
790
  }
832
791
  }
833
- async setContent(metadata, html, options = {}) {
834
- const controller = new import_progress.ProgressController(metadata, this);
835
- return controller.run(async (progress) => {
836
- await this.raceNavigationAction(progress, options, async () => {
837
- const waitUntil = options.waitUntil === void 0 ? "load" : options.waitUntil;
838
- progress.log(`setting frame content, waiting until "${waitUntil}"`);
839
- const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
840
- const bindingName = "_tagDebug" + import_crypto.default.randomBytes(20).toString("hex");
841
- const context = await this._utilityContext();
842
- await this._page._delegate._mainFrameSession._client.send("Runtime.addBinding", { name: bindingName });
843
- const lifecyclePromise = new Promise(async (resolve, reject) => {
844
- await this._page.exposeBinding(bindingName, false, (tag2) => {
845
- this._onClearLifecycle();
846
- this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
847
- });
848
- });
849
- const contentPromise = context.evaluate(({ html: html2, tag: tag2, bindingName: bindingName2 }) => {
850
- document.open();
851
- var _tagDebug = window[bindingName2].bind({});
852
- delete window[bindingName2];
853
- _tagDebug('{ "name": "' + bindingName2 + '", "seq": 1, "serializedArgs": ["' + tag2 + '"] }');
854
- console.debug(tag2);
855
- document.write(html2);
856
- document.close();
857
- }, {
858
- html,
859
- tag,
860
- bindingName
861
- });
862
- await Promise.all([contentPromise, lifecyclePromise]);
863
- 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);
864
799
  });
865
- }, this._page._timeoutSettings.navigationTimeout(options));
800
+ const setContentPromise = this._page.delegate._mainFrameSession._client.send("Page.setDocumentContent", {
801
+ frameId: this._id,
802
+ html
803
+ });
804
+ await Promise.all([setContentPromise, lifecyclePromise]);
805
+ return null;
806
+ });
866
807
  }
867
808
  name() {
868
809
  return this._name || "";
@@ -894,7 +835,7 @@ class Frame extends import_instrumentation.SdkObject {
894
835
  if (url !== null)
895
836
  return (await context.evaluateHandle(addScriptUrl, { url, type })).asElement();
896
837
  const result = (await context.evaluateHandle(addScriptContent, { content, type })).asElement();
897
- if (this._page._delegate.cspErrorsAsynchronousForInlineScripts)
838
+ if (this._page.delegate.cspErrorsAsynchronousForInlineScripts)
898
839
  await context.evaluate(() => true);
899
840
  return result;
900
841
  });
@@ -968,7 +909,7 @@ class Frame extends import_instrumentation.SdkObject {
968
909
  let cspMessage;
969
910
  const actionPromise = func().then((r) => result = r).catch((e) => error = e);
970
911
  const errorPromise = new Promise((resolve) => {
971
- 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) => {
972
913
  if (message.page() !== this._page || message.type() !== "error")
973
914
  return;
974
915
  if (message.text().includes("Content-Security-Policy") || message.text().includes("Content Security Policy")) {
@@ -989,31 +930,30 @@ class Frame extends import_instrumentation.SdkObject {
989
930
  const continuePolling = Symbol("continuePolling");
990
931
  timeouts = [0, ...timeouts];
991
932
  let timeoutIndex = 0;
992
- while (progress.isRunning()) {
933
+ while (true) {
993
934
  const timeout = timeouts[Math.min(timeoutIndex++, timeouts.length - 1)];
994
935
  if (timeout) {
995
936
  const actionPromise = new Promise((f) => setTimeout(f, timeout));
996
- await import_utils.LongStandingScope.raceMultiple([
937
+ await progress.race(import_utils.LongStandingScope.raceMultiple([
997
938
  this._page.openScope,
998
939
  this._detachedScope
999
- ], actionPromise);
940
+ ], actionPromise));
1000
941
  }
1001
- progress.throwIfAborted();
1002
942
  try {
1003
943
  const result = await action(continuePolling);
1004
944
  if (result === continuePolling)
1005
945
  continue;
1006
946
  return result;
1007
947
  } catch (e) {
1008
- if (this._isErrorThatCannotBeRetried(e))
948
+ if (this.isNonRetriableError(e))
1009
949
  throw e;
1010
950
  continue;
1011
951
  }
1012
952
  }
1013
- progress.throwIfAborted();
1014
- return void 0;
1015
953
  }
1016
- _isErrorThatCannotBeRetried(e) {
954
+ isNonRetriableError(e) {
955
+ if ((0, import_progress.isAbortError)(e))
956
+ return true;
1017
957
  if (js.isJavaScriptErrorInEvaluate(e) || (0, import_protocolError.isSessionClosedError)(e))
1018
958
  return true;
1019
959
  if (dom.isNonRecoverableDOMError(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
@@ -1025,186 +965,115 @@ class Frame extends import_instrumentation.SdkObject {
1025
965
  async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action, returnAction) {
1026
966
  progress.log("waiting for " + this._asLocator(selector));
1027
967
  return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
1028
- if (performActionPreChecks) await this._page.performActionPreChecks(progress);
1029
- const resolved = await this.selectors.resolveInjectedForSelector(selector, {
1030
- strict
1031
- });
1032
- progress.throwIfAborted();
1033
- if (!resolved) {
1034
- if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1035
- const result2 = await action(null);
1036
- return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1037
- }
1038
- return continuePolling;
1039
- }
1040
- try {
1041
- var client = this._page._delegate._sessionForFrame(resolved.frame)._client;
1042
- } catch (e) {
1043
- var client = this._page._delegate._mainFrameSession._client;
1044
- }
1045
- var utilityContext = await resolved.frame._utilityContext();
1046
- var mainContext = await resolved.frame._mainContext();
1047
- const documentNode = await client.send("Runtime.evaluate", {
1048
- expression: "document",
1049
- serializationOptions: {
1050
- serialization: "idOnly"
1051
- },
1052
- contextId: utilityContext.delegate._contextId
1053
- });
1054
- const documentScope = new dom.ElementHandle(utilityContext, documentNode.result.objectId);
1055
- let currentScopingElements;
1056
- try {
1057
- currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext, documentScope, progress, resolved.info.parsed);
1058
- } catch (e) {
1059
- if ("JSHandles can be evaluated only in the context they were created!" === e.message) return continuePolling3;
1060
- await resolved.injected.evaluateHandle((injected, { error }) => {
1061
- throw error;
1062
- }, { error: e });
1063
- }
1064
- if (currentScopingElements.length == 0) {
1065
- if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1066
- const result2 = await action(null);
1067
- return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1068
- }
1069
- return continuePolling;
1070
- }
1071
- const resultElement = currentScopingElements[0];
1072
- if (currentScopingElements.length > 1) {
1073
- if (resolved.info.strict) {
1074
- await resolved.injected.evaluateHandle((injected, {
1075
- info,
1076
- elements
1077
- }) => {
1078
- throw injected.strictModeViolationError(info.parsed, elements);
1079
- }, {
1080
- info: resolved.info,
1081
- elements: currentScopingElements
1082
- });
1083
- }
1084
- progress.log(" locator resolved to " + currentScopingElements.length + " elements. Proceeding with the first one: " + resultElement.preview());
1085
- } else if (resultElement) {
1086
- progress.log(" locator resolved to " + resultElement.preview());
1087
- }
1088
- try {
1089
- var result = null;
1090
- if (returnAction === "returnAll") {
1091
- result = await action([resultElement, currentScopingElements]);
1092
- } else {
1093
- result = await action(resultElement);
1094
- }
1095
- if (result === "error:notconnected") {
1096
- progress.log("element was detached from the DOM, retrying");
1097
- return continuePolling;
1098
- } else if (result === "internal:continuepolling") {
1099
- return continuePolling;
1100
- }
1101
- return result;
1102
- } finally {
1103
- }
968
+ return this._retryWithoutProgress(progress, selector, strict, performActionPreChecks, action, returnAction, continuePolling);
1104
969
  });
1105
970
  }
1106
971
  async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
1107
972
  return await this._retryWithProgressIfNotConnected(progress, selector, true, true, async (handle) => {
1108
- await handle._frame.rafrafTimeout(timeout);
1109
- 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);
1110
975
  });
1111
976
  }
1112
- async click(metadata, selector, options) {
1113
- const controller = new import_progress.ProgressController(metadata, this);
1114
- return controller.run(async (progress) => {
1115
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
1116
- }, this._page._timeoutSettings.timeout(options));
1117
- }
1118
- async dblclick(metadata, selector, options = {}) {
1119
- const controller = new import_progress.ProgressController(metadata, this);
1120
- return controller.run(async (progress) => {
1121
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._dblclick(progress, options)));
1122
- }, this._page._timeoutSettings.timeout(options));
1123
- }
1124
- async dragAndDrop(metadata, source, target, options = {}) {
1125
- const controller = new import_progress.ProgressController(metadata, this);
1126
- await controller.run(async (progress) => {
1127
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force, async (handle) => {
1128
- return handle._retryPointerAction(progress, "move and down", false, async (point) => {
1129
- await this._page.mouse.move(point.x, point.y);
1130
- await this._page.mouse.down();
1131
- }, {
1132
- ...options,
1133
- waitAfter: "disabled",
1134
- position: options.sourcePosition,
1135
- timeout: progress.timeUntilDeadline()
1136
- });
1137
- }));
1138
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
1139
- return handle._retryPointerAction(progress, "move and up", false, async (point) => {
1140
- await this._page.mouse.move(point.x, point.y);
1141
- await this._page.mouse.up();
1142
- }, {
1143
- ...options,
1144
- waitAfter: "disabled",
1145
- position: options.targetPosition,
1146
- timeout: progress.timeUntilDeadline()
1147
- });
1148
- }));
1149
- }, 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
+ }));
1150
1004
  }
1151
- async tap(metadata, selector, options) {
1152
- if (!this._page._browserContext._options.hasTouch)
1005
+ async tap(progress, selector, options) {
1006
+ if (!this._page.browserContext._options.hasTouch)
1153
1007
  throw new Error("The page does not support tap. Use hasTouch context option to enable touch support.");
1154
- const controller = new import_progress.ProgressController(metadata, this);
1155
- return controller.run(async (progress) => {
1156
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._tap(progress, options)));
1157
- }, this._page._timeoutSettings.timeout(options));
1158
- }
1159
- async fill(metadata, selector, value, options) {
1160
- const controller = new import_progress.ProgressController(metadata, this);
1161
- return controller.run(async (progress) => {
1162
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._fill(progress, value, options)));
1163
- }, this._page._timeoutSettings.timeout(options));
1164
- }
1165
- async focus(metadata, selector, options = {}) {
1166
- const controller = new import_progress.ProgressController(metadata, this);
1167
- await controller.run(async (progress) => {
1168
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._focus(progress)));
1169
- }, this._page._timeoutSettings.timeout(options));
1170
- }
1171
- async blur(metadata, selector, options = {}) {
1172
- const controller = new import_progress.ProgressController(metadata, this);
1173
- await controller.run(async (progress) => {
1174
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
1175
- }, this._page._timeoutSettings.timeout(options));
1176
- }
1177
- async textContent(metadata, selector, options = {}, scope) {
1178
- return this._callOnElementOnceMatches(metadata, selector, (injected, element) => element.textContent, void 0, options, scope);
1179
- }
1180
- async innerText(metadata, selector, options = {}, scope) {
1181
- 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) => {
1182
1051
  if (element.namespaceURI !== "http://www.w3.org/1999/xhtml")
1183
1052
  throw injectedScript.createStacklessError("Node is not an HTMLElement");
1184
1053
  return element.innerText;
1185
1054
  }, void 0, options, scope);
1186
1055
  }
1187
- async innerHTML(metadata, selector, options = {}, scope) {
1188
- 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);
1189
1058
  }
1190
- async getAttribute(metadata, selector, name, options = {}, scope) {
1191
- 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);
1192
1061
  }
1193
- async inputValue(metadata, selector, options = {}, scope) {
1194
- return this._callOnElementOnceMatches(metadata, selector, (injectedScript, node) => {
1062
+ async inputValue(progress, selector, options, scope) {
1063
+ return this._callOnElementOnceMatches(progress, selector, (injectedScript, node) => {
1195
1064
  const element = injectedScript.retarget(node, "follow-label");
1196
1065
  if (!element || element.nodeName !== "INPUT" && element.nodeName !== "TEXTAREA" && element.nodeName !== "SELECT")
1197
1066
  throw injectedScript.createStacklessError("Node is not an <input>, <textarea> or <select> element");
1198
1067
  return element.value;
1199
1068
  }, void 0, options, scope);
1200
1069
  }
1201
- async highlight(selector) {
1202
- const resolved = await this.selectors.resolveInjectedForSelector(selector);
1070
+ async highlight(progress, selector) {
1071
+ const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector));
1203
1072
  if (!resolved)
1204
1073
  return;
1205
- return await resolved.injected.evaluate((injected, { info }) => {
1074
+ return await progress.race(resolved.injected.evaluate((injected, { info }) => {
1206
1075
  return injected.highlight(info.parsed);
1207
- }, { info: resolved.info });
1076
+ }, { info: resolved.info }));
1208
1077
  }
1209
1078
  async hideHighlight() {
1210
1079
  return this.raceAgainstEvaluationStallingEvents(async () => {
@@ -1215,28 +1084,48 @@ class Frame extends import_instrumentation.SdkObject {
1215
1084
  });
1216
1085
  });
1217
1086
  }
1218
- async _elementState(metadata, selector, state, options = {}, scope) {
1219
- 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) => {
1220
1089
  return injected.elementState(element, data.state);
1221
1090
  }, { state }, options, scope);
1222
1091
  if (result.received === "error:notconnected")
1223
1092
  dom.throwElementIsNotAttached();
1224
1093
  return result.matches;
1225
1094
  }
1226
- async isVisible(metadata, selector, options = {}, scope) {
1227
- const controller = new import_progress.ProgressController(metadata, this);
1228
- return controller.run(async (progress) => {
1229
- progress.log(` checking visibility of ${this._asLocator(selector)}`);
1230
- return await this.isVisibleInternal(selector, options, scope);
1231
- }, 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);
1232
1098
  }
1233
- async isVisibleInternal(selector, options = {}, scope) {
1099
+ async isVisibleInternal(progress, selector, options = {}, scope) {
1234
1100
  try {
1235
- const customMetadata = { "internal": false, "log": [], "method": "isVisible" };
1236
- const controller = new import_progress.ProgressController(customMetadata, this);
1237
- return await controller.run(async (progress) => {
1238
- progress.log("waiting for " + this._asLocator(selector));
1239
- 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) => {
1240
1129
  if (!handle) return false;
1241
1130
  if (handle.parentNode.constructor.name == "ElementHandle") {
1242
1131
  return await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
@@ -1255,242 +1144,215 @@ class Frame extends import_instrumentation.SdkObject {
1255
1144
  return state.matches;
1256
1145
  }, { handle });
1257
1146
  }
1258
- }, "returnOnNotResolved");
1259
- return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1260
- }, 1e4) || false;
1147
+ }, "returnOnNotResolved", null);
1148
+ }
1261
1149
  } catch (e) {
1262
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e) || (0, import_protocolError.isSessionClosedError)(e)) throw e;
1150
+ if (this.isNonRetriableError(e)) throw e;
1263
1151
  return false;
1264
1152
  }
1265
1153
  }
1266
- async isHidden(metadata, selector, options = {}, scope) {
1267
- return !await this.isVisible(metadata, selector, options, scope);
1154
+ async isHidden(progress, selector, options = {}, scope) {
1155
+ return !await this.isVisible(progress, selector, options, scope);
1268
1156
  }
1269
- async isDisabled(metadata, selector, options = {}, scope) {
1270
- return this._elementState(metadata, selector, "disabled", options, scope);
1157
+ async isDisabled(progress, selector, options, scope) {
1158
+ return this._elementState(progress, selector, "disabled", options, scope);
1271
1159
  }
1272
- async isEnabled(metadata, selector, options = {}, scope) {
1273
- return this._elementState(metadata, selector, "enabled", options, scope);
1160
+ async isEnabled(progress, selector, options, scope) {
1161
+ return this._elementState(progress, selector, "enabled", options, scope);
1274
1162
  }
1275
- async isEditable(metadata, selector, options = {}, scope) {
1276
- return this._elementState(metadata, selector, "editable", options, scope);
1163
+ async isEditable(progress, selector, options, scope) {
1164
+ return this._elementState(progress, selector, "editable", options, scope);
1277
1165
  }
1278
- async isChecked(metadata, selector, options = {}, scope) {
1279
- return this._elementState(metadata, selector, "checked", options, scope);
1166
+ async isChecked(progress, selector, options, scope) {
1167
+ return this._elementState(progress, selector, "checked", options, scope);
1280
1168
  }
1281
- async hover(metadata, selector, options = {}) {
1282
- const controller = new import_progress.ProgressController(metadata, this);
1283
- return controller.run(async (progress) => {
1284
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._hover(progress, options)));
1285
- }, 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)));
1286
1171
  }
1287
- async selectOption(metadata, selector, elements, values, options = {}) {
1288
- const controller = new import_progress.ProgressController(metadata, this);
1289
- return controller.run(async (progress) => {
1290
- return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._selectOption(progress, elements, values, options));
1291
- }, 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));
1292
1174
  }
1293
- async setInputFiles(metadata, selector, params) {
1175
+ async setInputFiles(progress, selector, params) {
1294
1176
  const inputFileItems = await (0, import_fileUploadUtils.prepareFilesForUpload)(this, params);
1295
- const controller = new import_progress.ProgressController(metadata, this);
1296
- return controller.run(async (progress) => {
1297
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
1298
- }, this._page._timeoutSettings.timeout(params));
1299
- }
1300
- async type(metadata, selector, text, options = {}) {
1301
- const controller = new import_progress.ProgressController(metadata, this);
1302
- return controller.run(async (progress) => {
1303
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._type(progress, text, options)));
1304
- }, this._page._timeoutSettings.timeout(options));
1305
- }
1306
- async press(metadata, selector, key, options = {}) {
1307
- const controller = new import_progress.ProgressController(metadata, this);
1308
- return controller.run(async (progress) => {
1309
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._press(progress, key, options)));
1310
- }, this._page._timeoutSettings.timeout(options));
1311
- }
1312
- async check(metadata, selector, options = {}) {
1313
- const controller = new import_progress.ProgressController(metadata, this);
1314
- return controller.run(async (progress) => {
1315
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, true, options)));
1316
- }, this._page._timeoutSettings.timeout(options));
1317
- }
1318
- async uncheck(metadata, selector, options = {}) {
1319
- const controller = new import_progress.ProgressController(metadata, this);
1320
- return controller.run(async (progress) => {
1321
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, false, options)));
1322
- }, this._page._timeoutSettings.timeout(options));
1323
- }
1324
- async waitForTimeout(metadata, timeout) {
1325
- const controller = new import_progress.ProgressController(metadata, this);
1326
- return controller.run(async () => {
1327
- await new Promise((resolve) => setTimeout(resolve, timeout));
1328
- });
1177
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
1329
1178
  }
1330
- async ariaSnapshot(metadata, selector, options = {}) {
1331
- const controller = new import_progress.ProgressController(metadata, this);
1332
- return controller.run(async (progress) => {
1333
- return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => handle.ariaSnapshot(options));
1334
- }, 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)));
1335
1181
  }
1336
- async expect(metadata, selector, options) {
1337
- const result = await this._expectImpl(metadata, selector, options);
1338
- if (result.matches === options.isNot)
1339
- metadata.error = { error: { name: "Expect", message: "Expect failed" } };
1340
- 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)));
1341
1190
  }
1342
- async _expectImpl(metadata, selector, options) {
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()));
1196
+ }
1197
+ async expect(progress, selector, options, timeout) {
1198
+ progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${timeout ? ` with timeout ${timeout}ms` : ""}`);
1343
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
+ };
1344
1204
  try {
1345
- let timeout = this._page._timeoutSettings.timeout(options);
1346
- const start = timeout > 0 ? (0, import_utils.monotonicTime)() : 0;
1347
- await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1348
- progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ""}`);
1205
+ if (selector)
1349
1206
  progress.log(`waiting for ${this._asLocator(selector)}`);
1350
- await this._page.performActionPreChecks(progress);
1351
- }, timeout);
1207
+ await this._page.performActionPreChecks(progress);
1352
1208
  try {
1353
- const resultOneShot = await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1354
- return await this._expectInternal(progress, selector, options, lastIntermediateResult);
1355
- });
1209
+ const resultOneShot = await this._expectInternal(progress, selector, options, lastIntermediateResult, true);
1356
1210
  if (resultOneShot.matches !== options.isNot)
1357
1211
  return resultOneShot;
1358
1212
  } catch (e) {
1359
- if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
1213
+ if (this.isNonRetriableError(e))
1360
1214
  throw e;
1361
1215
  }
1362
- if (timeout > 0) {
1363
- const elapsed = (0, import_utils.monotonicTime)() - start;
1364
- timeout -= elapsed;
1365
- }
1366
- if (timeout < 0)
1367
- return { matches: options.isNot, log: (0, import_callLog.compressCallLog)(metadata.log), timedOut: true, received: lastIntermediateResult.received };
1368
- return await new import_progress.ProgressController(metadata, this).run(async (progress) => {
1369
- return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling) => {
1370
- await this._page.performActionPreChecks(progress);
1371
- const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult);
1372
- if (matches === options.isNot) {
1373
- return continuePolling;
1374
- }
1375
- return { matches, received };
1376
- });
1377
- }, 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;
1378
1226
  } catch (e) {
1379
1227
  if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
1380
1228
  throw e;
1381
- 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) };
1382
1230
  if (lastIntermediateResult.isSet)
1383
1231
  result.received = lastIntermediateResult.received;
1384
1232
  if (e instanceof import_errors.TimeoutError)
1385
1233
  result.timedOut = true;
1234
+ fixupMetadataError(result);
1386
1235
  return result;
1387
1236
  }
1388
1237
  }
1389
- async _expectInternal(progress, selector, options, lastIntermediateResult) {
1390
- progress.log("waiting for " + this._asLocator(selector));
1238
+ async _expectInternal(progress, selector, options, lastIntermediateResult, noAbort) {
1239
+ const race = (p) => noAbort ? p : progress.race(p);
1391
1240
  const isArray = options.expression === "to.have.count" || options.expression.endsWith(".array");
1392
- const promise = await this._retryWithProgressIfNotConnected(progress, selector, !isArray, false, async (result) => {
1393
- if (!result) {
1394
- if (options.expectedNumber === 0)
1395
- return { matches: true };
1396
- if (!options.isNot && options.expression === "to.be.hidden")
1397
- return { matches: true };
1398
- if (options.isNot && options.expression === "to.be.visible")
1399
- return { matches: false };
1400
- if (!options.isNot && options.expression === "to.be.detached")
1401
- return { matches: true };
1402
- if (options.isNot && options.expression === "to.be.attached")
1403
- return { matches: false };
1404
- if (options.isNot && options.expression === "to.be.in.viewport")
1405
- return { matches: false };
1406
- return { matches: options.isNot, missingReceived: true };
1407
- }
1408
- const handle = result[0];
1409
- const handles = result[1];
1410
- if (handle.parentNode.constructor.name == "ElementHandle") {
1411
- return await handle.parentNode.evaluateInUtility(async ([injected, node, { handle: handle2, options: options2, handles: handles2 }]) => {
1412
- return await injected.expect(handle2, options2, handles2);
1413
- }, { 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);
1414
1274
  } else {
1415
- return await handle.parentNode.evaluate(async (injected, { handle: handle2, options: options2, handles: handles2 }) => {
1416
- return await injected.expect(handle2, options2, handles2);
1417
- }, { handle, options, handles });
1275
+ var { log, matches, received, missingReceived } = await race(this._retryWithProgressIfNotConnected(progress, selector, !isArray, false, action, "returnAll"));
1418
1276
  }
1419
- }, "returnAll");
1420
- var matches = false;
1421
- var received = 0;
1422
- var missingReceived = null;
1423
- if (promise) {
1424
- matches = promise.matches;
1425
- received = promise.received;
1426
- missingReceived = promise.missingReceived;
1427
- } else if (options.expectedNumber === 0) {
1428
- 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 }));
1429
1284
  }
1285
+ if (log)
1286
+ progress.log(log);
1430
1287
  if (matches === options.isNot) {
1431
1288
  lastIntermediateResult.received = missingReceived ? "<element(s) not found>" : received;
1432
1289
  lastIntermediateResult.isSet = true;
1433
- 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)}"`);
1434
1292
  }
1435
- return {
1436
- matches,
1437
- received
1438
- };
1293
+ return { matches, received };
1439
1294
  }
1440
- async _waitForFunctionExpression(metadata, expression, isFunction, arg, options, world = "main") {
1441
- const controller = new import_progress.ProgressController(metadata, this);
1295
+ async waitForFunctionExpression(progress, expression, isFunction, arg, options, world = "main") {
1442
1296
  if (typeof options.pollingInterval === "number")
1443
1297
  (0, import_utils.assert)(options.pollingInterval > 0, "Cannot poll with non-positive interval: " + options.pollingInterval);
1444
1298
  expression = js.normalizeEvaluationExpression(expression, isFunction);
1445
- return controller.run(async (progress) => {
1446
- return this.retryWithProgressAndTimeouts(progress, [100], async () => {
1447
- const context = world === "main" ? await this._mainContext() : await this._utilityContext();
1448
- const injectedScript = await context.injectedScript();
1449
- const handle = await injectedScript.evaluateHandle((injected, { expression: expression2, isFunction: isFunction2, polling, arg: arg2 }) => {
1450
- const predicate = () => {
1451
- let result2 = globalThis.eval(expression2);
1452
- 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;
1453
1314
  result2 = result2(arg2);
1454
- } else if (isFunction2 === false) {
1455
- result2 = result2;
1456
- } else {
1457
- if (typeof result2 === "function")
1458
- result2 = result2(arg2);
1459
1315
  }
1460
- return result2;
1461
- };
1462
- let fulfill;
1463
- let reject;
1464
- let aborted = false;
1465
- const result = new Promise((f, r) => {
1466
- fulfill = f;
1467
- reject = r;
1468
- });
1469
- const next = () => {
1470
- 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);
1471
1333
  return;
1472
- try {
1473
- const success = predicate();
1474
- if (success) {
1475
- fulfill(success);
1476
- return;
1477
- }
1478
- if (typeof polling !== "number")
1479
- injected.utils.builtins.requestAnimationFrame(next);
1480
- else
1481
- injected.utils.builtins.setTimeout(next, polling);
1482
- } catch (e) {
1483
- reject(e);
1484
1334
  }
1485
- };
1486
- next();
1487
- return { result, abort: () => aborted = true };
1488
- }, { expression, isFunction, polling: options.pollingInterval, arg });
1489
- progress.cleanupWhenAborted(() => handle.evaluate((h) => h.abort()).catch(() => {
1490
- }));
1491
- return handle.evaluateHandle((h) => h.result);
1492
- });
1493
- }, 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
+ });
1494
1356
  }
1495
1357
  async waitForFunctionValueInUtility(progress, pageFunction) {
1496
1358
  const expression = `() => {
@@ -1499,25 +1361,25 @@ class Frame extends import_instrumentation.SdkObject {
1499
1361
  return result;
1500
1362
  return JSON.stringify(result);
1501
1363
  }`;
1502
- 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");
1503
1365
  return JSON.parse(handle.rawValue());
1504
1366
  }
1505
1367
  async title() {
1506
1368
  const context = await this._utilityContext();
1507
1369
  return context.evaluate(() => document.title);
1508
1370
  }
1509
- async rafrafTimeout(timeout) {
1371
+ async rafrafTimeout(progress, timeout) {
1510
1372
  if (timeout === 0)
1511
1373
  return;
1512
- const context = await this._utilityContext();
1374
+ const context = await progress.race(this._utilityContext());
1513
1375
  await Promise.all([
1514
1376
  // wait for double raf
1515
- context.evaluate(() => new Promise((x) => {
1377
+ progress.race(context.evaluate(() => new Promise((x) => {
1516
1378
  requestAnimationFrame(() => {
1517
1379
  requestAnimationFrame(x);
1518
1380
  });
1519
- })),
1520
- new Promise((fulfill) => setTimeout(fulfill, timeout))
1381
+ }))),
1382
+ progress.wait(timeout)
1521
1383
  ]);
1522
1384
  }
1523
1385
  _onDetached() {
@@ -1532,16 +1394,39 @@ class Frame extends import_instrumentation.SdkObject {
1532
1394
  this._parentFrame._childFrames.delete(this);
1533
1395
  this._parentFrame = null;
1534
1396
  }
1535
- async _callOnElementOnceMatches(metadata, selector, body, taskData, options = {}, scope) {
1397
+ async _callOnElementOnceMatches(progress, selector, body, taskData, options, scope) {
1536
1398
  const callbackText = body.toString();
1537
- const controller = new import_progress.ProgressController(metadata, this);
1538
- return controller.run(async (progress) => {
1539
- progress.log("waiting for " + this._asLocator(selector));
1540
- const promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, 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) => {
1541
1425
  if (handle.parentNode.constructor.name == "ElementHandle") {
1542
1426
  return await handle.parentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, handle: handle2, taskData: taskData2 }]) => {
1543
1427
  const callback = injected.eval(callbackText2);
1544
- return callback(injected, handle2, taskData2);
1428
+ const haha = callback(injected, handle2, taskData2);
1429
+ return haha;
1545
1430
  }, {
1546
1431
  callbackText,
1547
1432
  handle,
@@ -1558,8 +1443,8 @@ class Frame extends import_instrumentation.SdkObject {
1558
1443
  });
1559
1444
  }
1560
1445
  });
1561
- return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1562
- }, this._page._timeoutSettings.timeout(options));
1446
+ }
1447
+ return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
1563
1448
  }
1564
1449
  _setContext(world, context) {
1565
1450
  const data = this._contextData.get(world);
@@ -1604,35 +1489,12 @@ class Frame extends import_instrumentation.SdkObject {
1604
1489
  async extendInjectedScript(source, arg) {
1605
1490
  const context = await this._context("main");
1606
1491
  const injectedScriptHandle = await context.injectedScript();
1607
- return injectedScriptHandle.evaluateHandle((injectedScript, { source: source2, arg: arg2 }) => {
1608
- return injectedScript.extend(source2, arg2);
1492
+ await injectedScriptHandle.evaluate((injectedScript, { source: source2, arg: arg2 }) => {
1493
+ injectedScript.extend(source2, arg2);
1609
1494
  }, { source, arg });
1610
1495
  }
1611
- async resetStorageForCurrentOriginBestEffort(newStorage) {
1612
- const context = await this._utilityContext();
1613
- await context.evaluate(async ({ ls }) => {
1614
- sessionStorage.clear();
1615
- localStorage.clear();
1616
- for (const entry of ls || [])
1617
- localStorage[entry.name] = entry.value;
1618
- const registrations = navigator.serviceWorker ? await navigator.serviceWorker.getRegistrations() : [];
1619
- await Promise.all(registrations.map(async (r) => {
1620
- if (!r.installing && !r.waiting && !r.active)
1621
- r.unregister().catch(() => {
1622
- });
1623
- else
1624
- await r.unregister().catch(() => {
1625
- });
1626
- }));
1627
- for (const db of await indexedDB.databases?.() || []) {
1628
- if (db.name)
1629
- indexedDB.deleteDatabase(db.name);
1630
- }
1631
- }, { ls: newStorage?.localStorage }).catch(() => {
1632
- });
1633
- }
1634
1496
  _asLocator(selector) {
1635
- return (0, import_utils.asLocator)(this._page.attribution.playwright.options.sdkLanguage, selector);
1497
+ return (0, import_utils.asLocator)(this._page.browserContext._browser.sdkLanguage(), selector);
1636
1498
  }
1637
1499
  async _getFrameMainFrameContextId(client) {
1638
1500
  try {
@@ -1653,6 +1515,82 @@ class Frame extends import_instrumentation.SdkObject {
1653
1515
  }
1654
1516
  return 0;
1655
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
+ }
1656
1594
  async _customFindElementsByParsed(resolved, client, context, documentScope, progress, parsed) {
1657
1595
  var parsedEdits = { ...parsed };
1658
1596
  var currentScopingElements = [documentScope];
@@ -1663,6 +1601,7 @@ class Frame extends import_instrumentation.SdkObject {
1663
1601
  var elementsIndexes = [];
1664
1602
  if (part.name == "nth") {
1665
1603
  const partNth = Number(part.body);
1604
+ if (currentScopingElements.length == 0) return [];
1666
1605
  if (partNth > currentScopingElements.length - 1 || partNth < -(currentScopingElements.length - 1)) {
1667
1606
  throw new Error("Can't query n-th element");
1668
1607
  } else {
@@ -1784,26 +1723,27 @@ class SignalBarrier {
1784
1723
  }
1785
1724
  waitFor() {
1786
1725
  this.release();
1787
- return this._promise;
1726
+ return this._progress.race(this._promise);
1788
1727
  }
1789
- async addFrameNavigation(frame) {
1728
+ addFrameNavigation(frame) {
1790
1729
  if (frame.parentFrame())
1791
1730
  return;
1792
1731
  this.retain();
1793
- 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) => {
1794
1733
  if (!e.isPublic)
1795
1734
  return false;
1796
1735
  if (!e.error && this._progress)
1797
1736
  this._progress.log(` navigated to "${frame._url}"`);
1798
1737
  return true;
1799
1738
  });
1800
- await import_utils.LongStandingScope.raceMultiple([
1739
+ import_utils.LongStandingScope.raceMultiple([
1801
1740
  frame._page.openScope,
1802
1741
  frame._detachedScope
1803
1742
  ], waiter.promise).catch(() => {
1743
+ }).finally(() => {
1744
+ waiter.dispose();
1745
+ this.release();
1804
1746
  });
1805
- waiter.dispose();
1806
- this.release();
1807
1747
  }
1808
1748
  retain() {
1809
1749
  ++this._protectCount;