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.
- package/ThirdPartyNotices.txt +3134 -560
- package/bin/install_webkit_wsl.ps1 +1 -3
- package/browsers.json +21 -22
- package/lib/cli/program.js +16 -60
- package/lib/client/api.js +3 -3
- package/lib/client/browser.js +3 -5
- package/lib/client/browserContext.js +62 -8
- package/lib/client/browserType.js +4 -3
- package/lib/client/connection.js +4 -0
- package/lib/client/consoleMessage.js +5 -1
- package/lib/client/electron.js +1 -1
- package/lib/client/elementHandle.js +3 -0
- package/lib/client/events.js +5 -1
- package/lib/client/fetch.js +3 -4
- package/lib/client/frame.js +10 -1
- package/lib/client/locator.js +12 -1
- package/lib/client/network.js +5 -1
- package/lib/client/page.js +31 -6
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +3 -0
- package/lib/client/playwright.js +1 -5
- package/lib/client/tracing.js +7 -5
- package/lib/client/worker.js +22 -0
- package/lib/generated/clockSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/inProcessFactory.js +0 -2
- package/lib/mcpBundle.js +84 -0
- package/lib/mcpBundleImpl/index.js +147 -0
- package/lib/protocol/serializers.js +5 -0
- package/lib/protocol/validator.js +112 -50
- package/lib/remote/playwrightServer.js +1 -2
- package/lib/server/agent/actionRunner.js +335 -0
- package/lib/server/agent/actions.js +128 -0
- package/lib/server/agent/codegen.js +111 -0
- package/lib/server/agent/context.js +150 -0
- package/lib/server/agent/expectTools.js +156 -0
- package/lib/server/agent/pageAgent.js +204 -0
- package/lib/server/agent/performTools.js +262 -0
- package/lib/server/agent/tool.js +109 -0
- package/lib/server/android/android.js +1 -1
- package/lib/server/artifact.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +81 -22
- package/lib/server/bidi/bidiChromium.js +9 -13
- package/lib/server/bidi/bidiConnection.js +1 -0
- package/lib/server/bidi/bidiDeserializer.js +116 -0
- package/lib/server/bidi/bidiExecutionContext.js +75 -29
- package/lib/server/bidi/bidiFirefox.js +7 -9
- package/lib/server/bidi/bidiNetworkManager.js +1 -1
- package/lib/server/bidi/bidiPage.js +61 -30
- package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
- package/lib/server/browserContext.js +43 -36
- package/lib/server/browserType.js +12 -4
- package/lib/server/chromium/chromium.js +26 -21
- package/lib/server/chromium/chromiumSwitches.js +12 -3
- package/lib/server/chromium/crBrowser.js +30 -12
- package/lib/server/chromium/crConnection.js +0 -5
- package/lib/server/chromium/crCoverage.js +13 -1
- package/lib/server/chromium/crDevTools.js +0 -2
- package/lib/server/chromium/crNetworkManager.js +107 -18
- package/lib/server/chromium/crPage.js +68 -124
- package/lib/server/chromium/crServiceWorker.js +14 -1
- package/lib/server/codegen/javascript.js +6 -29
- package/lib/server/console.js +5 -1
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
- package/lib/server/dispatchers/dispatcher.js +6 -13
- package/lib/server/dispatchers/frameDispatcher.js +1 -1
- package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
- package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
- package/lib/server/dispatchers/pageDispatcher.js +14 -22
- package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
- package/lib/server/dom.js +12 -3
- package/lib/server/electron/electron.js +6 -3
- package/lib/server/firefox/ffBrowser.js +10 -20
- package/lib/server/firefox/ffConnection.js +0 -5
- package/lib/server/firefox/ffNetworkManager.js +2 -2
- package/lib/server/firefox/ffPage.js +18 -24
- package/lib/server/firefox/firefox.js +18 -9
- package/lib/server/frameSelectors.js +18 -8
- package/lib/server/frames.js +257 -87
- package/lib/server/input.js +7 -3
- package/lib/server/instrumentation.js +3 -0
- package/lib/server/javascript.js +8 -4
- package/lib/server/launchApp.js +2 -1
- package/lib/server/localUtils.js +4 -8
- package/lib/server/network.js +50 -12
- package/lib/server/page.js +112 -126
- package/lib/server/playwright.js +2 -4
- package/lib/server/progress.js +26 -6
- package/lib/server/recorder/recorderApp.js +80 -101
- package/lib/server/recorder.js +3 -2
- package/lib/server/registry/browserFetcher.js +6 -4
- package/lib/server/registry/index.js +278 -189
- package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
- package/lib/server/screencast.js +190 -0
- package/lib/server/screenshotter.js +6 -0
- package/lib/server/socksClientCertificatesInterceptor.js +1 -1
- package/lib/server/trace/recorder/snapshotter.js +17 -8
- package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
- package/lib/server/trace/recorder/tracing.js +31 -21
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +45 -40
- package/lib/server/utils/comparators.js +3 -25
- package/lib/server/utils/expectUtils.js +87 -2
- package/lib/server/utils/hostPlatform.js +30 -3
- package/lib/server/utils/httpServer.js +5 -20
- package/lib/server/utils/imageUtils.js +141 -0
- package/lib/server/utils/network.js +55 -40
- package/lib/server/utils/nodePlatform.js +6 -0
- package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
- package/lib/server/webkit/webkit.js +5 -16
- package/lib/server/webkit/wkBrowser.js +2 -6
- package/lib/server/webkit/wkConnection.js +1 -6
- package/lib/server/webkit/wkInterceptableRequest.js +29 -1
- package/lib/server/webkit/wkPage.js +76 -51
- package/lib/server/webkit/wkWorkers.js +2 -1
- package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
- package/lib/utils/isomorphic/locatorGenerators.js +24 -8
- package/lib/utils/isomorphic/lruCache.js +51 -0
- package/lib/utils/isomorphic/mimeType.js +1 -1
- package/lib/utils/isomorphic/protocolFormatter.js +3 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
- package/lib/utils/isomorphic/stringUtils.js +49 -0
- package/lib/utils/isomorphic/trace/entries.js +16 -0
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
- package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
- package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
- package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
- package/lib/utils/isomorphic/trace/traceModel.js +365 -0
- package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
- package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
- package/lib/utils/isomorphic/urlMatch.js +19 -5
- package/lib/utils/isomorphic/yaml.js +84 -0
- package/lib/utils.js +4 -0
- package/lib/utilsBundle.js +1 -1
- package/lib/utilsBundleImpl/index.js +124 -124
- package/lib/vite/htmlReport/index.html +21 -21
- package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
- package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
- package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
- package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
- package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
- package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
- package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
- package/lib/vite/traceViewer/index.html +6 -6
- package/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/lib/vite/traceViewer/snapshot.html +3 -3
- package/lib/vite/traceViewer/sw.bundle.js +5 -3
- package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/package.json +2 -1
- package/types/protocol.d.ts +939 -245
- package/types/types.d.ts +143 -153
- package/lib/client/accessibility.js +0 -49
- package/lib/server/accessibility.js +0 -69
- package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
- package/lib/server/chromium/crAccessibility.js +0 -263
- package/lib/server/firefox/ffAccessibility.js +0 -238
- package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
- package/lib/server/webkit/wkAccessibility.js +0 -237
- package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
- package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
- package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
- package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
- package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
- package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
- package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
- package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
- package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
- package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
package/lib/server/frames.js
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
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.
|
|
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() &&
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
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(
|
|
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.
|
|
857
|
+
this.waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
|
|
800
858
|
});
|
|
801
|
-
const setContentPromise = this._page.delegate.
|
|
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,
|
|
967
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1199
|
-
progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1296
|
-
|
|
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
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1646
|
+
backendNodeId: describedNode.node.contentDocument.backendNodeId
|
|
1514
1647
|
});
|
|
1515
|
-
|
|
1516
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
|
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" ?
|
|
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);
|