patchright-core 1.56.1 → 1.58.2

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 (180) hide show
  1. package/ThirdPartyNotices.txt +3134 -560
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +21 -22
  4. package/lib/cli/program.js +16 -60
  5. package/lib/client/api.js +3 -3
  6. package/lib/client/browser.js +3 -5
  7. package/lib/client/browserContext.js +62 -8
  8. package/lib/client/browserType.js +4 -3
  9. package/lib/client/connection.js +4 -0
  10. package/lib/client/consoleMessage.js +5 -1
  11. package/lib/client/electron.js +1 -1
  12. package/lib/client/elementHandle.js +3 -0
  13. package/lib/client/events.js +5 -1
  14. package/lib/client/fetch.js +3 -4
  15. package/lib/client/frame.js +10 -1
  16. package/lib/client/locator.js +12 -1
  17. package/lib/client/network.js +5 -1
  18. package/lib/client/page.js +31 -6
  19. package/lib/client/pageAgent.js +64 -0
  20. package/lib/client/platform.js +3 -0
  21. package/lib/client/playwright.js +1 -5
  22. package/lib/client/tracing.js +7 -5
  23. package/lib/client/worker.js +22 -0
  24. package/lib/generated/clockSource.js +1 -1
  25. package/lib/generated/injectedScriptSource.js +1 -1
  26. package/lib/generated/pollingRecorderSource.js +1 -1
  27. package/lib/inProcessFactory.js +0 -2
  28. package/lib/mcpBundle.js +84 -0
  29. package/lib/mcpBundleImpl/index.js +147 -0
  30. package/lib/protocol/serializers.js +5 -0
  31. package/lib/protocol/validator.js +112 -50
  32. package/lib/remote/playwrightServer.js +1 -2
  33. package/lib/server/agent/actionRunner.js +335 -0
  34. package/lib/server/agent/actions.js +128 -0
  35. package/lib/server/agent/codegen.js +111 -0
  36. package/lib/server/agent/context.js +150 -0
  37. package/lib/server/agent/expectTools.js +156 -0
  38. package/lib/server/agent/pageAgent.js +204 -0
  39. package/lib/server/agent/performTools.js +262 -0
  40. package/lib/server/agent/tool.js +109 -0
  41. package/lib/server/android/android.js +1 -1
  42. package/lib/server/artifact.js +1 -1
  43. package/lib/server/bidi/bidiBrowser.js +81 -22
  44. package/lib/server/bidi/bidiChromium.js +9 -13
  45. package/lib/server/bidi/bidiConnection.js +1 -0
  46. package/lib/server/bidi/bidiDeserializer.js +116 -0
  47. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  48. package/lib/server/bidi/bidiFirefox.js +7 -9
  49. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  50. package/lib/server/bidi/bidiPage.js +61 -30
  51. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  52. package/lib/server/browserContext.js +43 -36
  53. package/lib/server/browserType.js +12 -4
  54. package/lib/server/chromium/chromium.js +26 -21
  55. package/lib/server/chromium/chromiumSwitches.js +12 -3
  56. package/lib/server/chromium/crBrowser.js +30 -12
  57. package/lib/server/chromium/crConnection.js +0 -5
  58. package/lib/server/chromium/crCoverage.js +13 -1
  59. package/lib/server/chromium/crDevTools.js +0 -2
  60. package/lib/server/chromium/crNetworkManager.js +107 -18
  61. package/lib/server/chromium/crPage.js +68 -124
  62. package/lib/server/chromium/crServiceWorker.js +14 -1
  63. package/lib/server/codegen/javascript.js +6 -29
  64. package/lib/server/console.js +5 -1
  65. package/lib/server/deviceDescriptorsSource.json +56 -56
  66. package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
  67. package/lib/server/dispatchers/dispatcher.js +6 -13
  68. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  69. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  70. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  71. package/lib/server/dispatchers/pageDispatcher.js +14 -22
  72. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  73. package/lib/server/dom.js +12 -3
  74. package/lib/server/electron/electron.js +6 -3
  75. package/lib/server/firefox/ffBrowser.js +10 -20
  76. package/lib/server/firefox/ffConnection.js +0 -5
  77. package/lib/server/firefox/ffNetworkManager.js +2 -2
  78. package/lib/server/firefox/ffPage.js +18 -24
  79. package/lib/server/firefox/firefox.js +18 -9
  80. package/lib/server/frameSelectors.js +18 -8
  81. package/lib/server/frames.js +257 -87
  82. package/lib/server/input.js +7 -3
  83. package/lib/server/instrumentation.js +3 -0
  84. package/lib/server/javascript.js +8 -4
  85. package/lib/server/launchApp.js +2 -1
  86. package/lib/server/localUtils.js +4 -8
  87. package/lib/server/network.js +50 -12
  88. package/lib/server/page.js +112 -126
  89. package/lib/server/playwright.js +2 -4
  90. package/lib/server/progress.js +26 -6
  91. package/lib/server/recorder/recorderApp.js +80 -101
  92. package/lib/server/recorder.js +3 -2
  93. package/lib/server/registry/browserFetcher.js +6 -4
  94. package/lib/server/registry/index.js +278 -189
  95. package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
  96. package/lib/server/screencast.js +190 -0
  97. package/lib/server/screenshotter.js +6 -0
  98. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  99. package/lib/server/trace/recorder/snapshotter.js +17 -8
  100. package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
  101. package/lib/server/trace/recorder/tracing.js +31 -21
  102. package/lib/server/trace/viewer/traceParser.js +72 -0
  103. package/lib/server/trace/viewer/traceViewer.js +45 -40
  104. package/lib/server/utils/comparators.js +3 -25
  105. package/lib/server/utils/expectUtils.js +87 -2
  106. package/lib/server/utils/hostPlatform.js +30 -3
  107. package/lib/server/utils/httpServer.js +5 -20
  108. package/lib/server/utils/imageUtils.js +141 -0
  109. package/lib/server/utils/network.js +55 -40
  110. package/lib/server/utils/nodePlatform.js +6 -0
  111. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
  112. package/lib/server/webkit/webkit.js +5 -16
  113. package/lib/server/webkit/wkBrowser.js +2 -6
  114. package/lib/server/webkit/wkConnection.js +1 -6
  115. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  116. package/lib/server/webkit/wkPage.js +76 -51
  117. package/lib/server/webkit/wkWorkers.js +2 -1
  118. package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
  119. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  120. package/lib/utils/isomorphic/lruCache.js +51 -0
  121. package/lib/utils/isomorphic/mimeType.js +1 -1
  122. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  123. package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
  124. package/lib/utils/isomorphic/stringUtils.js +49 -0
  125. package/lib/utils/isomorphic/trace/entries.js +16 -0
  126. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  127. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  128. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  129. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  130. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  131. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  132. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  133. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  134. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  135. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  136. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  137. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  138. package/lib/utils/isomorphic/urlMatch.js +19 -5
  139. package/lib/utils/isomorphic/yaml.js +84 -0
  140. package/lib/utils.js +4 -0
  141. package/lib/utilsBundle.js +1 -1
  142. package/lib/utilsBundleImpl/index.js +124 -124
  143. package/lib/vite/htmlReport/index.html +21 -21
  144. package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
  145. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  146. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  147. package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
  148. package/lib/vite/recorder/index.html +2 -2
  149. package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
  150. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
  151. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  152. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  153. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  154. package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
  155. package/lib/vite/traceViewer/index.html +6 -6
  156. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  157. package/lib/vite/traceViewer/snapshot.html +3 -3
  158. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  159. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
  160. package/lib/vite/traceViewer/uiMode.html +3 -3
  161. package/package.json +2 -1
  162. package/types/protocol.d.ts +939 -245
  163. package/types/types.d.ts +143 -153
  164. package/lib/client/accessibility.js +0 -49
  165. package/lib/server/accessibility.js +0 -69
  166. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  167. package/lib/server/chromium/crAccessibility.js +0 -263
  168. package/lib/server/firefox/ffAccessibility.js +0 -238
  169. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  170. package/lib/server/webkit/wkAccessibility.js +0 -237
  171. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  172. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  173. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  174. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
  175. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  176. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  177. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  178. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  179. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
  180. package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
