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