patchright-core 1.57.0 → 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 +3223 -308
- package/browsers.json +21 -22
- package/lib/cli/program.js +4 -5
- package/lib/client/api.js +3 -0
- package/lib/client/browser.js +3 -5
- package/lib/client/browserContext.js +40 -4
- package/lib/client/browserType.js +4 -3
- package/lib/client/connection.js +4 -0
- package/lib/client/elementHandle.js +3 -0
- package/lib/client/events.js +3 -0
- package/lib/client/fetch.js +3 -4
- package/lib/client/frame.js +10 -1
- package/lib/client/locator.js +8 -0
- package/lib/client/network.js +5 -1
- package/lib/client/page.js +29 -1
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +3 -0
- package/lib/client/tracing.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- 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 +88 -4
- 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/artifact.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +56 -12
- package/lib/server/bidi/bidiChromium.js +8 -12
- 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 +6 -8
- package/lib/server/bidi/bidiNetworkManager.js +1 -1
- package/lib/server/bidi/bidiPage.js +39 -28
- package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
- package/lib/server/browserContext.js +34 -26
- package/lib/server/browserType.js +12 -4
- package/lib/server/chromium/chromium.js +14 -20
- package/lib/server/chromium/chromiumSwitches.js +2 -2
- package/lib/server/chromium/crBrowser.js +22 -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 +92 -12
- package/lib/server/chromium/crPage.js +62 -116
- package/lib/server/codegen/javascript.js +6 -29
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +3 -2
- 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 +4 -0
- package/lib/server/dom.js +12 -3
- package/lib/server/electron/electron.js +5 -2
- 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 +15 -18
- package/lib/server/firefox/firefox.js +6 -8
- package/lib/server/frameSelectors.js +16 -4
- package/lib/server/frames.js +251 -86
- package/lib/server/instrumentation.js +3 -0
- package/lib/server/javascript.js +8 -4
- package/lib/server/launchApp.js +2 -1
- package/lib/server/network.js +50 -12
- package/lib/server/page.js +61 -91
- package/lib/server/progress.js +26 -6
- package/lib/server/recorder/recorderApp.js +79 -100
- package/lib/server/registry/browserFetcher.js +6 -4
- package/lib/server/registry/index.js +172 -149
- package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
- package/lib/server/screencast.js +190 -0
- package/lib/server/screenshotter.js +6 -0
- 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 +29 -21
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +21 -17
- package/lib/server/utils/expectUtils.js +87 -2
- package/lib/server/utils/hostPlatform.js +15 -0
- package/lib/server/utils/httpServer.js +5 -20
- package/lib/server/utils/network.js +37 -28
- package/lib/server/utils/nodePlatform.js +6 -0
- package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +22 -13
- package/lib/server/webkit/webkit.js +4 -6
- 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 +75 -46
- package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
- package/lib/utils/isomorphic/lruCache.js +51 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +9 -1
- 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/yaml.js +84 -0
- package/lib/utils.js +2 -0
- package/lib/utilsBundle.js +2 -5
- package/lib/utilsBundleImpl/index.js +165 -165
- package/lib/vite/htmlReport/index.html +21 -21
- package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
- package/lib/vite/{traceViewer/codeMirrorModule.C3UTv-Ge.css → recorder/assets/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/{recorder/assets/codeMirrorModule-C3UTv-Ge.css → traceViewer/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 +4 -4
- 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 +738 -159
- package/types/types.d.ts +25 -38
- package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
- package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
- package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
- package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
- package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
- package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
- package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
- package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
- package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
- package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
package/lib/server/frames.js
CHANGED
|
@@ -177,6 +177,9 @@ class FrameManager {
|
|
|
177
177
|
} else {
|
|
178
178
|
frame._currentDocument = { documentId, request: void 0 };
|
|
179
179
|
}
|
|
180
|
+
frame._iframeWorld = void 0;
|
|
181
|
+
frame._mainWorld = void 0;
|
|
182
|
+
frame._isolatedWorld = void 0;
|
|
180
183
|
frame._onClearLifecycle();
|
|
181
184
|
const navigationEvent = { url, name, newDocument: frame._currentDocument, isPublic: true };
|
|
182
185
|
this._fireInternalFrameNavigation(frame, navigationEvent);
|
|
@@ -352,6 +355,11 @@ class FrameManager {
|
|
|
352
355
|
frame.emit(Frame.Events.InternalNavigation, event);
|
|
353
356
|
}
|
|
354
357
|
}
|
|
358
|
+
const FrameEvent = {
|
|
359
|
+
InternalNavigation: "internalnavigation",
|
|
360
|
+
AddLifecycle: "addlifecycle",
|
|
361
|
+
RemoveLifecycle: "removelifecycle"
|
|
362
|
+
};
|
|
355
363
|
class Frame extends import_instrumentation.SdkObject {
|
|
356
364
|
constructor(page, id, parentFrame) {
|
|
357
365
|
super(page, "frame");
|
|
@@ -384,11 +392,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
384
392
|
this._startNetworkIdleTimer();
|
|
385
393
|
}
|
|
386
394
|
static {
|
|
387
|
-
this.Events =
|
|
388
|
-
InternalNavigation: "internalnavigation",
|
|
389
|
-
AddLifecycle: "addlifecycle",
|
|
390
|
-
RemoveLifecycle: "removelifecycle"
|
|
391
|
-
};
|
|
395
|
+
this.Events = FrameEvent;
|
|
392
396
|
}
|
|
393
397
|
isDetached() {
|
|
394
398
|
return this._detachedScope.isClosed();
|
|
@@ -403,9 +407,6 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
403
407
|
this._page.mainFrame()._recalculateNetworkIdle();
|
|
404
408
|
}
|
|
405
409
|
_onClearLifecycle() {
|
|
406
|
-
this._isolatedWorld = void 0;
|
|
407
|
-
this._mainWorld = void 0;
|
|
408
|
-
this._iframeWorld = void 0;
|
|
409
410
|
for (const event of this._firedLifecycleEvents)
|
|
410
411
|
this.emit(Frame.Events.RemoveLifecycle, event);
|
|
411
412
|
this._firedLifecycleEvents.clear();
|
|
@@ -456,7 +457,11 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
456
457
|
});
|
|
457
458
|
}
|
|
458
459
|
nonStallingEvaluateInExistingContext(expression, world) {
|
|
459
|
-
return this.raceAgainstEvaluationStallingEvents(() => {
|
|
460
|
+
return this.raceAgainstEvaluationStallingEvents(async () => {
|
|
461
|
+
try {
|
|
462
|
+
await this._context(world);
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
460
465
|
const context = this._contextData.get(world)?.context;
|
|
461
466
|
if (!context)
|
|
462
467
|
throw new Error("Frame does not yet have the execution context");
|
|
@@ -574,7 +579,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
574
579
|
const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : void 0;
|
|
575
580
|
return request ? progress.race(request._finalRequest().response()) : null;
|
|
576
581
|
}
|
|
577
|
-
async
|
|
582
|
+
async waitForLoadState(progress, state) {
|
|
578
583
|
const waitUntil = verifyLifecycle("state", state);
|
|
579
584
|
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
580
585
|
await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
|
|
@@ -595,7 +600,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
595
600
|
var executionContextId = iframeExecutionContextId;
|
|
596
601
|
var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
|
|
597
602
|
this._iframeWorld = new import_dom.FrameExecutionContext(crContext, this, world);
|
|
598
|
-
this._page.delegate.
|
|
603
|
+
this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
|
|
599
604
|
id: executionContextId,
|
|
600
605
|
origin: world,
|
|
601
606
|
name: world,
|
|
@@ -607,13 +612,14 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
607
612
|
serializationOptions: { serialization: "idOnly" }
|
|
608
613
|
});
|
|
609
614
|
if (!globalThis2) {
|
|
615
|
+
if (this.isDetached()) throw new Error("Frame was detached");
|
|
610
616
|
return;
|
|
611
617
|
}
|
|
612
618
|
var globalThisObjId = globalThis2["result"]["objectId"];
|
|
613
619
|
var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
|
|
614
620
|
var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
|
|
615
621
|
this._mainWorld = new import_dom.FrameExecutionContext(crContext, this, world);
|
|
616
|
-
this._page.delegate.
|
|
622
|
+
this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
|
|
617
623
|
id: executionContextId,
|
|
618
624
|
origin: world,
|
|
619
625
|
name: world,
|
|
@@ -629,12 +635,13 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
629
635
|
worldName: world
|
|
630
636
|
});
|
|
631
637
|
if (!result) {
|
|
638
|
+
if (this.isDetached()) throw new Error("Frame was detached");
|
|
632
639
|
return;
|
|
633
640
|
}
|
|
634
641
|
var executionContextId = result.executionContextId;
|
|
635
642
|
var crContext = new import_crExecutionContext.CRExecutionContext(client, { id: executionContextId }, this._id);
|
|
636
643
|
this._isolatedWorld = new import_dom.FrameExecutionContext(crContext, this, world);
|
|
637
|
-
this._page.delegate.
|
|
644
|
+
this._page.delegate._sessionForFrame(this)._onExecutionContextCreated({
|
|
638
645
|
id: executionContextId,
|
|
639
646
|
origin: world,
|
|
640
647
|
name: world,
|
|
@@ -643,7 +650,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
643
650
|
}
|
|
644
651
|
if (world != "main") {
|
|
645
652
|
return this._isolatedWorld;
|
|
646
|
-
} else if (this != this._page.mainFrame() &&
|
|
653
|
+
} else if (this != this._page.mainFrame() && this._iframeWorld) {
|
|
647
654
|
return this._iframeWorld;
|
|
648
655
|
} else {
|
|
649
656
|
return this._mainWorld;
|
|
@@ -659,13 +666,13 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
659
666
|
return this._context("utility");
|
|
660
667
|
}
|
|
661
668
|
async evaluateExpression(expression, options = {}, arg) {
|
|
662
|
-
const context = await this._context(options.world ?? "main");
|
|
663
|
-
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));
|
|
664
671
|
return value;
|
|
665
672
|
}
|
|
666
673
|
async evaluateExpressionHandle(expression, options = {}, arg) {
|
|
667
|
-
const context = await this._context(options.world ?? "utility");
|
|
668
|
-
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));
|
|
669
676
|
return value;
|
|
670
677
|
}
|
|
671
678
|
async querySelector(selector, options) {
|
|
@@ -687,7 +694,15 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
687
694
|
throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
|
|
688
695
|
if (performActionPreChecksAndLog)
|
|
689
696
|
progress.log(`waiting for ${this._asLocator(selector)}${state === "attached" ? "" : " to be " + state}`);
|
|
690
|
-
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
|
+
}
|
|
691
706
|
const attached = !!handle;
|
|
692
707
|
var visible = false;
|
|
693
708
|
if (attached) {
|
|
@@ -718,17 +733,55 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
718
733
|
return "internal:continuepolling";
|
|
719
734
|
}
|
|
720
735
|
}, "returnOnNotResolved");
|
|
721
|
-
|
|
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
|
+
});
|
|
722
742
|
}
|
|
723
743
|
async dispatchEvent(progress, selector, type, eventInit = {}, options, scope) {
|
|
724
|
-
|
|
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) => {
|
|
725
769
|
injectedScript.dispatchEvent(element, data.type, data.eventInit);
|
|
726
|
-
}
|
|
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
|
+
}
|
|
727
780
|
}
|
|
728
781
|
async evalOnSelector(selector, strict, expression, isFunction, arg, scope) {
|
|
729
782
|
const handle = await this.selectors.query(selector, { strict }, scope);
|
|
730
783
|
if (!handle)
|
|
731
|
-
throw new Error(
|
|
784
|
+
throw new Error('Failed to find element matching selector "' + selector + '"');
|
|
732
785
|
const result = await handle.evaluateExpression(expression, { isFunction }, arg, true);
|
|
733
786
|
handle.dispose();
|
|
734
787
|
return result;
|
|
@@ -759,7 +812,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
759
812
|
metadata,
|
|
760
813
|
race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
|
|
761
814
|
};
|
|
762
|
-
return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
|
|
815
|
+
return await this._retryWithoutProgress(progress, selector, { strict: null, performActionPreChecks: false }, async (result) => {
|
|
763
816
|
if (!result || !result[0]) return [];
|
|
764
817
|
return result[1];
|
|
765
818
|
}, "returnAll", null);
|
|
@@ -771,7 +824,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
771
824
|
metadata,
|
|
772
825
|
race: (promise) => Promise.race(Array.isArray(promise) ? promise : [promise])
|
|
773
826
|
};
|
|
774
|
-
return await this._retryWithoutProgress(progress, selector, null, false, async (result) => {
|
|
827
|
+
return await this._retryWithoutProgress(progress, selector, { strict: null, performActionPreChecks: false }, async (result) => {
|
|
775
828
|
if (!result) return 0;
|
|
776
829
|
const handle = result[0];
|
|
777
830
|
const handles = result[1];
|
|
@@ -801,9 +854,9 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
801
854
|
progress.log(`setting frame content, waiting until "${waitUntil}"`);
|
|
802
855
|
const lifecyclePromise = new Promise((resolve, reject) => {
|
|
803
856
|
this._onClearLifecycle();
|
|
804
|
-
this.
|
|
857
|
+
this.waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
|
|
805
858
|
});
|
|
806
|
-
const setContentPromise = this._page.delegate.
|
|
859
|
+
const setContentPromise = this._page.delegate._sessionForFrame(this)._client.send("Page.setDocumentContent", {
|
|
807
860
|
frameId: this._id,
|
|
808
861
|
html
|
|
809
862
|
});
|
|
@@ -968,26 +1021,27 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
968
1021
|
return true;
|
|
969
1022
|
return false;
|
|
970
1023
|
}
|
|
971
|
-
async _retryWithProgressIfNotConnected(progress, selector,
|
|
972
|
-
|
|
1024
|
+
async _retryWithProgressIfNotConnected(progress, selector, options, action, returnAction) {
|
|
1025
|
+
if (!options?.__patchrightSkipRetryLogWaiting)
|
|
1026
|
+
progress.log("waiting for " + this._asLocator(selector));
|
|
973
1027
|
return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
|
|
974
|
-
return this._retryWithoutProgress(progress, selector,
|
|
1028
|
+
return this._retryWithoutProgress(progress, selector, options, action, returnAction, continuePolling);
|
|
975
1029
|
});
|
|
976
1030
|
}
|
|
977
1031
|
async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
|
|
978
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, true, true, async (handle) => {
|
|
1032
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, { strict: true, performActionPreChecks: true }, async (handle) => {
|
|
979
1033
|
await handle._frame.rafrafTimeout(progress, timeout);
|
|
980
1034
|
return await this._page.screenshotter.screenshotElement(progress, handle, options);
|
|
981
1035
|
});
|
|
982
1036
|
}
|
|
983
1037
|
async click(progress, selector, options) {
|
|
984
|
-
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 })));
|
|
985
1039
|
}
|
|
986
1040
|
async dblclick(progress, selector, options) {
|
|
987
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1041
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._dblclick(progress, options)));
|
|
988
1042
|
}
|
|
989
1043
|
async dragAndDrop(progress, source, target, options) {
|
|
990
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options
|
|
1044
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options, async (handle) => {
|
|
991
1045
|
return handle._retryPointerAction(progress, "move and down", false, async (point) => {
|
|
992
1046
|
await this._page.mouse.move(progress, point.x, point.y);
|
|
993
1047
|
await this._page.mouse.down(progress);
|
|
@@ -997,7 +1051,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
997
1051
|
position: options.sourcePosition
|
|
998
1052
|
});
|
|
999
1053
|
}));
|
|
1000
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options
|
|
1054
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, { ...options, performActionPreChecks: false }, async (handle) => {
|
|
1001
1055
|
return handle._retryPointerAction(progress, "move and up", false, async (point) => {
|
|
1002
1056
|
await this._page.mouse.move(progress, point.x, point.y, { steps: options.steps });
|
|
1003
1057
|
await this._page.mouse.up(progress);
|
|
@@ -1011,16 +1065,16 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1011
1065
|
async tap(progress, selector, options) {
|
|
1012
1066
|
if (!this._page.browserContext._options.hasTouch)
|
|
1013
1067
|
throw new Error("The page does not support tap. Use hasTouch context option to enable touch support.");
|
|
1014
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1068
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._tap(progress, options)));
|
|
1015
1069
|
}
|
|
1016
1070
|
async fill(progress, selector, value, options) {
|
|
1017
|
-
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)));
|
|
1018
1072
|
}
|
|
1019
1073
|
async focus(progress, selector, options) {
|
|
1020
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1074
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._focus(progress)));
|
|
1021
1075
|
}
|
|
1022
1076
|
async blur(progress, selector, options) {
|
|
1023
|
-
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1077
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._blur(progress)));
|
|
1024
1078
|
}
|
|
1025
1079
|
async resolveSelector(progress, selector, options = {}) {
|
|
1026
1080
|
const element = await progress.race(this.selectors.query(selector, options));
|
|
@@ -1131,7 +1185,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1131
1185
|
}, { scope });
|
|
1132
1186
|
}
|
|
1133
1187
|
} else {
|
|
1134
|
-
return await this._retryWithoutProgress(progress2, selector, options
|
|
1188
|
+
return await this._retryWithoutProgress(progress2, selector, { ...options, performActionPreChecks: false }, async (handle) => {
|
|
1135
1189
|
if (!handle) return false;
|
|
1136
1190
|
if (handle.parentNode.constructor.name == "ElementHandle") {
|
|
1137
1191
|
return await handle.parentNode.evaluateInUtility(([injected, node, { handle: handle2 }]) => {
|
|
@@ -1173,35 +1227,35 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1173
1227
|
return this._elementState(progress, selector, "checked", options, scope);
|
|
1174
1228
|
}
|
|
1175
1229
|
async hover(progress, selector, options) {
|
|
1176
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1230
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._hover(progress, options)));
|
|
1177
1231
|
}
|
|
1178
1232
|
async selectOption(progress, selector, elements, values, options) {
|
|
1179
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1233
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, options, (handle) => handle._selectOption(progress, elements, values, options));
|
|
1180
1234
|
}
|
|
1181
1235
|
async setInputFiles(progress, selector, params) {
|
|
1182
1236
|
const inputFileItems = await (0, import_fileUploadUtils.prepareFilesForUpload)(this, params);
|
|
1183
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params
|
|
1237
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params, (handle) => handle._setInputFiles(progress, inputFileItems)));
|
|
1184
1238
|
}
|
|
1185
1239
|
async type(progress, selector, text, options) {
|
|
1186
|
-
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)));
|
|
1187
1241
|
}
|
|
1188
1242
|
async press(progress, selector, key, options) {
|
|
1189
|
-
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)));
|
|
1190
1244
|
}
|
|
1191
1245
|
async check(progress, selector, options) {
|
|
1192
|
-
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)));
|
|
1193
1247
|
}
|
|
1194
1248
|
async uncheck(progress, selector, options) {
|
|
1195
|
-
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)));
|
|
1196
1250
|
}
|
|
1197
1251
|
async waitForTimeout(progress, timeout) {
|
|
1198
1252
|
return progress.wait(timeout);
|
|
1199
1253
|
}
|
|
1200
1254
|
async ariaSnapshot(progress, selector) {
|
|
1201
|
-
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()));
|
|
1202
1256
|
}
|
|
1203
|
-
async expect(progress, selector, options
|
|
1204
|
-
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` : ""}`);
|
|
1205
1259
|
const lastIntermediateResult = { isSet: false };
|
|
1206
1260
|
const fixupMetadataError = (result) => {
|
|
1207
1261
|
if (result.matches === options.isNot)
|
|
@@ -1210,17 +1264,19 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1210
1264
|
try {
|
|
1211
1265
|
if (selector)
|
|
1212
1266
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1213
|
-
|
|
1267
|
+
if (!options.noAutoWaiting)
|
|
1268
|
+
await this._page.performActionPreChecks(progress);
|
|
1214
1269
|
try {
|
|
1215
1270
|
const resultOneShot = await this._expectInternal(progress, selector, options, lastIntermediateResult, true);
|
|
1216
|
-
if (resultOneShot.matches !== options.isNot)
|
|
1271
|
+
if (options.noAutoWaiting || resultOneShot.matches !== options.isNot)
|
|
1217
1272
|
return resultOneShot;
|
|
1218
1273
|
} catch (e) {
|
|
1219
|
-
if (this.isNonRetriableError(e))
|
|
1274
|
+
if (options.noAutoWaiting || this.isNonRetriableError(e))
|
|
1220
1275
|
throw e;
|
|
1221
1276
|
}
|
|
1222
1277
|
const result = await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling) => {
|
|
1223
|
-
|
|
1278
|
+
if (!options.noAutoWaiting)
|
|
1279
|
+
await this._page.performActionPreChecks(progress);
|
|
1224
1280
|
const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult, false);
|
|
1225
1281
|
if (matches === options.isNot) {
|
|
1226
1282
|
return continuePolling;
|
|
@@ -1250,11 +1306,17 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1250
1306
|
const isArray = options.expression === "to.have.count" || options.expression.endsWith(".array");
|
|
1251
1307
|
var log, matches, received, missingReceived;
|
|
1252
1308
|
if (selector) {
|
|
1253
|
-
|
|
1309
|
+
var frame, info;
|
|
1310
|
+
try {
|
|
1311
|
+
var { frame, info } = await race(this.selectors.resolveFrameForSelector(selector, { strict: true }));
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
}
|
|
1254
1314
|
const action = async (result) => {
|
|
1255
1315
|
if (!result) {
|
|
1256
1316
|
if (options.expectedNumber === 0)
|
|
1257
1317
|
return { matches: true };
|
|
1318
|
+
if (options.isNot && options.expectedNumber)
|
|
1319
|
+
return { matches: false, received: 0 };
|
|
1258
1320
|
if (!options.isNot && options.expression === "to.be.hidden")
|
|
1259
1321
|
return { matches: true };
|
|
1260
1322
|
if (options.isNot && options.expression === "to.be.visible")
|
|
@@ -1265,6 +1327,12 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1265
1327
|
return { matches: false };
|
|
1266
1328
|
if (options.isNot && options.expression === "to.be.in.viewport")
|
|
1267
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
|
+
}
|
|
1268
1336
|
return { matches: options.isNot, missingReceived: true };
|
|
1269
1337
|
}
|
|
1270
1338
|
const handle = result[0];
|
|
@@ -1280,9 +1348,9 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1280
1348
|
}
|
|
1281
1349
|
};
|
|
1282
1350
|
if (noAbort) {
|
|
1283
|
-
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);
|
|
1284
1352
|
} else {
|
|
1285
|
-
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"));
|
|
1286
1354
|
}
|
|
1287
1355
|
} else {
|
|
1288
1356
|
const world = options.expression === "to.have.property" ? "main" : "utility";
|
|
@@ -1295,10 +1363,18 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1295
1363
|
if (log)
|
|
1296
1364
|
progress.log(log);
|
|
1297
1365
|
if (matches === options.isNot) {
|
|
1298
|
-
|
|
1366
|
+
if (missingReceived) {
|
|
1367
|
+
lastIntermediateResult.errorMessage = "Error: element(s) not found";
|
|
1368
|
+
} else {
|
|
1369
|
+
lastIntermediateResult.errorMessage = void 0;
|
|
1370
|
+
lastIntermediateResult.received = received;
|
|
1371
|
+
}
|
|
1299
1372
|
lastIntermediateResult.isSet = true;
|
|
1300
|
-
if (!missingReceived
|
|
1301
|
-
|
|
1373
|
+
if (!missingReceived) {
|
|
1374
|
+
const rendered = renderUnexpectedValue(options.expression, received);
|
|
1375
|
+
if (rendered !== void 0)
|
|
1376
|
+
progress.log(' unexpected value "' + rendered + '"');
|
|
1377
|
+
}
|
|
1302
1378
|
}
|
|
1303
1379
|
return { matches, received };
|
|
1304
1380
|
}
|
|
@@ -1354,7 +1430,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1354
1430
|
return { result, abort: () => aborted = true };
|
|
1355
1431
|
}, { expression, isFunction, polling: options.pollingInterval, arg }));
|
|
1356
1432
|
try {
|
|
1357
|
-
return await progress.race(handle.evaluateHandle((h) => h.result));
|
|
1433
|
+
return await progress.race(this._detachedScope.race(handle.evaluateHandle((h) => h.result)));
|
|
1358
1434
|
} catch (error) {
|
|
1359
1435
|
await handle.evaluate((h) => h.abort()).catch(() => {
|
|
1360
1436
|
});
|
|
@@ -1400,6 +1476,12 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1400
1476
|
data.context.contextDestroyed("Frame was detached");
|
|
1401
1477
|
data.contextPromise.resolve({ destroyedReason: "Frame was detached" });
|
|
1402
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");
|
|
1403
1485
|
if (this._parentFrame)
|
|
1404
1486
|
this._parentFrame._childFrames.delete(this);
|
|
1405
1487
|
this._parentFrame = null;
|
|
@@ -1411,15 +1493,33 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1411
1493
|
if (selector === ":scope") {
|
|
1412
1494
|
const scopeParentNode = scope.parentNode || scope;
|
|
1413
1495
|
if (scopeParentNode.constructor.name == "ElementHandle") {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
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
|
+
}
|
|
1423
1523
|
} else {
|
|
1424
1524
|
promise = scopeParentNode.evaluate((injected, { callbackText: callbackText2, scope: handle2, taskData: taskData2 }) => {
|
|
1425
1525
|
const callback = injected.eval(callbackText2);
|
|
@@ -1431,12 +1531,40 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1431
1531
|
});
|
|
1432
1532
|
}
|
|
1433
1533
|
} else {
|
|
1434
|
-
promise = this._retryWithProgressIfNotConnected(progress, selector, options
|
|
1534
|
+
promise = this._retryWithProgressIfNotConnected(progress, selector, { ...options, performActionPreChecks: false }, async (handle) => {
|
|
1435
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
|
+
}
|
|
1436
1565
|
return await handle.parentNode.evaluateInUtility(([injected, node, { callbackText: callbackText2, handle: handle2, taskData: taskData2 }]) => {
|
|
1437
1566
|
const callback = injected.eval(callbackText2);
|
|
1438
|
-
|
|
1439
|
-
return haha;
|
|
1567
|
+
return callback(injected, handle2, taskData2);
|
|
1440
1568
|
}, {
|
|
1441
1569
|
callbackText,
|
|
1442
1570
|
handle,
|
|
@@ -1513,21 +1641,23 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1513
1641
|
var describedNode = await client._sendMayFail("DOM.describeNode", {
|
|
1514
1642
|
backendNodeId: globalDocument.backendNodeId
|
|
1515
1643
|
});
|
|
1516
|
-
if (describedNode) {
|
|
1644
|
+
if (describedNode && describedNode.node.contentDocument) {
|
|
1517
1645
|
var resolvedNode = await client._sendMayFail("DOM.resolveNode", {
|
|
1518
|
-
|
|
1646
|
+
backendNodeId: describedNode.node.contentDocument.backendNodeId
|
|
1519
1647
|
});
|
|
1520
|
-
|
|
1521
|
-
|
|
1648
|
+
if (resolvedNode && resolvedNode.object && resolvedNode.object.objectId) {
|
|
1649
|
+
var _executionContextId = parseInt(resolvedNode.object.objectId.split(".")[1], 10);
|
|
1650
|
+
return _executionContextId;
|
|
1651
|
+
}
|
|
1522
1652
|
}
|
|
1523
1653
|
}
|
|
1524
1654
|
} catch (e) {
|
|
1525
1655
|
}
|
|
1526
1656
|
return 0;
|
|
1527
1657
|
}
|
|
1528
|
-
async _retryWithoutProgress(progress, selector,
|
|
1529
|
-
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
1530
|
-
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);
|
|
1531
1661
|
if (!resolved) {
|
|
1532
1662
|
if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
|
|
1533
1663
|
const result2 = await action(null);
|
|
@@ -1550,24 +1680,51 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1550
1680
|
contextId: utilityContext.delegate._contextId
|
|
1551
1681
|
});
|
|
1552
1682
|
if (!documentNode) return continuePolling;
|
|
1553
|
-
|
|
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;
|
|
1554
1695
|
let currentScopingElements;
|
|
1555
1696
|
try {
|
|
1556
|
-
currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext,
|
|
1697
|
+
currentScopingElements = await this._customFindElementsByParsed(resolved, client, mainContext, initialScope, progress, resolved.info.parsed);
|
|
1557
1698
|
} catch (e) {
|
|
1558
|
-
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;
|
|
1559
1701
|
await progress.race(resolved.injected.evaluateHandle((injected, { error }) => {
|
|
1560
1702
|
throw error;
|
|
1561
1703
|
}, { error: e }));
|
|
1562
1704
|
}
|
|
1563
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
|
+
}
|
|
1564
1715
|
if (returnAction === "returnOnNotResolved" || returnAction === "returnAll") {
|
|
1565
1716
|
const result2 = await action(null);
|
|
1566
|
-
return result2 === "internal:continuepolling" ?
|
|
1717
|
+
return result2 === "internal:continuepolling" ? continuePolling : result2;
|
|
1567
1718
|
}
|
|
1568
1719
|
return continuePolling;
|
|
1569
1720
|
}
|
|
1570
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
|
+
}
|
|
1571
1728
|
if (currentScopingElements.length > 1) {
|
|
1572
1729
|
if (resolved.info.strict) {
|
|
1573
1730
|
await progress.race(resolved.injected.evaluateHandle((injected, {
|
|
@@ -1582,7 +1739,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1582
1739
|
}
|
|
1583
1740
|
progress.log(" locator resolved to " + currentScopingElements.length + " elements. Proceeding with the first one: " + resultElement.preview());
|
|
1584
1741
|
} else if (resultElement) {
|
|
1585
|
-
progress.log(" locator resolved to " + resultElement.preview());
|
|
1742
|
+
progress.log(" locator resolved to " + (visibilityQualifier ? visibilityQualifier + " " : "") + resultElement.preview().replace("JSHandle@", ""));
|
|
1586
1743
|
}
|
|
1587
1744
|
try {
|
|
1588
1745
|
var result = null;
|
|
@@ -1597,6 +1754,14 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1597
1754
|
} else if (result === "internal:continuepolling") {
|
|
1598
1755
|
return continuePolling;
|
|
1599
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
|
+
}
|
|
1600
1765
|
return result;
|
|
1601
1766
|
} finally {
|
|
1602
1767
|
}
|
|
@@ -1709,7 +1874,7 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1709
1874
|
}
|
|
1710
1875
|
}
|
|
1711
1876
|
}
|
|
1712
|
-
const getParts = (pos) => (pos || "").split("").map(Number);
|
|
1877
|
+
const getParts = (pos) => (pos || "").split(".").filter(Boolean).map(Number);
|
|
1713
1878
|
elements.sort((a, b) => {
|
|
1714
1879
|
const partA = getParts(a.nodePosition);
|
|
1715
1880
|
const partB = getParts(b.nodePosition);
|