@@ -67,9 +67,13 @@ class FrameManager {
67
67
  this._consoleMessageTags = /* @__PURE__ */ new Map();
68
68
  this._signalBarriers = /* @__PURE__ */ new Set();
69
69
  this._webSockets = /* @__PURE__ */ new Map();
70
+ this._nextFrameSeq = 0;
70
71
  this._page = page;
71
72
  this._mainFrame = void 0;
72
73
  }
74
+ nextFrameSeq() {
75
+ return this._nextFrameSeq++;
76
+ }
73
77
  createDummyMainFrameIfNeeded() {
74
78
  if (!this._mainFrame)
75
79
  this.frameAttached(kDummyFrameId, null);
@@ -173,6 +177,9 @@ class FrameManager {
173
177
  } else {
174
178
  frame._currentDocument = { documentId, request: void 0 };
175
179
  }
180
+ frame._iframeWorld = void 0;
181
+ frame._mainWorld = void 0;
182
+ frame._isolatedWorld = void 0;
176
183
  frame._onClearLifecycle();
177
184
  const navigationEvent = { url, name, newDocument: frame._currentDocument, isPublic: true };
178
185
  this._fireInternalFrameNavigation(frame, navigationEvent);
@@ -348,6 +355,11 @@ class FrameManager {
348
355
  frame.emit(Frame.Events.InternalNavigation, event);
349
356
  }
350
357
  }
358
+ const FrameEvent = {
359
+ InternalNavigation: "internalnavigation",
360
+ AddLifecycle: "addlifecycle",
361
+ RemoveLifecycle: "removelifecycle"
362
+ };
351
363
  class Frame extends import_instrumentation.SdkObject {
352
364
  constructor(page, id, parentFrame) {
353
365
  super(page, "frame");
@@ -363,6 +375,7 @@ class Frame extends import_instrumentation.SdkObject {
363
375
  this._raceAgainstEvaluationStallingEventsPromises = /* @__PURE__ */ new Set();
364
376
  this._redirectedNavigations = /* @__PURE__ */ new Map();
365
377
  this.attribution.frame = this;
378
+ this.seq = page.frameManager.nextFrameSeq();
366
379
  this._id = id;
367
380
  this._page = page;
368
381
  this._parentFrame = parentFrame;
@@ -379,11 +392,7 @@ class Frame extends import_instrumentation.SdkObject {
379
392
  this._startNetworkIdleTimer();
380
393
  }
381
394
  static {
382
- this.Events = {
383
- InternalNavigation: "internalnavigation",
384
- AddLifecycle: "addlifecycle",
385
- RemoveLifecycle: "removelifecycle"
386
- };
395
+ this.Events = FrameEvent;
387
396
  }
388
397
  isDetached() {
389
398
  return this._detachedScope.isClosed();
@@ -398,9 +407,6 @@ class Frame extends import_instrumentation.SdkObject {
398
407
  this._page.mainFrame()._recalculateNetworkIdle();
399
408
  }
400
409
  _onClearLifecycle() {
401
- this._isolatedWorld = void 0;
402
- this._mainWorld = void 0;
403
- this._iframeWorld = void 0;
404
410
  for (const event of this._firedLifecycleEvents)
405
411
  this.emit(Frame.Events.RemoveLifecycle, event);
406
412
  this._firedLifecycleEvents.clear();
@@ -451,7 +457,11 @@ class Frame extends import_instrumentation.SdkObject {
451
457
  });
452
458
  }
453
459
  nonStallingEvaluateInExistingContext(expression, world) {
454
- return this.raceAgainstEvaluationStallingEvents(() => {
460
+ return this.raceAgainstEvaluationStallingEvents(async () => {
461
+ try {
462
+ await this._context(world);
463
+ } catch {
464
+ }
455
465
  const context = this._contextData.get(world)?.context;
456
466
  if (!context)
457
467
  throw new Error("Frame does not yet have the execution context");
@@ -569,7 +579,7 @@ class Frame extends import_instrumentation.SdkObject {
569
579
  const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : void 0;
570
580
  return request ? progress.race(request._finalRequest().response()) : null;
571
581
  }
572
- async _waitForLoadState(progress, state) {
582
+ async waitForLoadState(progress, state) {
573
583
  const waitUntil = verifyLifecycle("state", state);
574
584
  if (!this._firedLifecycleEvents.has(waitUntil))
575
585
  await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
@@ -590,7 +600,7 @@ class Frame extends import_instrumentation.SdkObject {
590
600
  var executionContextId = iframeExecutionContextId;
591
601
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
592
602
  this._iframeWorld = new import_dom.FrameExecutionContext(crContext, this, world);
593
- this._page.delegate._mainFrameSession._onExecutionContextCreated({
603
+ this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
594
604
  id: executionContextId,
595
605
  origin: world,
596
606
  name: world,
@@ -602,13 +612,14 @@ class Frame extends import_instrumentation.SdkObject {
602
612
  serializationOptions: { serialization: "idOnly" }
603
613
  });
604
614
  if (!globalThis2) {
615
+ if (this.isDetached()) throw new Error("Frame was detached");
605
616
  return;
606
617
  }
607
618
  var globalThisObjId = globalThis2["result"]["objectId"];
608
619
  var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
609
620
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
610
621
  this._mainWorld = new import_dom.FrameExecutionContext(crContext, this, world);
611
- this._page.delegate._mainFrameSession._onExecutionContextCreated({
622
+ this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
612
623
  id: executionContextId,
613
624
  origin: world,
614
625
  name: world,
@@ -624,12 +635,13 @@ class Frame extends import_instrumentation.SdkObject {
624
635
  worldName: world
625
636
  });
626
637
  if (!result) {
638
+ if (this.isDetached()) throw new Error("Frame was detached");
627
639
  return;
628
640
  }
629
641
  var executionContextId = result.executionContextId;
630
642
  var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
631
643
  this._isolatedWorld = new import_dom.FrameExecutionContext(crContext, this, world);
632
- this._page.delegate._mainFrameSession._onExecutionContextCreated({
644
+ this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
633
645
  id: executionContextId,
634
646
  origin: world,
635
647
  name: world,
@@ -638,7 +650,7 @@ class Frame extends import_instrumentation.SdkObject {
638
650
  }
639
651
  if (world != "main") {
640
652
  return this._isolatedWorld;
641
- } else if (this != this._page.mainFrame() && iframeExecutionContextId) {
653
+ } else if (this != this._page.mainFrame() && this._iframeWorld) {
642
654
  return this._iframeWorld;
643
655
  } else {
644
656
  return this._mainWorld;
@@ -654,13 +666,13 @@ class Frame extends import_instrumentation.SdkObject {
654
666
  return this._context("utility");
655
667
  }
656
668
  async evaluateExpression(expression, options = {}, arg) {
657
- const context = await this._context(options.world ?? "main");
658
- const value = await context.evaluateExpression(expression, options, arg);
669
+ const context = await this._detachedScope.race(this._context(options.world ?? "main"));
670
+ const value = await this._detachedScope.race(context.evaluateExpression(expression, options, arg));
659
671
  return value;
660
672
  }
661
673
  async evaluateExpressionHandle(expression, options = {}, arg) {
662
- const context = await this._context(options.world ?? "utility");
663
- const value = await context.evaluateExpressionHandle(expression, options, arg);
674
+ const context = await this._detachedScope.race(this._context(options.world ?? "utility"));
675
+ const value = await this._detachedScope.race(context.evaluateExpressionHandle(expression, options, arg));
664
676
  return value;
665
677
  }
666
678
  async querySelector(selector, options) {
@@ -682,7 +694,15 @@ class Frame extends import_instrumentation.SdkObject {
682
694
  throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
683
695
  if (performActionPreChecksAndLog)
684
696
  progress.log(`waiting for ${this._asLocator(selector)}${state === "attached" ? "" : " to be " + state}`);
685
- const promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, async (handle) => {
697
+ const promise = this._retryWithProgressIfNotConnected(progress, selector, { ...options, performActionPreChecks: true, __patchrightWaitForSelector: true, __patchrightInitialScope: scope }, async (handle) => {
698
+ if (scope) {
699
+ const scopeIsConnected = await scope.evaluateInUtility(([injected, node]) => node.isConnected, {}).catch(() => false);
700
+ if (scopeIsConnected !== true) {
701
+ if (state === "hidden" || state === "detached")
702
+ return null;
703
+ throw new dom.NonRecoverableDOMError("Element is not attached to the DOM");
704
+ }
705
+ }
686
706
  const attached = !!handle;
687
707
  var visible = false;
688
708
  if (attached) {
@@ -713,17 +733,55 @@ class Frame extends import_instrumentation.SdkObject {
713
733
  return "internal:continuepolling";
714
734
  }
715
735
  }, "returnOnNotResolved");
716
- return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
736
+ const resultPromise = scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
737
+ return resultPromise.catch((e) => {
738
+ if (this.isDetached() && e?.message?.includes("Execution context was destroyed"))
739
+ throw new Error("Frame was detached");
740
+ throw e;
741
+ });
717
742
  }
718
743
  async dispatchEvent(progress, selector, type, eventInit = {}, options, scope) {
719
- await this._callOnElementOnceMatches(progress, selector, (injectedScript, element, data) => {
744
+ const eventInitHandles = [];
745
+ const visited = /* @__PURE__ */ new WeakSet();
746
+ const collectHandles = (value) => {
747
+ if (!value || typeof value !== "object")
748
+ return;
749
+ if (value instanceof js.JSHandle) {
750
+ eventInitHandles.push(value);
751
+ return;
752
+ }
753
+ if (visited.has(value))
754
+ return;
755
+ visited.add(value);
756
+ if (Array.isArray(value)) {
757
+ for (const item of value)
758
+ collectHandles(item);
759
+ return;
760
+ }
761
+ for (const propertyValue of Object.values(value))
762
+ collectHandles(propertyValue);
763
+ };
764
+ collectHandles(eventInit);
765
+ const allHandlesFromSameFrame = eventInitHandles.length > 0 && eventInitHandles.every((handle) => handle._context?.frame === eventInitHandles[0]?._context?.frame);
766
+ const handlesFrame = eventInitHandles[0]?._context?.frame;
767
+ const canRetryInSecondaryContext = allHandlesFromSameFrame && (handlesFrame !== this || !selector.includes("internal:control=enter-frame"));
768
+ const callback = (injectedScript, element, data) => {
720
769
  injectedScript.dispatchEvent(element, data.type, data.eventInit);
721
- }, { type, eventInit }, { mainWorld: true, ...options }, scope);
770
+ };
771
+ try {
772
+ await this._callOnElementOnceMatches(progress, selector, callback, { type, eventInit }, { mainWorld: true, ...options }, scope);
773
+ } catch (e) {
774
+ if ("JSHandles can be evaluated only in the context they were created!" === e.message && canRetryInSecondaryContext) {
775
+ await this._callOnElementOnceMatches(progress, selector, callback, { type, eventInit }, { ...options }, scope);
776
+ return;
777
+ }
778
+ throw e;
779
+ }
722
780
  }
723
781
  async evalOnSelector(selector, strict, expression, isFunction, arg, scope) {
724
782
  const handle = await this.selectors.query(selector, { strict }, scope);
725
783
  if (!handle)
726
- throw new Error("Failed to find element matching selector " + selector);
784
+ throw new Error('Failed to find element matching selector "' + selector + '"');
727
785
  const result = await handle.evaluateExpression(expression, { isFunction }, arg, true);
728
786
  handle.dispose();
729
787
  return result;
@@ -754,7 +812,7 @@ class Frame extends import_instrumentation.SdkObject {
754
812
  metadata,
755
813
  race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
756
814
  };
757
- return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
815
+ return await this._retryWithoutProgress(progress, selector, { strict: null, performActionPreChecks: false }, async (result) => {
758
816
  if (!result || !result[0]) return [];
759
817
  return result[1];
760
818
  }, "returnAll", null);
@@ -766,7 +824,7 @@ class Frame extends import_instrumentation.SdkObject {
766
824
  metadata,
767
825
  race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
768
826
  };
769
- return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
827
+ return await this._retryWithoutProgress(progress, selector, { strict: null, performActionPreChecks: false }, async (result) => {
770
828
  if (!result) return 0;
771
829
  const handle = result[0];
772
830
  const handles = result[1];
@@ -796,9 +854,9 @@ class Frame extends import_instrumentation.SdkObject {
796
854
  progress.log(`setting frame content, waiting until "${waitUntil}"`);
797
855
  const lifecyclePromise = new Promise((resolve, reject) => {
798
856
  this._onClearLifecycle();
799
- this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
857
+ this.waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
800
858
  });
801
- const setContentPromise = this._page.delegate._mainFrameSession._client.send("Page.setDocumentContent", {
859
+ const setContentPromise = this._page.delegate._sessionForFrame(this)._client.send("Page.setDocumentContent", {
802
860
  frameId: this._id,
803
861
  html
804
862
  });
@@ -963,26 +1021,27 @@ class Frame extends import_instrumentation.SdkObject {
963
1021
  return true;
964
1022
  return false;
965
1023
  }
966
- async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action, returnAction) {
967
- progress.log("waiting for " + this._asLocator(selector));
1024
+ async _retryWithProgressIfNotConnected(progress, selector, options, action, returnAction) {
1025
+ if (!options?.__patchrightSkipRetryLogWaiting)
1026
+ progress.log("waiting for " + this._asLocator(selector));
968
1027
  return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
969
- return this._retryWithoutProgress(progress, selector, strict, performActionPreChecks, action, returnAction, continuePolling);
1028
+ return this._retryWithoutProgress(progress, selector, options, action, returnAction, continuePolling);
970
1029
  });
971
1030
  }
972
1031
  async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
973
- return await this._retryWithProgressIfNotConnected(progress, selector, true, true, async (handle) => {
1032
+ return await this._retryWithProgressIfNotConnected(progress, selector, { strict: true, performActionPreChecks: true }, async (handle) => {
974
1033
  await handle._frame.rafrafTimeout(progress, timeout);
975
1034
  return await this._page.screenshotter.screenshotElement(progress, handle, options);
976
1035
  });
977
1036
  }
978
1037
  async click(progress, selector, options) {
979
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
1038
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
980
1039
  }
981
1040
  async dblclick(progress, selector, options) {
982
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._dblclick(progress, options)));
1041
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._dblclick(progress, options)));
983
1042
  }
984
1043
  async dragAndDrop(progress, source, target, options) {
985
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force, async (handle) => {
1044
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options, async (handle) => {
986
1045
  return handle._retryPointerAction(progress, "move and down", false, async (point) => {
987
1046
  await this._page.mouse.move(progress, point.x, point.y);
988
1047
  await this._page.mouse.down(progress);
@@ -992,9 +1051,9 @@ class Frame extends import_instrumentation.SdkObject {
992
1051
  position: options.sourcePosition
993
1052
  });
994
1053
  }));
995
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
1054
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, { ...options, performActionPreChecks: false }, async (handle) => {
996
1055
  return handle._retryPointerAction(progress, "move and up", false, async (point) => {
997
- await this._page.mouse.move(progress, point.x, point.y);
1056
+ await this._page.mouse.move(progress, point.x, point.y, { steps: options.steps });
998
1057
  await this._page.mouse.up(progress);
999
1058
  }, {
1000
1059
  ...options,
@@ -1006,16 +1065,16 @@ class Frame extends import_instrumentation.SdkObject {
1006
1065
  async tap(progress, selector, options) {
1007
1066
  if (!this._page.browserContext._options.hasTouch)
1008
1067
  throw new Error("The page does not support tap. Use hasTouch context option to enable touch support.");
1009
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._tap(progress, options)));
1068
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._tap(progress, options)));
1010
1069
  }
1011
1070
  async fill(progress, selector, value, options) {
1012
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._fill(progress, value, options)));
1071
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._fill(progress, value, options)));
1013
1072
  }
1014
1073
  async focus(progress, selector, options) {
1015
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._focus(progress)));
1074
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._focus(progress)));
1016
1075
  }
1017
1076
  async blur(progress, selector, options) {
1018
- dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
1077
+ dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._blur(progress)));
1019
1078
  }
1020
1079
  async resolveSelector(progress, selector, options = {}) {
1021
1080
  const element = await progress.race(this.selectors.query(selector, options));
@@ -1126,7 +1185,7 @@ class Frame extends import_instrumentation.SdkObject {
1126
1185
  }, { scope });
1127
1186
  }
1128
1187
  } else {
1129
- return await this._retryWithoutProgress(progress2, selector, options.strict, false, async (handle) => {
1188
+ return await this._retryWithoutProgress(progress2, selector, { ...options, performActionPreChecks: false }, async (handle) => {
1130
1189
  if (!handle) return false;
1131
1190
  if (handle.parentNode.constructor.name == "ElementHandle") {
1132
1191
  return await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
@@ -1168,35 +1227,35 @@ class Frame extends import_instrumentation.SdkObject {
1168
1227
  return this._elementState(progress, selector, "checked", options, scope);
1169
1228
  }
1170
1229
  async hover(progress, selector, options) {
1171
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._hover(progress, options)));
1230
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._hover(progress, options)));
1172
1231
  }
1173
1232
  async selectOption(progress, selector, elements, values, options) {
1174
- return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._selectOption(progress, elements, values, options));
1233
+ return await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._selectOption(progress, elements, values, options));
1175
1234
  }
1176
1235
  async setInputFiles(progress, selector, params) {
1177
1236
  const inputFileItems = await (0, import_fileUploadUtils.prepareFilesForUpload)(this, params);
1178
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
1237
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params, (handle) => handle._setInputFiles(progress, inputFileItems)));
1179
1238
  }
1180
1239
  async type(progress, selector, text, options) {
1181
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._type(progress, text, options)));
1240
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._type(progress, text, options)));
1182
1241
  }
1183
1242
  async press(progress, selector, key, options) {
1184
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._press(progress, key, options)));
1243
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._press(progress, key, options)));
1185
1244
  }
1186
1245
  async check(progress, selector, options) {
1187
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, true, options)));
1246
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._setChecked(progress, true, options)));
1188
1247
  }
1189
1248
  async uncheck(progress, selector, options) {
1190
- return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, false, options)));
1249
+ return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._setChecked(progress, false, options)));
1191
1250
  }
1192
1251
  async waitForTimeout(progress, timeout) {
1193
1252
  return progress.wait(timeout);
1194
1253
  }
1195
1254
  async ariaSnapshot(progress, selector) {
1196
- return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => progress.race(handle.ariaSnapshot()));
1255
+ return await this._retryWithProgressIfNotConnected(progress, selector, { strict: true, performActionPreChecks: true }, (handle) => progress.race(handle.ariaSnapshot()));
1197
1256
  }
1198
- async expect(progress, selector, options, timeout) {
1199
- progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${timeout ? ` with timeout ${timeout}ms` : ""}`);
1257
+ async expect(progress, selector, options) {
1258
+ progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${options.timeoutForLogs ? ` with timeout ${options.timeoutForLogs}ms` : ""}`);
1200
1259
  const lastIntermediateResult = { isSet: false };
1201
1260
  const fixupMetadataError = (result) => {
1202
1261
  if (result.matches === options.isNot)
@@ -1205,17 +1264,19 @@ class Frame extends import_instrumentation.SdkObject {
1205
1264
  try {
1206
1265
  if (selector)
1207
1266
  progress.log(`waiting for ${this._asLocator(selector)}`);
1208
- await this._page.performActionPreChecks(progress);
1267
+ if (!options.noAutoWaiting)
1268
+ await this._page.performActionPreChecks(progress);
1209
1269
  try {
1210
1270
  const resultOneShot = await this._expectInternal(progress, selector, options, lastIntermediateResult, true);
1211
- if (resultOneShot.matches !== options.isNot)
1271
+ if (options.noAutoWaiting || resultOneShot.matches !== options.isNot)
1212
1272
  return resultOneShot;
1213
1273
  } catch (e) {
1214
- if (this.isNonRetriableError(e))
1274
+ if (options.noAutoWaiting || this.isNonRetriableError(e))
1215
1275
  throw e;
1216
1276
  }
1217
1277
  const result = await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling) => {
1218
- await this._page.performActionPreChecks(progress);
1278
+ if (!options.noAutoWaiting)
1279
+ await this._page.performActionPreChecks(progress);
1219
1280
  const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult, false);
1220
1281
  if (matches === options.isNot) {
1221
1282
  return continuePolling;
@@ -1245,11 +1306,17 @@ class Frame extends import_instrumentation.SdkObject {
1245
1306
  const isArray = options.expression === "to.have.count" || options.expression.endsWith(".array");
1246
1307
  var log, matches, received, missingReceived;
1247
1308
  if (selector) {
1248
- const { frame, info } = await race(this.selectors.resolveFrameForSelector(selector, { strict: true }));
1309
+ var frame, info;
1310
+ try {
1311
+ var { frame, info } = await race(this.selectors.resolveFrameForSelector(selector, { strict: true }));
1312
+ } catch (e) {
1313
+ }
1249
1314
  const action = async (result) => {
1250
1315
  if (!result) {
1251
1316
  if (options.expectedNumber === 0)
1252
1317
  return { matches: true };
1318
+ if (options.isNot && options.expectedNumber)
1319
+ return { matches: false, received: 0 };
1253
1320
  if (!options.isNot && options.expression === "to.be.hidden")
1254
1321
  return { matches: true };
1255
1322
  if (options.isNot && options.expression === "to.be.visible")
@@ -1260,6 +1327,12 @@ class Frame extends import_instrumentation.SdkObject {
1260
1327
  return { matches: false };
1261
1328
  if (options.isNot && options.expression === "to.be.in.viewport")
1262
1329
  return { matches: false };
1330
+ if (options.expression === "to.have.text.array") {
1331
+ if (options.expectedText.length === 0)
1332
+ return { matches: true, received: [] };
1333
+ if (options.isNot && options.expectedText.length !== 0)
1334
+ return { matches: false, received: [] };
1335
+ }
1263
1336
  return { matches: options.isNot, missingReceived: true };
1264
1337
  }
1265
1338
  const handle = result[0];
@@ -1275,9 +1348,9 @@ class Frame extends import_instrumentation.SdkObject {
1275
1348
  }
1276
1349
  };
1277
1350
  if (noAbort) {
1278
- var { log, matches, received, missingReceived } = await this._retryWithoutProgress(progress, selector, !isArray, false, action, "returnAll", null);
1351
+ var { log, matches, received, missingReceived } = await this._retryWithoutProgress(progress, selector, { strict: !isArray, performActionPreChecks: false }, action, "returnAll", null);
1279
1352
  } else {
1280
- var { log, matches, received, missingReceived } = await race(this._retryWithProgressIfNotConnected(progress, selector, !isArray, false, action, "returnAll"));
1353
+ var { log, matches, received, missingReceived } = await race(this._retryWithProgressIfNotConnected(progress, selector, { strict: !isArray, performActionPreChecks: false, __patchrightSkipRetryLogWaiting: true }, action, "returnAll"));
1281
1354
  }
1282
1355
  } else {
1283
1356
  const world = options.expression === "to.have.property" ? "main" : "utility";
@@ -1290,10 +1363,18 @@ class Frame extends import_instrumentation.SdkObject {
1290
1363
  if (log)
1291
1364
  progress.log(log);
1292
1365
  if (matches === options.isNot) {
1293
- lastIntermediateResult.received = missingReceived ? "<element(s) not found>" : received;
1366
+ if (missingReceived) {
1367
+ lastIntermediateResult.errorMessage = "Error: element(s) not found";
1368
+ } else {
1369
+ lastIntermediateResult.errorMessage = void 0;
1370
+ lastIntermediateResult.received = received;
1371
+ }
1294
1372
  lastIntermediateResult.isSet = true;
1295
- if (!missingReceived && !Array.isArray(received))
1296
- progress.log(` unexpected value "${renderUnexpectedValue(options.expression, received)}"`);
1373
+ if (!missingReceived) {
1374
+ const rendered = renderUnexpectedValue(options.expression, received);
1375
+ if (rendered !== void 0)
1376
+ progress.log(' unexpected value "' + rendered + '"');
1377
+ }
1297
1378
  }
1298
1379
  return { matches, received };
1299
1380
  }
@@ -1349,7 +1430,7 @@ class Frame extends import_instrumentation.SdkObject {
1349
1430
  return { result, abort: () => aborted = true };
1350
1431
  }, { expression, isFunction, polling: options.pollingInterval, arg }));
1351
1432
  try {
1352
- return await progress.race(handle.evaluateHandle((h) => h.result));
1433
+ return await progress.race(this._detachedScope.race(handle.evaluateHandle((h) => h.result)));
1353
1434
  } catch (error) {
1354
1435
  await handle.evaluate((h) => h.abort()).catch(() => {
1355
1436
  });
@@ -1395,6 +1476,12 @@ class Frame extends import_instrumentation.SdkObject {
1395
1476
  data.context.contextDestroyed("Frame was detached");
1396
1477
  data.contextPromise.resolve({ destroyedReason: "Frame was detached" });
1397
1478
  }
1479
+ if (this._mainWorld)
1480
+ this._mainWorld.contextDestroyed("Frame was detached");
1481
+ if (this._iframeWorld)
1482
+ this._iframeWorld.contextDestroyed("Frame was detached");
1483
+ if (this._isolatedWorld)
1484
+ this._isolatedWorld.contextDestroyed("Frame was detached");
1398
1485
  if (this._parentFrame)
1399
1486
  this._parentFrame._childFrames.delete(this);
1400
1487
  this._parentFrame = null;
@@ -1406,15 +1493,33 @@ class Frame extends import_instrumentation.SdkObject {
1406
1493
  if (selector === ":scope") {
1407
1494
  const scopeParentNode = scope.parentNode || scope;
1408
1495
  if (scopeParentNode.constructor.name == "ElementHandle") {
1409
- promise = scopeParentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }]) => {
1410
- const callback = injected.eval(callbackText2);
1411
- const haha = callback(injected, handle2, taskData2);
1412
- return haha;
1413
- }, {
1414
- callbackText,
1415
- scope,
1416
- taskData
1417
- });
1496
+ if (options?.mainWorld) {
1497
+ promise = (async () => {
1498
+ const mainContext = await this._mainContext();
1499
+ const adoptedScope = await this._page.delegate.adoptElementHandle(scope, mainContext);
1500
+ try {
1501
+ return await mainContext.evaluate(([injected, node, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }]) => {
1502
+ const callback = injected.eval(callbackText2);
1503
+ return callback(injected, handle2, taskData2);
1504
+ }, [
1505
+ await mainContext.injectedScript(),
1506
+ adoptedScope,
1507
+ { callbackText, scope: adoptedScope, taskData }
1508
+ ]);
1509
+ } finally {
1510
+ adoptedScope.dispose();
1511
+ }
1512
+ })();
1513
+ } else {
1514
+ promise = scopeParentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }]) => {
1515
+ const callback = injected.eval(callbackText2);
1516
+ return callback(injected, handle2, taskData2);
1517
+ }, {
1518
+ callbackText,
1519
+ scope,
1520
+ taskData
1521
+ });
1522
+ }
1418
1523
  } else {
1419
1524
  promise = scopeParentNode.evaluate((injected, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }) => {
1420
1525
  const callback = injected.eval(callbackText2);
@@ -1426,12 +1531,40 @@ class Frame extends import_instrumentation.SdkObject {
1426
1531
  });
1427
1532
  }
1428
1533
  } else {
1429
- promise = this._retryWithProgressIfNotConnected(progress, selector, options.strict, false, async (handle) => {
1534
+ promise = this._retryWithProgressIfNotConnected(progress, selector, { ...options, performActionPreChecks: false }, async (handle) => {
1430
1535
  if (handle.parentNode.constructor.name == "ElementHandle") {
1536
+ if (options?.mainWorld) {
1537
+ const mainContext = await handle._frame._mainContext();
1538
+ const adoptedHandle = await this._page.delegate.adoptElementHandle(handle, mainContext);
1539
+ try {
1540
+ return await mainContext.evaluate(([injected, node, { callbackText: callbackText2, handle: handle2, taskData: taskData2 }]) => {
1541
+ const callback = injected.eval(callbackText2);
1542
+ return callback(injected, handle2, taskData2);
1543
+ }, [
1544
+ await mainContext.injectedScript(),
1545
+ adoptedHandle,
1546
+ { callbackText, handle: adoptedHandle, taskData }
1547
+ ]);
1548
+ } finally {
1549
+ adoptedHandle.dispose();
1550
+ }
1551
+ }
1552
+ const [taskScope] = Object.values(taskData?.eventInit ?? {});
1553
+ if (taskScope) {
1554
+ const taskScopeContext = taskScope._context;
1555
+ const adoptedHandle = await handle._adoptTo(taskScopeContext);
1556
+ return await taskScopeContext.evaluate(([injected, node, { callbackText: callbackText2, adoptedHandle: handle2, taskData: taskData2 }]) => {
1557
+ const callback = injected.eval(callbackText2);
1558
+ return callback(injected, handle2, taskData2);
1559
+ }, [
1560
+ await taskScopeContext.injectedScript(),
1561
+ adoptedHandle,
1562
+ { callbackText, adoptedHandle, taskData }
1563
+ ]);
1564
+ }
1431
1565
  return await handle.parentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, handle: handle2, taskData: taskData2 }]) => {
1432
1566
  const callback = injected.eval(callbackText2);
1433
- const haha = callback(injected, handle2, taskData2);
1434
- return haha;
1567
+ return callback(injected, handle2, taskData2);
1435
1568
  }, {
1436
1569
  callbackText,
1437
1570
  handle,
@@ -1508,21 +1641,23 @@ class Frame extends import_instrumentation.SdkObject {
1508
1641
  var describedNode = await client._sendMayFail("DOM.describeNode", {
1509
1642
  backendNodeId: globalDocument.backendNodeId
1510
1643
  });
1511
- if (describedNode) {
1644
+ if (describedNode && describedNode.node.contentDocument) {
1512
1645
  var resolvedNode = await client._sendMayFail("DOM.resolveNode", {
1513
- nodeId: describedNode.node.contentDocument.nodeId
1646
+ backendNodeId: describedNode.node.contentDocument.backendNodeId
1514
1647
  });
1515
- var _executionContextId = parseInt(resolvedNode.object.objectId.split(".")[1], 10);
1516
- return _executionContextId;
1648
+ if (resolvedNode && resolvedNode.object && resolvedNode.object.objectId) {
1649
+ var _executionContextId = parseInt(resolvedNode.object.objectId.split(".")[1], 10);
1650
+ return _executionContextId;
1651
+ }
1517
1652
  }
1518
1653
  }
1519
1654
  } catch (e) {
1520
1655
  }
1521
1656
  return 0;
1522
1657
  }
1523
- async _retryWithoutProgress(progress, selector, strict, performActionPreChecks, action, returnAction, continuePolling) {
1524
- if (performActionPreChecks) await this._page.performActionPreChecks(progress);
1525
- const resolved = await this.selectors.resolveInjectedForSelector(selector, { strict });
1658
+ async _retryWithoutProgress(progress, selector, options, action, returnAction, continuePolling) {
1659
+ if (options.performActionPreChecks) await this._page.performActionPreChecks(progress);
1660
+ const resolved = await this.selectors.resolveInjectedForSelector(selector, { strict: options.strict }, options.__patchrightInitialScope);
1526
1661
  if (!resolved) {
1527
1662
  if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1528
1663
  const result2 = await action(null);
@@ -1545,24 +1680,51 @@ class Frame extends import_instrumentation.SdkObject {
1545
1680
  contextId: utilityContext.delegate._contextId
1546
1681
  });
1547
1682
  if (!documentNode) return continuePolling;
1548
- const documentScope = new dom.ElementHandle(utilityContext, documentNode.result.objectId);
1683
+ let documentScope = new dom.ElementHandle(utilityContext, documentNode.result.objectId);
1684
+ let initialScope = documentScope;
1685
+ if (resolved.scope) {
1686
+ const scopeBackendNodeId = resolved.scope._objectId ? (await client._sendMayFail("DOM.describeNode", { objectId: resolved.scope._objectId }))?.node?.backendNodeId : null;
1687
+ if (scopeBackendNodeId) {
1688
+ const scopeInUtility = await client._sendMayFail("DOM.resolveNode", { backendNodeId: scopeBackendNodeId, executionContextId: utilityContext.delegate._contextId });
1689
+ if (scopeInUtility?.object?.objectId)
1690
+ initialScope = new dom.ElementHandle(utilityContext, scopeInUtility.object.objectId);
1691
+ }
1692
+ }
1693
+ progress.__patchrightInitialScope = resolved.scope;
1694
+ const parsedSnapshot = options.__patchrightWaitForSelector ? JSON.parse(JSON.stringify(resolved.info.parsed)) : null;
1549
1695
  let currentScopingElements;
1550
1696
  try {
1551
- currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext, documentScope, progress, resolved.info.parsed);
1697
+ currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext, initialScope, progress, resolved.info.parsed);
1552
1698
  } catch (e) {
1553
- if ("JSHandles can be evaluated only in the context they were created!" === e.message) return continuePolling3;
1699
+ if ("JSHandles can be evaluated only in the context they were created!" === e.message) return continuePolling;
1700
+ if (e instanceof TypeError && e.message.includes("is not a function")) return continuePolling;
1554
1701
  await progress.race(resolved.injected.evaluateHandle((injected, { error }) => {
1555
1702
  throw error;
1556
1703
  }, { error: e }));
1557
1704
  }
1558
1705
  if (currentScopingElements.length == 0) {
1706
+ if (options.__testHookNoAutoWaiting || options.noAutoWaiting)
1707
+ throw new dom.NonRecoverableDOMError("Element(s) not found");
1708
+ if (parsedSnapshot && (returnAction === "returnOnNotResolved" || returnAction === "returnAll")) {
1709
+ const elementCount = await resolved.injected.evaluate((injected, { parsed }) => {
1710
+ return injected.querySelectorAll(parsed, document).length;
1711
+ }, { parsed: parsedSnapshot }).catch(() => 0);
1712
+ if (elementCount > 0)
1713
+ return continuePolling;
1714
+ }
1559
1715
  if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
1560
1716
  const result2 = await action(null);
1561
- return result2 === "internal:continuepolling" ? continuePolling2 : result2;
1717
+ return result2 === "internal:continuepolling" ? continuePolling : result2;
1562
1718
  }
1563
1719
  return continuePolling;
1564
1720
  }
1565
1721
  const resultElement = currentScopingElements[0];
1722
+ await resultElement._initializePreview().catch(() => {
1723
+ });
1724
+ let visibilityQualifier = "";
1725
+ if (options && options.__patchrightWaitForSelector) {
1726
+ visibilityQualifier = await resultElement.evaluateInUtility(([injected, node]) => injected.utils.isElementVisible(node) ? "visible" : "hidden", {}).catch(() => "");
1727
+ }
1566
1728
  if (currentScopingElements.length > 1) {
1567
1729
  if (resolved.info.strict) {
1568
1730
  await progress.race(resolved.injected.evaluateHandle((injected, {
@@ -1577,7 +1739,7 @@ class Frame extends import_instrumentation.SdkObject {
1577
1739
  }
1578
1740
  progress.log(" locator resolved to " + currentScopingElements.length + " elements. Proceeding with the first one: " + resultElement.preview());
1579
1741
  } else if (resultElement) {
1580
- progress.log(" locator resolved to " + resultElement.preview());
1742
+ progress.log(" locator resolved to " + (visibilityQualifier ? visibilityQualifier + " " : "") + resultElement.preview().replace("JSHandle@", ""));
1581
1743
  }
1582
1744
  try {
1583
1745
  var result = null;
@@ -1592,6 +1754,14 @@ class Frame extends import_instrumentation.SdkObject {
1592
1754
  } else if (result === "internal:continuepolling") {
1593
1755
  return continuePolling;
1594
1756
  }
1757
+ if (parsedSnapshot && result === null && (options.state === "hidden" || options.state === "detached")) {
1758
+ const visibleCount = await resolved.injected.evaluate((injected, { parsed }) => {
1759
+ const elements = injected.querySelectorAll(parsed, document);
1760
+ return elements.filter((e) => injected.utils.isElementVisible(e)).length;
1761
+ }, { parsed: parsedSnapshot }).catch(() => 0);
1762
+ if (visibleCount > 0)
1763
+ return continuePolling;
1764
+ }
1595
1765
  return result;
1596
1766
  } finally {
1597
1767
  }
@@ -1704,7 +1874,7 @@ class Frame extends import_instrumentation.SdkObject {
1704
1874
  }
1705
1875
  }
1706
1876
  }
1707
- const getParts = (pos) => (pos || "").split("").map(Number);
1877
+ const getParts = (pos) => (pos || "").split(".").filter(Boolean).map(Number);
1708
1878
  elements.sort((a, b) => {
1709
1879
  const partA = getParts(a.nodePosition);
1710
1880
  const partB = getParts(b.nodePosition);