@checkly/playwright-core 1.51.17-beta.2 → 1.54.2-beta.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/browsers.json +16 -14
- package/index.js +1 -1
- package/lib/androidServerImpl.js +47 -50
- package/lib/browserServerImpl.js +89 -69
- package/lib/checkly/escapeRegExp.js +23 -27
- package/lib/checkly/fetch.js +64 -46
- package/lib/checkly/secretsFilter.js +49 -35
- package/lib/cli/driver.js +71 -69
- package/lib/cli/program.js +400 -359
- package/lib/cli/programWithTestStub.js +51 -45
- package/lib/client/accessibility.js +31 -32
- package/lib/client/android.js +151 -242
- package/lib/client/api.js +135 -283
- package/lib/client/artifact.js +39 -36
- package/lib/client/browser.js +96 -71
- package/lib/client/browserContext.js +314 -345
- package/lib/client/browserType.js +103 -127
- package/lib/client/cdpSession.js +29 -31
- package/lib/client/channelOwner.js +90 -113
- package/lib/client/clientHelper.js +48 -39
- package/lib/client/clientInstrumentation.js +40 -37
- package/lib/client/clientStackTrace.js +41 -37
- package/lib/client/clock.js +36 -36
- package/lib/client/connection.js +188 -214
- package/lib/client/consoleMessage.js +31 -28
- package/lib/client/coverage.js +25 -22
- package/lib/client/dialog.js +30 -31
- package/lib/client/download.js +25 -25
- package/lib/client/electron.js +80 -77
- package/lib/client/elementHandle.js +120 -159
- package/lib/client/errors.js +53 -53
- package/lib/client/eventEmitter.js +124 -121
- package/lib/client/events.js +72 -68
- package/lib/client/fetch.js +166 -190
- package/lib/client/fileChooser.js +25 -24
- package/lib/client/fileUtils.js +31 -28
- package/lib/client/frame.js +207 -306
- package/lib/client/harRouter.js +42 -52
- package/lib/client/input.js +42 -69
- package/lib/client/jsHandle.js +54 -69
- package/lib/client/jsonPipe.js +27 -23
- package/lib/client/localUtils.js +29 -29
- package/lib/client/locator.js +145 -237
- package/lib/client/network.js +282 -307
- package/lib/client/page.js +269 -318
- package/lib/client/platform.js +46 -43
- package/lib/client/playwright.js +51 -76
- package/lib/client/selectors.js +45 -63
- package/lib/client/stream.js +29 -25
- package/lib/client/timeoutSettings.js +55 -41
- package/lib/client/tracing.js +49 -96
- package/lib/client/types.js +26 -22
- package/lib/client/video.js +35 -27
- package/lib/client/waiter.js +69 -88
- package/lib/client/webError.js +25 -23
- package/lib/client/webSocket.js +43 -56
- package/lib/client/worker.js +48 -56
- package/lib/client/writableStream.js +27 -23
- package/lib/generated/bindingsControllerSource.js +28 -0
- package/lib/generated/clockSource.js +26 -6
- package/lib/generated/consoleApiSource.js +26 -6
- package/lib/generated/injectedScriptSource.js +26 -6
- package/lib/generated/pollingRecorderSource.js +26 -6
- package/lib/generated/storageScriptSource.js +28 -0
- package/lib/generated/utilityScriptSource.js +26 -6
- package/lib/generated/webSocketMockSource.js +333 -5
- package/lib/inProcessFactory.js +51 -53
- package/lib/inprocess.js +2 -19
- package/lib/outofprocess.js +51 -46
- package/lib/protocol/serializers.js +153 -134
- package/lib/protocol/validator.js +2807 -2739
- package/lib/protocol/validatorPrimitives.js +114 -73
- package/lib/remote/playwrightConnection.js +88 -242
- package/lib/remote/playwrightServer.js +305 -92
- package/lib/server/accessibility.js +44 -37
- package/lib/server/android/android.js +251 -241
- package/lib/server/android/backendAdb.js +87 -82
- package/lib/server/artifact.js +78 -55
- package/lib/server/bidi/bidiBrowser.js +297 -158
- package/lib/server/bidi/bidiChromium.js +119 -89
- package/lib/server/bidi/bidiConnection.js +66 -83
- package/lib/server/bidi/bidiExecutionContext.js +129 -113
- package/lib/server/bidi/bidiFirefox.js +86 -76
- package/lib/server/bidi/bidiInput.js +106 -117
- package/lib/server/bidi/bidiNetworkManager.js +142 -159
- package/lib/server/bidi/bidiOverCdp.js +57 -58
- package/lib/server/bidi/bidiPage.js +260 -260
- package/lib/server/bidi/bidiPdf.js +52 -86
- package/lib/server/bidi/third_party/bidiCommands.d.js +22 -0
- package/lib/server/bidi/third_party/bidiDeserializer.js +55 -50
- package/lib/server/bidi/third_party/bidiKeyboard.js +236 -220
- package/lib/server/bidi/third_party/bidiProtocol.js +22 -137
- package/lib/server/bidi/third_party/bidiProtocolCore.js +152 -0
- package/lib/server/bidi/third_party/bidiProtocolPermissions.js +42 -0
- package/lib/server/bidi/third_party/bidiSerializer.js +67 -63
- package/lib/server/bidi/third_party/firefoxPrefs.js +141 -119
- package/lib/server/browser.js +93 -95
- package/lib/server/browserContext.js +419 -429
- package/lib/server/browserType.js +186 -216
- package/lib/server/callLog.js +47 -44
- package/lib/server/chromium/chromium.js +235 -203
- package/lib/server/chromium/chromiumSwitches.js +100 -67
- package/lib/server/chromium/crAccessibility.js +157 -131
- package/lib/server/chromium/crBrowser.js +310 -292
- package/lib/server/chromium/crConnection.js +95 -121
- package/lib/server/chromium/crCoverage.js +121 -131
- package/lib/server/chromium/crDevTools.js +60 -51
- package/lib/server/chromium/crDragDrop.js +68 -84
- package/lib/server/chromium/crExecutionContext.js +89 -83
- package/lib/server/chromium/crInput.js +118 -113
- package/lib/server/chromium/crNetworkManager.js +274 -375
- package/lib/server/chromium/crPage.js +536 -593
- package/lib/server/chromium/crPdf.js +54 -86
- package/lib/server/chromium/crProtocolHelper.js +92 -80
- package/lib/server/chromium/crServiceWorker.js +84 -73
- package/lib/server/chromium/defaultFontFamilies.js +152 -135
- package/lib/server/chromium/protocol.d.js +16 -0
- package/lib/server/chromium/videoRecorder.js +66 -99
- package/lib/server/clock.js +107 -83
- package/lib/server/codegen/csharp.js +192 -162
- package/lib/server/codegen/java.js +156 -129
- package/lib/server/codegen/javascript.js +163 -148
- package/lib/server/codegen/jsonl.js +32 -28
- package/lib/server/codegen/language.js +75 -52
- package/lib/server/codegen/languages.js +65 -27
- package/lib/server/codegen/python.js +141 -126
- package/lib/server/codegen/types.js +15 -4
- package/lib/server/console.js +28 -32
- package/lib/server/cookieStore.js +108 -86
- package/lib/server/debugController.js +147 -151
- package/lib/server/debugger.js +86 -78
- package/lib/server/deviceDescriptors.js +37 -24
- package/lib/server/deviceDescriptorsSource.json +238 -128
- package/lib/server/dialog.js +84 -39
- package/lib/server/dispatchers/androidDispatcher.js +257 -148
- package/lib/server/dispatchers/artifactDispatcher.js +79 -79
- package/lib/server/dispatchers/browserContextDispatcher.js +289 -259
- package/lib/server/dispatchers/browserDispatcher.js +96 -148
- package/lib/server/dispatchers/browserTypeDispatcher.js +50 -41
- package/lib/server/dispatchers/cdpSessionDispatcher.js +35 -39
- package/lib/server/dispatchers/debugControllerDispatcher.js +65 -83
- package/lib/server/dispatchers/dialogDispatcher.js +34 -31
- package/lib/server/dispatchers/dispatcher.js +208 -248
- package/lib/server/dispatchers/electronDispatcher.js +66 -70
- package/lib/server/dispatchers/elementHandlerDispatcher.js +164 -216
- package/lib/server/dispatchers/frameDispatcher.js +211 -272
- package/lib/server/dispatchers/jsHandleDispatcher.js +63 -75
- package/lib/server/dispatchers/jsonPipeDispatcher.js +37 -38
- package/lib/server/dispatchers/localUtilsDispatcher.js +121 -119
- package/lib/server/dispatchers/networkDispatchers.js +117 -128
- package/lib/server/dispatchers/pageDispatcher.js +256 -248
- package/lib/server/dispatchers/playwrightDispatcher.js +92 -87
- package/lib/server/dispatchers/streamDispatcher.js +52 -48
- package/lib/server/dispatchers/tracingDispatcher.js +47 -52
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +126 -150
- package/lib/server/dispatchers/writableStreamDispatcher.js +65 -43
- package/lib/server/dom.js +485 -582
- package/lib/server/download.js +47 -37
- package/lib/server/electron/electron.js +216 -243
- package/lib/server/electron/loader.js +9 -37
- package/lib/server/errors.js +47 -46
- package/lib/server/fetch.js +317 -360
- package/lib/server/fileChooser.js +25 -24
- package/lib/server/fileUploadUtils.js +66 -60
- package/lib/server/firefox/ffAccessibility.js +153 -131
- package/lib/server/firefox/ffBrowser.js +268 -305
- package/lib/server/firefox/ffConnection.js +63 -84
- package/lib/server/firefox/ffExecutionContext.js +92 -73
- package/lib/server/firefox/ffInput.js +82 -84
- package/lib/server/firefox/ffNetworkManager.js +137 -114
- package/lib/server/firefox/ffPage.js +261 -293
- package/lib/server/firefox/firefox.js +80 -72
- package/lib/server/firefox/protocol.d.js +16 -0
- package/lib/server/formData.js +107 -35
- package/lib/server/frameSelectors.js +98 -114
- package/lib/server/frames.js +845 -1055
- package/lib/server/har/harRecorder.js +85 -77
- package/lib/server/har/harTracer.js +290 -223
- package/lib/server/harBackend.js +80 -80
- package/lib/server/helper.js +55 -59
- package/lib/server/index.js +59 -99
- package/lib/server/input.js +151 -189
- package/lib/server/instrumentation.js +57 -44
- package/lib/server/javascript.js +133 -134
- package/lib/server/launchApp.js +113 -75
- package/lib/server/localUtils.js +150 -142
- package/lib/server/macEditingCommands.js +141 -137
- package/lib/server/network.js +299 -303
- package/lib/server/page.js +513 -544
- package/lib/server/pipeTransport.js +49 -45
- package/lib/server/playwright.js +58 -67
- package/lib/server/progress.js +137 -68
- package/lib/server/protocolError.js +34 -31
- package/lib/server/recorder/chat.js +70 -86
- package/lib/server/recorder/recorderApp.js +341 -176
- package/lib/server/recorder/recorderInTraceViewer.js +65 -94
- package/lib/server/recorder/recorderRunner.js +93 -116
- package/lib/server/recorder/recorderSignalProcessor.js +83 -0
- package/lib/server/recorder/recorderUtils.js +104 -47
- package/lib/server/recorder/throttledFile.js +42 -30
- package/lib/server/recorder.js +395 -275
- package/lib/server/registry/browserFetcher.js +106 -101
- package/lib/server/registry/dependencies.js +245 -196
- package/lib/server/registry/index.js +930 -803
- package/lib/server/registry/nativeDeps.js +1073 -464
- package/lib/server/registry/oopDownloadBrowserMain.js +57 -75
- package/lib/server/screenshotter.js +160 -191
- package/lib/server/selectors.js +90 -51
- package/lib/server/socksClientCertificatesInterceptor.js +171 -186
- package/lib/server/socksInterceptor.js +62 -70
- package/lib/server/trace/recorder/snapshotter.js +76 -102
- package/lib/server/trace/recorder/snapshotterInjected.js +238 -217
- package/lib/server/trace/recorder/tracing.js +354 -362
- package/lib/server/trace/test/inMemorySnapshotter.js +46 -52
- package/lib/server/trace/viewer/traceViewer.js +160 -147
- package/lib/server/transport.js +119 -134
- package/lib/server/types.js +26 -22
- package/lib/server/usKeyboardLayout.js +135 -545
- package/lib/server/utils/ascii.js +39 -26
- package/lib/server/utils/comparators.js +105 -103
- package/lib/server/utils/crypto.js +157 -112
- package/lib/server/utils/debug.js +36 -32
- package/lib/server/utils/debugLogger.js +77 -48
- package/lib/server/utils/env.js +52 -37
- package/lib/server/utils/eventsHelper.js +29 -28
- package/lib/server/utils/expectUtils.js +31 -26
- package/lib/server/utils/fileUtils.js +123 -136
- package/lib/server/utils/happyEyeballs.js +141 -126
- package/lib/server/utils/hostPlatform.js +84 -120
- package/lib/server/utils/httpServer.js +106 -121
- package/lib/server/utils/image_tools/colorUtils.js +42 -51
- package/lib/server/utils/image_tools/compare.js +44 -43
- package/lib/server/utils/image_tools/imageChannel.js +38 -30
- package/lib/server/utils/image_tools/stats.js +40 -40
- package/lib/server/utils/linuxUtils.js +50 -37
- package/lib/server/utils/network.js +152 -96
- package/lib/server/utils/nodePlatform.js +87 -79
- package/lib/server/utils/pipeTransport.js +44 -42
- package/lib/server/utils/processLauncher.js +111 -121
- package/lib/server/utils/profiler.js +52 -39
- package/lib/server/utils/socksProxy.js +280 -339
- package/lib/server/utils/spawnAsync.js +37 -41
- package/lib/server/utils/task.js +31 -38
- package/lib/server/utils/userAgent.js +73 -66
- package/lib/server/utils/wsServer.js +68 -75
- package/lib/server/utils/zipFile.js +36 -37
- package/lib/server/utils/zones.js +37 -34
- package/lib/server/webkit/protocol.d.js +16 -0
- package/lib/server/webkit/webkit.js +77 -61
- package/lib/server/webkit/wkAccessibility.js +161 -118
- package/lib/server/webkit/wkBrowser.js +193 -184
- package/lib/server/webkit/wkConnection.js +59 -83
- package/lib/server/webkit/wkExecutionContext.js +85 -70
- package/lib/server/webkit/wkInput.js +97 -95
- package/lib/server/webkit/wkInterceptableRequest.js +102 -95
- package/lib/server/webkit/wkPage.js +568 -667
- package/lib/server/webkit/wkProvisionalPage.js +45 -56
- package/lib/server/webkit/wkWorkers.js +79 -79
- package/lib/utils/expectUtils.js +31 -26
- package/lib/utils/isomorphic/ariaSnapshot.js +149 -152
- package/lib/utils/isomorphic/assert.js +28 -22
- package/lib/utils/isomorphic/colors.js +66 -59
- package/lib/utils/isomorphic/cssParser.js +120 -125
- package/lib/utils/isomorphic/cssTokenizer.js +436 -364
- package/lib/utils/isomorphic/headers.js +38 -37
- package/lib/utils/isomorphic/locatorGenerators.js +358 -357
- package/lib/utils/isomorphic/locatorParser.js +96 -105
- package/lib/utils/isomorphic/locatorUtils.js +63 -44
- package/lib/utils/isomorphic/manualPromise.js +46 -39
- package/lib/utils/isomorphic/mimeType.js +447 -25
- package/lib/utils/isomorphic/multimap.js +34 -27
- package/lib/utils/isomorphic/protocolFormatter.js +68 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +321 -0
- package/lib/utils/isomorphic/recorderUtils.js +140 -181
- package/lib/utils/isomorphic/rtti.js +35 -33
- package/lib/utils/isomorphic/selectorParser.js +182 -193
- package/lib/utils/isomorphic/semaphore.js +27 -24
- package/lib/utils/isomorphic/stackTrace.js +87 -98
- package/lib/utils/isomorphic/stringUtils.js +98 -112
- package/lib/utils/isomorphic/time.js +46 -22
- package/lib/utils/isomorphic/timeoutRunner.js +53 -53
- package/lib/utils/isomorphic/traceUtils.js +37 -41
- package/lib/utils/isomorphic/types.js +15 -4
- package/lib/utils/isomorphic/urlMatch.js +113 -67
- package/lib/utils/isomorphic/utilityScriptSerializers.js +251 -0
- package/lib/utils.js +101 -443
- package/lib/utilsBundle.js +101 -52
- package/lib/utilsBundleImpl/index.js +160 -150
- package/lib/zipBundle.js +32 -23
- package/lib/zipBundleImpl.js +4 -4
- package/package.json +1 -1
- package/types/protocol.d.ts +1267 -1057
- package/types/types.d.ts +131 -29
- package/lib/common/socksProxy.js +0 -569
- package/lib/common/timeoutSettings.js +0 -73
- package/lib/common/types.js +0 -5
- package/lib/image_tools/colorUtils.js +0 -98
- package/lib/image_tools/compare.js +0 -108
- package/lib/image_tools/imageChannel.js +0 -70
- package/lib/image_tools/stats.js +0 -102
- package/lib/protocol/debug.js +0 -27
- package/lib/protocol/transport.js +0 -82
- package/lib/server/dispatchers/selectorsDispatcher.js +0 -36
- package/lib/server/isomorphic/utilityScriptSerializers.js +0 -229
- package/lib/server/recorder/contextRecorder.js +0 -290
- package/lib/server/recorder/recorderCollection.js +0 -104
- package/lib/server/recorder/recorderFrontend.js +0 -5
- package/lib/server/storageScript.js +0 -160
- package/lib/server/timeoutSettings.js +0 -74
- package/lib/third_party/diff_match_patch.js +0 -2222
- package/lib/utils/ascii.js +0 -31
- package/lib/utils/comparators.js +0 -171
- package/lib/utils/crypto.js +0 -174
- package/lib/utils/debug.js +0 -46
- package/lib/utils/debugLogger.js +0 -91
- package/lib/utils/env.js +0 -49
- package/lib/utils/eventsHelper.js +0 -38
- package/lib/utils/fileUtils.js +0 -205
- package/lib/utils/happy-eyeballs.js +0 -210
- package/lib/utils/headers.js +0 -52
- package/lib/utils/hostPlatform.js +0 -133
- package/lib/utils/httpServer.js +0 -237
- package/lib/utils/index.js +0 -368
- package/lib/utils/linuxUtils.js +0 -78
- package/lib/utils/manualPromise.js +0 -109
- package/lib/utils/multimap.js +0 -75
- package/lib/utils/network.js +0 -160
- package/lib/utils/processLauncher.js +0 -248
- package/lib/utils/profiler.js +0 -53
- package/lib/utils/rtti.js +0 -44
- package/lib/utils/semaphore.js +0 -51
- package/lib/utils/spawnAsync.js +0 -45
- package/lib/utils/stackTrace.js +0 -121
- package/lib/utils/task.js +0 -58
- package/lib/utils/time.js +0 -37
- package/lib/utils/timeoutRunner.js +0 -66
- package/lib/utils/traceUtils.js +0 -44
- package/lib/utils/userAgent.js +0 -105
- package/lib/utils/wsServer.js +0 -127
- package/lib/utils/zipFile.js +0 -75
- package/lib/utils/zones.js +0 -62
- package/lib/vite/htmlReport/index.html +0 -69
- package/lib/vite/recorder/assets/codeMirrorModule-B9YMkrwa.js +0 -24
- package/lib/vite/recorder/assets/codeMirrorModule-C3UTv-Ge.css +0 -1
- package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/lib/vite/recorder/assets/index-ELPgmkwA.js +0 -184
- package/lib/vite/recorder/assets/index-eHBmevrY.css +0 -1
- package/lib/vite/recorder/index.html +0 -29
- package/lib/vite/recorder/playwright-logo.svg +0 -9
- package/lib/vite/traceViewer/assets/codeMirrorModule-gU1OOCQO.js +0 -24
- package/lib/vite/traceViewer/assets/defaultSettingsView-B5n_FjMx.js +0 -1
- package/lib/vite/traceViewer/assets/inspectorTab-6Tru8Mn_.js +0 -235
- package/lib/vite/traceViewer/assets/workbench-B_Nj4NA2.js +0 -25
- package/lib/vite/traceViewer/assets/xtermModule-BoAIEibi.js +0 -9
- package/lib/vite/traceViewer/codeMirrorModule.C3UTv-Ge.css +0 -1
- package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/lib/vite/traceViewer/defaultSettingsView.CO3FR0CX.css +0 -1
- package/lib/vite/traceViewer/embedded.DpNPH6mk.js +0 -2
- package/lib/vite/traceViewer/embedded.html +0 -18
- package/lib/vite/traceViewer/embedded.mLhjB5IF.css +0 -1
- package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
- package/lib/vite/traceViewer/index.CuE3SYGw.js +0 -2
- package/lib/vite/traceViewer/index.html +0 -47
- package/lib/vite/traceViewer/inspectorTab.CXDulcFG.css +0 -1
- package/lib/vite/traceViewer/playwright-logo.svg +0 -9
- package/lib/vite/traceViewer/recorder.BD-uZJs7.js +0 -2
- package/lib/vite/traceViewer/recorder.html +0 -17
- package/lib/vite/traceViewer/recorder.tn0RQdqM.css +0 -0
- package/lib/vite/traceViewer/snapshot.html +0 -21
- package/lib/vite/traceViewer/sw.bundle.js +0 -3
- package/lib/vite/traceViewer/uiMode.BatfzHMG.css +0 -1
- package/lib/vite/traceViewer/uiMode.DHrNgddz.js +0 -5
- package/lib/vite/traceViewer/uiMode.html +0 -21
- package/lib/vite/traceViewer/workbench.B9vIAzH9.css +0 -1
- package/lib/vite/traceViewer/xtermModule.Beg8tuEN.css +0 -32
package/lib/server/frames.js
CHANGED
|
@@ -1,76 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty
|
|
4
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var frames_exports = {};
|
|
30
|
+
__export(frames_exports, {
|
|
31
|
+
Frame: () => Frame,
|
|
32
|
+
FrameManager: () => FrameManager,
|
|
33
|
+
NavigationAbortedError: () => NavigationAbortedError
|
|
5
34
|
});
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
var dom =
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var js =
|
|
15
|
-
var network =
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
var types =
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
22
|
-
var
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
27
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
28
|
-
/**
|
|
29
|
-
* Copyright 2017 Google Inc. All rights reserved.
|
|
30
|
-
* Modifications copyright (c) Microsoft Corporation.
|
|
31
|
-
*
|
|
32
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
33
|
-
* you may not use this file except in compliance with the License.
|
|
34
|
-
* You may obtain a copy of the License at
|
|
35
|
-
*
|
|
36
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
37
|
-
*
|
|
38
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
39
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
40
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
41
|
-
* See the License for the specific language governing permissions and
|
|
42
|
-
* limitations under the License.
|
|
43
|
-
*/
|
|
44
|
-
|
|
35
|
+
module.exports = __toCommonJS(frames_exports);
|
|
36
|
+
var import_browserContext = require("./browserContext");
|
|
37
|
+
var dom = __toESM(require("./dom"));
|
|
38
|
+
var import_errors = require("./errors");
|
|
39
|
+
var import_fileUploadUtils = require("./fileUploadUtils");
|
|
40
|
+
var import_frameSelectors = require("./frameSelectors");
|
|
41
|
+
var import_helper = require("./helper");
|
|
42
|
+
var import_instrumentation = require("./instrumentation");
|
|
43
|
+
var js = __toESM(require("./javascript"));
|
|
44
|
+
var network = __toESM(require("./network"));
|
|
45
|
+
var import_page = require("./page");
|
|
46
|
+
var import_progress = require("./progress");
|
|
47
|
+
var types = __toESM(require("./types"));
|
|
48
|
+
var import_utils = require("../utils");
|
|
49
|
+
var import_protocolError = require("./protocolError");
|
|
50
|
+
var import_debugLogger = require("./utils/debugLogger");
|
|
51
|
+
var import_eventsHelper = require("./utils/eventsHelper");
|
|
52
|
+
var import_selectorParser = require("../utils/isomorphic/selectorParser");
|
|
53
|
+
var import_manualPromise = require("../utils/isomorphic/manualPromise");
|
|
54
|
+
var import_callLog = require("./callLog");
|
|
45
55
|
class NavigationAbortedError extends Error {
|
|
46
56
|
constructor(documentId, message) {
|
|
47
57
|
super(message);
|
|
48
|
-
this.documentId = void 0;
|
|
49
58
|
this.documentId = documentId;
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
|
-
|
|
53
|
-
const kDummyFrameId = '<dummy>';
|
|
61
|
+
const kDummyFrameId = "<dummy>";
|
|
54
62
|
class FrameManager {
|
|
55
63
|
constructor(page) {
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
this._signalBarriers = new Set();
|
|
61
|
-
this._webSockets = new Map();
|
|
62
|
-
this._openedDialogs = new Set();
|
|
63
|
-
this._closeAllOpeningDialogs = false;
|
|
64
|
+
this._frames = /* @__PURE__ */ new Map();
|
|
65
|
+
this._consoleMessageTags = /* @__PURE__ */ new Map();
|
|
66
|
+
this._signalBarriers = /* @__PURE__ */ new Set();
|
|
67
|
+
this._webSockets = /* @__PURE__ */ new Map();
|
|
64
68
|
this._page = page;
|
|
65
|
-
this._mainFrame =
|
|
69
|
+
this._mainFrame = void 0;
|
|
66
70
|
}
|
|
67
71
|
createDummyMainFrameIfNeeded() {
|
|
68
|
-
if (!this._mainFrame)
|
|
72
|
+
if (!this._mainFrame)
|
|
73
|
+
this.frameAttached(kDummyFrameId, null);
|
|
69
74
|
}
|
|
70
75
|
dispose() {
|
|
71
76
|
for (const frame of this._frames.values()) {
|
|
72
77
|
frame._stopNetworkIdleTimer();
|
|
73
|
-
frame._invalidateNonStallingEvaluations(
|
|
78
|
+
frame._invalidateNonStallingEvaluations("Target crashed");
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
mainFrame() {
|
|
@@ -82,7 +87,8 @@ class FrameManager {
|
|
|
82
87
|
return frames;
|
|
83
88
|
function collect(frame) {
|
|
84
89
|
frames.push(frame);
|
|
85
|
-
for (const subframe of frame.childFrames())
|
|
90
|
+
for (const subframe of frame.childFrames())
|
|
91
|
+
collect(subframe);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
94
|
frame(frameId) {
|
|
@@ -92,55 +98,54 @@ class FrameManager {
|
|
|
92
98
|
const parentFrame = parentFrameId ? this._frames.get(parentFrameId) : null;
|
|
93
99
|
if (!parentFrame) {
|
|
94
100
|
if (this._mainFrame) {
|
|
95
|
-
// Update frame id to retain frame identity on cross-process navigation.
|
|
96
101
|
this._frames.delete(this._mainFrame._id);
|
|
97
102
|
this._mainFrame._id = frameId;
|
|
98
103
|
} else {
|
|
99
|
-
(0,
|
|
104
|
+
(0, import_utils.assert)(!this._frames.has(frameId));
|
|
100
105
|
this._mainFrame = new Frame(this._page, frameId, parentFrame);
|
|
101
106
|
}
|
|
102
107
|
this._frames.set(frameId, this._mainFrame);
|
|
103
108
|
return this._mainFrame;
|
|
104
109
|
} else {
|
|
105
|
-
(0,
|
|
110
|
+
(0, import_utils.assert)(!this._frames.has(frameId));
|
|
106
111
|
const frame = new Frame(this._page, frameId, parentFrame);
|
|
107
112
|
this._frames.set(frameId, frame);
|
|
108
|
-
this._page.emit(
|
|
113
|
+
this._page.emit(import_page.Page.Events.FrameAttached, frame);
|
|
109
114
|
return frame;
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
async waitForSignalsCreatedBy(progress, waitAfter, action) {
|
|
113
|
-
if (!waitAfter)
|
|
118
|
+
if (!waitAfter)
|
|
119
|
+
return action();
|
|
114
120
|
const barrier = new SignalBarrier(progress);
|
|
115
121
|
this._signalBarriers.add(barrier);
|
|
116
|
-
|
|
122
|
+
progress.cleanupWhenAborted(() => this._signalBarriers.delete(barrier));
|
|
117
123
|
const result = await action();
|
|
118
|
-
await this._page.
|
|
124
|
+
await progress.race(this._page.delegate.inputActionEpilogue());
|
|
119
125
|
await barrier.waitFor();
|
|
120
126
|
this._signalBarriers.delete(barrier);
|
|
121
|
-
|
|
122
|
-
await new Promise((0, _utils.makeWaitForNextTask)());
|
|
127
|
+
await new Promise((0, import_utils.makeWaitForNextTask)());
|
|
123
128
|
return result;
|
|
124
129
|
}
|
|
125
130
|
frameWillPotentiallyRequestNavigation() {
|
|
126
|
-
for (const barrier of this._signalBarriers)
|
|
131
|
+
for (const barrier of this._signalBarriers)
|
|
132
|
+
barrier.retain();
|
|
127
133
|
}
|
|
128
134
|
frameDidPotentiallyRequestNavigation() {
|
|
129
|
-
for (const barrier of this._signalBarriers)
|
|
135
|
+
for (const barrier of this._signalBarriers)
|
|
136
|
+
barrier.release();
|
|
130
137
|
}
|
|
131
138
|
frameRequestedNavigation(frameId, documentId) {
|
|
132
139
|
const frame = this._frames.get(frameId);
|
|
133
|
-
if (!frame)
|
|
134
|
-
|
|
140
|
+
if (!frame)
|
|
141
|
+
return;
|
|
142
|
+
for (const barrier of this._signalBarriers)
|
|
143
|
+
barrier.addFrameNavigation(frame);
|
|
135
144
|
if (frame.pendingDocument() && frame.pendingDocument().documentId === documentId) {
|
|
136
|
-
// Do not override request with undefined.
|
|
137
145
|
return;
|
|
138
146
|
}
|
|
139
|
-
const request = documentId ? Array.from(frame._inflightRequests).find(
|
|
140
|
-
frame.setPendingDocument({
|
|
141
|
-
documentId,
|
|
142
|
-
request
|
|
143
|
-
});
|
|
147
|
+
const request = documentId ? Array.from(frame._inflightRequests).find((request2) => request2._documentId === documentId) : void 0;
|
|
148
|
+
frame.setPendingDocument({ documentId, request });
|
|
144
149
|
}
|
|
145
150
|
frameCommittedNewDocumentNavigation(frameId, url, name, documentId, initial) {
|
|
146
151
|
const frame = this._frames.get(frameId);
|
|
@@ -151,69 +156,47 @@ class FrameManager {
|
|
|
151
156
|
let keepPending;
|
|
152
157
|
const pendingDocument = frame.pendingDocument();
|
|
153
158
|
if (pendingDocument) {
|
|
154
|
-
if (pendingDocument.documentId ===
|
|
155
|
-
// Pending with unknown documentId - assume it is the one being committed.
|
|
159
|
+
if (pendingDocument.documentId === void 0) {
|
|
156
160
|
pendingDocument.documentId = documentId;
|
|
157
161
|
}
|
|
158
162
|
if (pendingDocument.documentId === documentId) {
|
|
159
|
-
// Committing a pending document.
|
|
160
163
|
frame._currentDocument = pendingDocument;
|
|
161
164
|
} else {
|
|
162
|
-
// Sometimes, we already have a new pending when the old one commits.
|
|
163
|
-
// An example would be Chromium error page followed by a new navigation request,
|
|
164
|
-
// where the error page commit arrives after Network.requestWillBeSent for the
|
|
165
|
-
// new navigation.
|
|
166
|
-
// We commit, but keep the pending request since it's not done yet.
|
|
167
165
|
keepPending = pendingDocument;
|
|
168
|
-
frame._currentDocument = {
|
|
169
|
-
documentId,
|
|
170
|
-
request: undefined
|
|
171
|
-
};
|
|
166
|
+
frame._currentDocument = { documentId, request: void 0 };
|
|
172
167
|
}
|
|
173
|
-
frame.setPendingDocument(
|
|
168
|
+
frame.setPendingDocument(void 0);
|
|
174
169
|
} else {
|
|
175
|
-
|
|
176
|
-
frame._currentDocument = {
|
|
177
|
-
documentId,
|
|
178
|
-
request: undefined
|
|
179
|
-
};
|
|
170
|
+
frame._currentDocument = { documentId, request: void 0 };
|
|
180
171
|
}
|
|
181
172
|
frame._onClearLifecycle();
|
|
182
|
-
const navigationEvent = {
|
|
183
|
-
url,
|
|
184
|
-
name,
|
|
185
|
-
newDocument: frame._currentDocument,
|
|
186
|
-
isPublic: true
|
|
187
|
-
};
|
|
173
|
+
const navigationEvent = { url, name, newDocument: frame._currentDocument, isPublic: true };
|
|
188
174
|
this._fireInternalFrameNavigation(frame, navigationEvent);
|
|
189
175
|
if (!initial) {
|
|
190
|
-
|
|
176
|
+
import_debugLogger.debugLogger.log("api", ` navigated to "${url}"`);
|
|
191
177
|
this._page.frameNavigatedToNewDocument(frame);
|
|
192
178
|
}
|
|
193
|
-
// Restore pending if any - see comments above about keepPending.
|
|
194
179
|
frame.setPendingDocument(keepPending);
|
|
195
180
|
}
|
|
196
181
|
frameCommittedSameDocumentNavigation(frameId, url) {
|
|
197
182
|
const frame = this._frames.get(frameId);
|
|
198
|
-
if (!frame)
|
|
183
|
+
if (!frame)
|
|
184
|
+
return;
|
|
199
185
|
const pending = frame.pendingDocument();
|
|
200
|
-
if (pending && pending.documentId ===
|
|
201
|
-
|
|
202
|
-
frame.setPendingDocument(undefined);
|
|
186
|
+
if (pending && pending.documentId === void 0 && pending.request === void 0) {
|
|
187
|
+
frame.setPendingDocument(void 0);
|
|
203
188
|
}
|
|
204
189
|
frame._url = url;
|
|
205
|
-
const navigationEvent = {
|
|
206
|
-
url,
|
|
207
|
-
name: frame._name,
|
|
208
|
-
isPublic: true
|
|
209
|
-
};
|
|
190
|
+
const navigationEvent = { url, name: frame._name, isPublic: true };
|
|
210
191
|
this._fireInternalFrameNavigation(frame, navigationEvent);
|
|
211
|
-
|
|
192
|
+
import_debugLogger.debugLogger.log("api", ` navigated to "${url}"`);
|
|
212
193
|
}
|
|
213
194
|
frameAbortedNavigation(frameId, errorText, documentId) {
|
|
214
195
|
const frame = this._frames.get(frameId);
|
|
215
|
-
if (!frame || !frame.pendingDocument())
|
|
216
|
-
|
|
196
|
+
if (!frame || !frame.pendingDocument())
|
|
197
|
+
return;
|
|
198
|
+
if (documentId !== void 0 && frame.pendingDocument().documentId !== documentId)
|
|
199
|
+
return;
|
|
217
200
|
const navigationEvent = {
|
|
218
201
|
url: frame._url,
|
|
219
202
|
name: frame._name,
|
|
@@ -221,7 +204,7 @@ class FrameManager {
|
|
|
221
204
|
error: new NavigationAbortedError(documentId, errorText),
|
|
222
205
|
isPublic: !(documentId && frame._redirectedNavigations.has(documentId))
|
|
223
206
|
};
|
|
224
|
-
frame.setPendingDocument(
|
|
207
|
+
frame.setPendingDocument(void 0);
|
|
225
208
|
this._fireInternalFrameNavigation(frame, navigationEvent);
|
|
226
209
|
}
|
|
227
210
|
frameDetached(frameId) {
|
|
@@ -233,104 +216,90 @@ class FrameManager {
|
|
|
233
216
|
}
|
|
234
217
|
frameLifecycleEvent(frameId, event) {
|
|
235
218
|
const frame = this._frames.get(frameId);
|
|
236
|
-
if (frame)
|
|
219
|
+
if (frame)
|
|
220
|
+
frame._onLifecycleEvent(event);
|
|
237
221
|
}
|
|
238
222
|
requestStarted(request, route) {
|
|
239
223
|
const frame = request.frame();
|
|
240
224
|
this._inflightRequestStarted(request);
|
|
241
|
-
if (request._documentId)
|
|
242
|
-
documentId: request._documentId,
|
|
243
|
-
request
|
|
244
|
-
});
|
|
225
|
+
if (request._documentId)
|
|
226
|
+
frame.setPendingDocument({ documentId: request._documentId, request });
|
|
245
227
|
if (request._isFavicon) {
|
|
246
|
-
|
|
247
|
-
|
|
228
|
+
route?.abort("aborted").catch(() => {
|
|
229
|
+
});
|
|
248
230
|
return;
|
|
249
231
|
}
|
|
250
|
-
this._page.emitOnContext(
|
|
251
|
-
if (route)
|
|
252
|
-
|
|
253
|
-
const r = new network.Route(request, route);
|
|
254
|
-
if ((_this$_page$_serverRe = (_this$_page = this._page)._serverRequestInterceptor) !== null && _this$_page$_serverRe !== void 0 && _this$_page$_serverRe.call(_this$_page, r, request)) return;
|
|
255
|
-
if ((_this$_page$_clientRe = (_this$_page2 = this._page)._clientRequestInterceptor) !== null && _this$_page$_clientRe !== void 0 && _this$_page$_clientRe.call(_this$_page2, r, request)) return;
|
|
256
|
-
if ((_this$_page$_browserC = (_this$_page$_browserC2 = this._page._browserContext)._requestInterceptor) !== null && _this$_page$_browserC !== void 0 && _this$_page$_browserC.call(_this$_page$_browserC2, r, request)) return;
|
|
257
|
-
r.continue({
|
|
258
|
-
isFallback: true
|
|
259
|
-
}).catch(() => {});
|
|
260
|
-
}
|
|
232
|
+
this._page.emitOnContext(import_browserContext.BrowserContext.Events.Request, request);
|
|
233
|
+
if (route)
|
|
234
|
+
new network.Route(request, route).handle([...this._page.requestInterceptors, ...this._page.browserContext.requestInterceptors]);
|
|
261
235
|
}
|
|
262
236
|
requestReceivedResponse(response) {
|
|
263
|
-
if (response.request()._isFavicon)
|
|
264
|
-
|
|
237
|
+
if (response.request()._isFavicon)
|
|
238
|
+
return;
|
|
239
|
+
this._page.emitOnContext(import_browserContext.BrowserContext.Events.Response, response);
|
|
265
240
|
}
|
|
266
241
|
reportRequestFinished(request, response) {
|
|
267
242
|
this._inflightRequestFinished(request);
|
|
268
|
-
if (request._isFavicon)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
response
|
|
272
|
-
});
|
|
243
|
+
if (request._isFavicon)
|
|
244
|
+
return;
|
|
245
|
+
this._page.emitOnContext(import_browserContext.BrowserContext.Events.RequestFinished, { request, response });
|
|
273
246
|
}
|
|
274
247
|
requestFailed(request, canceled) {
|
|
275
248
|
const frame = request.frame();
|
|
276
249
|
this._inflightRequestFinished(request);
|
|
277
250
|
if (frame.pendingDocument() && frame.pendingDocument().request === request) {
|
|
278
251
|
let errorText = request.failure().errorText;
|
|
279
|
-
if (canceled)
|
|
252
|
+
if (canceled)
|
|
253
|
+
errorText += "; maybe frame was detached?";
|
|
280
254
|
this.frameAbortedNavigation(frame._id, errorText, frame.pendingDocument().documentId);
|
|
281
255
|
}
|
|
282
|
-
if (request._isFavicon)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
dialogDidOpen(dialog) {
|
|
286
|
-
// Any ongoing evaluations will be stalled until the dialog is closed.
|
|
287
|
-
for (const frame of this._frames.values()) frame._invalidateNonStallingEvaluations('JavaScript dialog interrupted evaluation');
|
|
288
|
-
if (this._closeAllOpeningDialogs) dialog.close().then(() => {});else this._openedDialogs.add(dialog);
|
|
289
|
-
}
|
|
290
|
-
dialogWillClose(dialog) {
|
|
291
|
-
this._openedDialogs.delete(dialog);
|
|
292
|
-
}
|
|
293
|
-
async closeOpenDialogs() {
|
|
294
|
-
await Promise.all([...this._openedDialogs].map(dialog => dialog.close())).catch(() => {});
|
|
295
|
-
this._openedDialogs.clear();
|
|
296
|
-
}
|
|
297
|
-
setCloseAllOpeningDialogs(closeDialogs) {
|
|
298
|
-
this._closeAllOpeningDialogs = closeDialogs;
|
|
256
|
+
if (request._isFavicon)
|
|
257
|
+
return;
|
|
258
|
+
this._page.emitOnContext(import_browserContext.BrowserContext.Events.RequestFailed, request);
|
|
299
259
|
}
|
|
300
260
|
removeChildFramesRecursively(frame) {
|
|
301
|
-
for (const child of frame.childFrames())
|
|
261
|
+
for (const child of frame.childFrames())
|
|
262
|
+
this._removeFramesRecursively(child);
|
|
302
263
|
}
|
|
303
264
|
_removeFramesRecursively(frame) {
|
|
304
265
|
this.removeChildFramesRecursively(frame);
|
|
305
266
|
frame._onDetached();
|
|
306
267
|
this._frames.delete(frame._id);
|
|
307
|
-
if (!this._page.isClosed())
|
|
268
|
+
if (!this._page.isClosed())
|
|
269
|
+
this._page.emit(import_page.Page.Events.FrameDetached, frame);
|
|
308
270
|
}
|
|
309
271
|
_inflightRequestFinished(request) {
|
|
310
272
|
const frame = request.frame();
|
|
311
|
-
if (request._isFavicon)
|
|
312
|
-
|
|
273
|
+
if (request._isFavicon)
|
|
274
|
+
return;
|
|
275
|
+
if (!frame._inflightRequests.has(request))
|
|
276
|
+
return;
|
|
313
277
|
frame._inflightRequests.delete(request);
|
|
314
|
-
if (frame._inflightRequests.size === 0)
|
|
278
|
+
if (frame._inflightRequests.size === 0)
|
|
279
|
+
frame._startNetworkIdleTimer();
|
|
315
280
|
}
|
|
316
281
|
_inflightRequestStarted(request) {
|
|
317
282
|
const frame = request.frame();
|
|
318
|
-
if (request._isFavicon)
|
|
283
|
+
if (request._isFavicon)
|
|
284
|
+
return;
|
|
319
285
|
frame._inflightRequests.add(request);
|
|
320
|
-
if (frame._inflightRequests.size === 1)
|
|
286
|
+
if (frame._inflightRequests.size === 1)
|
|
287
|
+
frame._stopNetworkIdleTimer();
|
|
321
288
|
}
|
|
322
289
|
interceptConsoleMessage(message) {
|
|
323
|
-
if (message.type() !==
|
|
290
|
+
if (message.type() !== "debug")
|
|
291
|
+
return false;
|
|
324
292
|
const tag = message.text();
|
|
325
293
|
const handler = this._consoleMessageTags.get(tag);
|
|
326
|
-
if (!handler)
|
|
294
|
+
if (!handler)
|
|
295
|
+
return false;
|
|
327
296
|
this._consoleMessageTags.delete(tag);
|
|
328
297
|
handler();
|
|
329
298
|
return true;
|
|
330
299
|
}
|
|
331
300
|
clearWebSockets(frame) {
|
|
332
|
-
|
|
333
|
-
|
|
301
|
+
if (frame.parentFrame())
|
|
302
|
+
return;
|
|
334
303
|
this._webSockets.clear();
|
|
335
304
|
}
|
|
336
305
|
onWebSocketCreated(requestId, url) {
|
|
@@ -339,119 +308,128 @@ class FrameManager {
|
|
|
339
308
|
}
|
|
340
309
|
onWebSocketRequest(requestId) {
|
|
341
310
|
const ws = this._webSockets.get(requestId);
|
|
342
|
-
if (ws && ws.markAsNotified())
|
|
311
|
+
if (ws && ws.markAsNotified())
|
|
312
|
+
this._page.emit(import_page.Page.Events.WebSocket, ws);
|
|
343
313
|
}
|
|
344
314
|
onWebSocketResponse(requestId, status, statusText) {
|
|
345
315
|
const ws = this._webSockets.get(requestId);
|
|
346
|
-
if (status < 400)
|
|
347
|
-
|
|
316
|
+
if (status < 400)
|
|
317
|
+
return;
|
|
318
|
+
if (ws)
|
|
319
|
+
ws.error(`${statusText}: ${status}`);
|
|
348
320
|
}
|
|
349
321
|
onWebSocketFrameSent(requestId, opcode, data) {
|
|
350
322
|
const ws = this._webSockets.get(requestId);
|
|
351
|
-
if (ws)
|
|
323
|
+
if (ws)
|
|
324
|
+
ws.frameSent(opcode, data);
|
|
352
325
|
}
|
|
353
326
|
webSocketFrameReceived(requestId, opcode, data) {
|
|
354
327
|
const ws = this._webSockets.get(requestId);
|
|
355
|
-
if (ws)
|
|
328
|
+
if (ws)
|
|
329
|
+
ws.frameReceived(opcode, data);
|
|
356
330
|
}
|
|
357
331
|
webSocketClosed(requestId) {
|
|
358
332
|
const ws = this._webSockets.get(requestId);
|
|
359
|
-
if (ws)
|
|
333
|
+
if (ws)
|
|
334
|
+
ws.closed();
|
|
360
335
|
this._webSockets.delete(requestId);
|
|
361
336
|
}
|
|
362
337
|
webSocketError(requestId, errorMessage) {
|
|
363
338
|
const ws = this._webSockets.get(requestId);
|
|
364
|
-
if (ws)
|
|
339
|
+
if (ws)
|
|
340
|
+
ws.error(errorMessage);
|
|
365
341
|
}
|
|
366
342
|
_fireInternalFrameNavigation(frame, event) {
|
|
367
343
|
frame.emit(Frame.Events.InternalNavigation, event);
|
|
368
344
|
}
|
|
369
345
|
}
|
|
370
|
-
|
|
371
|
-
class Frame extends _instrumentation.SdkObject {
|
|
346
|
+
class Frame extends import_instrumentation.SdkObject {
|
|
372
347
|
constructor(page, id, parentFrame) {
|
|
373
|
-
super(page,
|
|
374
|
-
this.
|
|
375
|
-
this._firedLifecycleEvents = new Set();
|
|
348
|
+
super(page, "frame");
|
|
349
|
+
this._firedLifecycleEvents = /* @__PURE__ */ new Set();
|
|
376
350
|
this._firedNetworkIdleSelf = false;
|
|
377
|
-
this.
|
|
378
|
-
this.
|
|
379
|
-
this.
|
|
380
|
-
this.
|
|
381
|
-
this.
|
|
382
|
-
this._contextData = new Map();
|
|
383
|
-
this._childFrames = new Set();
|
|
384
|
-
this._name = '';
|
|
385
|
-
this._inflightRequests = new Set();
|
|
386
|
-
this._networkIdleTimer = void 0;
|
|
351
|
+
this._url = "";
|
|
352
|
+
this._contextData = /* @__PURE__ */ new Map();
|
|
353
|
+
this._childFrames = /* @__PURE__ */ new Set();
|
|
354
|
+
this._name = "";
|
|
355
|
+
this._inflightRequests = /* @__PURE__ */ new Set();
|
|
387
356
|
this._setContentCounter = 0;
|
|
388
|
-
this._detachedScope = new
|
|
389
|
-
this._raceAgainstEvaluationStallingEventsPromises = new Set();
|
|
390
|
-
this._redirectedNavigations = new Map();
|
|
391
|
-
// documentId -> data
|
|
392
|
-
this.selectors = void 0;
|
|
357
|
+
this._detachedScope = new import_utils.LongStandingScope();
|
|
358
|
+
this._raceAgainstEvaluationStallingEventsPromises = /* @__PURE__ */ new Set();
|
|
359
|
+
this._redirectedNavigations = /* @__PURE__ */ new Map();
|
|
393
360
|
this.attribution.frame = this;
|
|
394
361
|
this._id = id;
|
|
395
362
|
this._page = page;
|
|
396
363
|
this._parentFrame = parentFrame;
|
|
397
|
-
this._currentDocument = {
|
|
398
|
-
|
|
399
|
-
|
|
364
|
+
this._currentDocument = { documentId: void 0, request: void 0 };
|
|
365
|
+
this.selectors = new import_frameSelectors.FrameSelectors(this);
|
|
366
|
+
this._contextData.set("main", { contextPromise: new import_manualPromise.ManualPromise(), context: null });
|
|
367
|
+
this._contextData.set("utility", { contextPromise: new import_manualPromise.ManualPromise(), context: null });
|
|
368
|
+
this._setContext("main", null);
|
|
369
|
+
this._setContext("utility", null);
|
|
370
|
+
if (this._parentFrame)
|
|
371
|
+
this._parentFrame._childFrames.add(this);
|
|
372
|
+
this._firedLifecycleEvents.add("commit");
|
|
373
|
+
if (id !== kDummyFrameId)
|
|
374
|
+
this._startNetworkIdleTimer();
|
|
375
|
+
}
|
|
376
|
+
static {
|
|
377
|
+
this.Events = {
|
|
378
|
+
InternalNavigation: "internalnavigation",
|
|
379
|
+
AddLifecycle: "addlifecycle",
|
|
380
|
+
RemoveLifecycle: "removelifecycle"
|
|
400
381
|
};
|
|
401
|
-
this.selectors = new _frameSelectors.FrameSelectors(this);
|
|
402
|
-
this._contextData.set('main', {
|
|
403
|
-
contextPromise: new _manualPromise.ManualPromise(),
|
|
404
|
-
context: null
|
|
405
|
-
});
|
|
406
|
-
this._contextData.set('utility', {
|
|
407
|
-
contextPromise: new _manualPromise.ManualPromise(),
|
|
408
|
-
context: null
|
|
409
|
-
});
|
|
410
|
-
this._setContext('main', null);
|
|
411
|
-
this._setContext('utility', null);
|
|
412
|
-
if (this._parentFrame) this._parentFrame._childFrames.add(this);
|
|
413
|
-
this._firedLifecycleEvents.add('commit');
|
|
414
|
-
if (id !== kDummyFrameId) this._startNetworkIdleTimer();
|
|
415
382
|
}
|
|
416
383
|
isDetached() {
|
|
417
384
|
return this._detachedScope.isClosed();
|
|
418
385
|
}
|
|
419
386
|
_onLifecycleEvent(event) {
|
|
420
|
-
if (this._firedLifecycleEvents.has(event))
|
|
387
|
+
if (this._firedLifecycleEvents.has(event))
|
|
388
|
+
return;
|
|
421
389
|
this._firedLifecycleEvents.add(event);
|
|
422
390
|
this.emit(Frame.Events.AddLifecycle, event);
|
|
423
|
-
if (this === this._page.mainFrame() && this._url !==
|
|
391
|
+
if (this === this._page.mainFrame() && this._url !== "about:blank")
|
|
392
|
+
import_debugLogger.debugLogger.log("api", ` "${event}" event fired`);
|
|
424
393
|
this._page.mainFrame()._recalculateNetworkIdle();
|
|
425
394
|
}
|
|
426
395
|
_onClearLifecycle() {
|
|
427
|
-
for (const event of this._firedLifecycleEvents)
|
|
396
|
+
for (const event of this._firedLifecycleEvents)
|
|
397
|
+
this.emit(Frame.Events.RemoveLifecycle, event);
|
|
428
398
|
this._firedLifecycleEvents.clear();
|
|
429
|
-
|
|
430
|
-
this._inflightRequests = new Set(Array.from(this._inflightRequests).filter(request => request === this._currentDocument.request));
|
|
399
|
+
this._inflightRequests = new Set(Array.from(this._inflightRequests).filter((request) => request === this._currentDocument.request));
|
|
431
400
|
this._stopNetworkIdleTimer();
|
|
432
|
-
if (this._inflightRequests.size === 0)
|
|
401
|
+
if (this._inflightRequests.size === 0)
|
|
402
|
+
this._startNetworkIdleTimer();
|
|
433
403
|
this._page.mainFrame()._recalculateNetworkIdle(this);
|
|
434
|
-
this._onLifecycleEvent(
|
|
404
|
+
this._onLifecycleEvent("commit");
|
|
435
405
|
}
|
|
436
406
|
setPendingDocument(documentInfo) {
|
|
437
407
|
this._pendingDocument = documentInfo;
|
|
438
|
-
if (documentInfo)
|
|
408
|
+
if (documentInfo)
|
|
409
|
+
this._invalidateNonStallingEvaluations("Navigation interrupted the evaluation");
|
|
439
410
|
}
|
|
440
411
|
pendingDocument() {
|
|
441
412
|
return this._pendingDocument;
|
|
442
413
|
}
|
|
443
414
|
_invalidateNonStallingEvaluations(message) {
|
|
444
|
-
if (!this._raceAgainstEvaluationStallingEventsPromises.size)
|
|
415
|
+
if (!this._raceAgainstEvaluationStallingEventsPromises.size)
|
|
416
|
+
return;
|
|
445
417
|
const error = new Error(message);
|
|
446
|
-
for (const promise of this._raceAgainstEvaluationStallingEventsPromises)
|
|
418
|
+
for (const promise of this._raceAgainstEvaluationStallingEventsPromises)
|
|
419
|
+
promise.reject(error);
|
|
447
420
|
}
|
|
448
421
|
async raceAgainstEvaluationStallingEvents(cb) {
|
|
449
|
-
if (this._pendingDocument)
|
|
450
|
-
|
|
451
|
-
|
|
422
|
+
if (this._pendingDocument)
|
|
423
|
+
throw new Error("Frame is currently attempting a navigation");
|
|
424
|
+
if (this._page.browserContext.dialogManager.hasOpenDialogsForPage(this._page))
|
|
425
|
+
throw new Error("Open JavaScript dialog prevents evaluation");
|
|
426
|
+
const promise = new import_manualPromise.ManualPromise();
|
|
452
427
|
this._raceAgainstEvaluationStallingEventsPromises.add(promise);
|
|
453
428
|
try {
|
|
454
|
-
return await Promise.race([
|
|
429
|
+
return await Promise.race([
|
|
430
|
+
cb(),
|
|
431
|
+
promise
|
|
432
|
+
]);
|
|
455
433
|
} finally {
|
|
456
434
|
this._raceAgainstEvaluationStallingEventsPromises.delete(promise);
|
|
457
435
|
}
|
|
@@ -459,231 +437,207 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
459
437
|
nonStallingRawEvaluateInExistingMainContext(expression) {
|
|
460
438
|
return this.raceAgainstEvaluationStallingEvents(() => {
|
|
461
439
|
const context = this._existingMainContext();
|
|
462
|
-
if (!context)
|
|
440
|
+
if (!context)
|
|
441
|
+
throw new Error("Frame does not yet have a main execution context");
|
|
463
442
|
return context.rawEvaluateJSON(expression);
|
|
464
443
|
});
|
|
465
444
|
}
|
|
466
445
|
nonStallingEvaluateInExistingContext(expression, world) {
|
|
467
446
|
return this.raceAgainstEvaluationStallingEvents(() => {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
return context.evaluateExpression(expression, {
|
|
472
|
-
isFunction: false
|
|
473
|
-
});
|
|
447
|
+
const context = this._contextData.get(world)?.context;
|
|
448
|
+
if (!context)
|
|
449
|
+
throw new Error("Frame does not yet have the execution context");
|
|
450
|
+
return context.evaluateExpression(expression, { isFunction: false });
|
|
474
451
|
});
|
|
475
452
|
}
|
|
476
453
|
_recalculateNetworkIdle(frameThatAllowsRemovingNetworkIdle) {
|
|
477
454
|
let isNetworkIdle = this._firedNetworkIdleSelf;
|
|
478
455
|
for (const child of this._childFrames) {
|
|
479
456
|
child._recalculateNetworkIdle(frameThatAllowsRemovingNetworkIdle);
|
|
480
|
-
|
|
481
|
-
|
|
457
|
+
if (!child._firedLifecycleEvents.has("networkidle"))
|
|
458
|
+
isNetworkIdle = false;
|
|
482
459
|
}
|
|
483
|
-
if (isNetworkIdle && !this._firedLifecycleEvents.has(
|
|
484
|
-
this._firedLifecycleEvents.add(
|
|
485
|
-
this.emit(Frame.Events.AddLifecycle,
|
|
486
|
-
if (this === this._page.mainFrame() && this._url !==
|
|
460
|
+
if (isNetworkIdle && !this._firedLifecycleEvents.has("networkidle")) {
|
|
461
|
+
this._firedLifecycleEvents.add("networkidle");
|
|
462
|
+
this.emit(Frame.Events.AddLifecycle, "networkidle");
|
|
463
|
+
if (this === this._page.mainFrame() && this._url !== "about:blank")
|
|
464
|
+
import_debugLogger.debugLogger.log("api", ` "networkidle" event fired`);
|
|
487
465
|
}
|
|
488
|
-
if (frameThatAllowsRemovingNetworkIdle !== this && this._firedLifecycleEvents.has(
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this._firedLifecycleEvents.delete('networkidle');
|
|
492
|
-
this.emit(Frame.Events.RemoveLifecycle, 'networkidle');
|
|
466
|
+
if (frameThatAllowsRemovingNetworkIdle !== this && this._firedLifecycleEvents.has("networkidle") && !isNetworkIdle) {
|
|
467
|
+
this._firedLifecycleEvents.delete("networkidle");
|
|
468
|
+
this.emit(Frame.Events.RemoveLifecycle, "networkidle");
|
|
493
469
|
}
|
|
494
470
|
}
|
|
495
|
-
async raceNavigationAction(progress,
|
|
496
|
-
return
|
|
471
|
+
async raceNavigationAction(progress, action) {
|
|
472
|
+
return import_utils.LongStandingScope.raceMultiple([
|
|
473
|
+
this._detachedScope,
|
|
474
|
+
this._page.openScope
|
|
475
|
+
], action().catch((e) => {
|
|
497
476
|
if (e instanceof NavigationAbortedError && e.documentId) {
|
|
498
477
|
const data = this._redirectedNavigations.get(e.documentId);
|
|
499
478
|
if (data) {
|
|
500
479
|
progress.log(`waiting for redirected navigation to "${data.url}"`);
|
|
501
|
-
return data.gotoPromise;
|
|
480
|
+
return progress.race(data.gotoPromise);
|
|
502
481
|
}
|
|
503
482
|
}
|
|
504
483
|
throw e;
|
|
505
484
|
}));
|
|
506
485
|
}
|
|
507
486
|
redirectNavigation(url, documentId, referer) {
|
|
508
|
-
const controller = new
|
|
487
|
+
const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), this);
|
|
509
488
|
const data = {
|
|
510
489
|
url,
|
|
511
|
-
gotoPromise: controller.run(progress => this.
|
|
512
|
-
referer
|
|
513
|
-
}), 0)
|
|
490
|
+
gotoPromise: controller.run((progress) => this.gotoImpl(progress, url, { referer }), 0)
|
|
514
491
|
};
|
|
515
492
|
this._redirectedNavigations.set(documentId, data);
|
|
516
493
|
data.gotoPromise.finally(() => this._redirectedNavigations.delete(documentId));
|
|
517
494
|
}
|
|
518
|
-
async goto(
|
|
519
|
-
const constructedNavigationURL = (0,
|
|
520
|
-
|
|
521
|
-
return controller.run(progress => this._goto(progress, constructedNavigationURL, options), this._page._timeoutSettings.navigationTimeout(options));
|
|
522
|
-
}
|
|
523
|
-
async _goto(progress, url, options) {
|
|
524
|
-
return this.raceNavigationAction(progress, options, async () => this._gotoAction(progress, url, options));
|
|
495
|
+
async goto(progress, url, options = {}) {
|
|
496
|
+
const constructedNavigationURL = (0, import_utils.constructURLBasedOnBaseURL)(this._page.browserContext._options.baseURL, url);
|
|
497
|
+
return this.raceNavigationAction(progress, async () => this.gotoImpl(progress, constructedNavigationURL, options));
|
|
525
498
|
}
|
|
526
|
-
async
|
|
527
|
-
const waitUntil = verifyLifecycle(
|
|
499
|
+
async gotoImpl(progress, url, options) {
|
|
500
|
+
const waitUntil = verifyLifecycle("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
|
|
528
501
|
progress.log(`navigating to "${url}", waiting until "${waitUntil}"`);
|
|
529
502
|
const headers = this._page.extraHTTPHeaders() || [];
|
|
530
|
-
const refererHeader = headers.find(h => h.name.toLowerCase() ===
|
|
531
|
-
let referer = refererHeader ? refererHeader.value :
|
|
532
|
-
if (options.referer !==
|
|
533
|
-
if (referer !==
|
|
503
|
+
const refererHeader = headers.find((h) => h.name.toLowerCase() === "referer");
|
|
504
|
+
let referer = refererHeader ? refererHeader.value : void 0;
|
|
505
|
+
if (options.referer !== void 0) {
|
|
506
|
+
if (referer !== void 0 && referer !== options.referer)
|
|
507
|
+
throw new Error('"referer" is already specified as extra HTTP header');
|
|
534
508
|
referer = options.referer;
|
|
535
509
|
}
|
|
536
|
-
url =
|
|
510
|
+
url = import_helper.helper.completeUserURL(url);
|
|
537
511
|
const navigationEvents = [];
|
|
538
|
-
const collectNavigations = arg => navigationEvents.push(arg);
|
|
512
|
+
const collectNavigations = (arg) => navigationEvents.push(arg);
|
|
539
513
|
this.on(Frame.Events.InternalNavigation, collectNavigations);
|
|
540
|
-
const navigateResult = await this._page.
|
|
514
|
+
const navigateResult = await progress.race(this._page.delegate.navigateFrame(this, url, referer)).finally(
|
|
515
|
+
() => this.off(Frame.Events.InternalNavigation, collectNavigations)
|
|
516
|
+
);
|
|
541
517
|
let event;
|
|
542
518
|
if (navigateResult.newDocumentId) {
|
|
543
|
-
const predicate =
|
|
544
|
-
|
|
545
|
-
// did commit and replaced the expected document.
|
|
546
|
-
return event.newDocument && (event.newDocument.documentId === navigateResult.newDocumentId || !event.error);
|
|
519
|
+
const predicate = (event2) => {
|
|
520
|
+
return event2.newDocument && (event2.newDocument.documentId === navigateResult.newDocumentId || !event2.error);
|
|
547
521
|
};
|
|
548
522
|
const events = navigationEvents.filter(predicate);
|
|
549
|
-
if (events.length)
|
|
523
|
+
if (events.length)
|
|
524
|
+
event = events[0];
|
|
525
|
+
else
|
|
526
|
+
event = await import_helper.helper.waitForEvent(progress, this, Frame.Events.InternalNavigation, predicate).promise;
|
|
550
527
|
if (event.newDocument.documentId !== navigateResult.newDocumentId) {
|
|
551
|
-
// This is just a sanity check. In practice, new navigation should
|
|
552
|
-
// cancel the previous one and report "request cancelled"-like error.
|
|
553
528
|
throw new NavigationAbortedError(navigateResult.newDocumentId, `Navigation to "${url}" is interrupted by another navigation to "${event.url}"`);
|
|
554
529
|
}
|
|
555
|
-
if (event.error)
|
|
530
|
+
if (event.error)
|
|
531
|
+
throw event.error;
|
|
556
532
|
} else {
|
|
557
|
-
|
|
558
|
-
const predicate = e => !e.newDocument;
|
|
533
|
+
const predicate = (e) => !e.newDocument;
|
|
559
534
|
const events = navigationEvents.filter(predicate);
|
|
560
|
-
if (events.length)
|
|
535
|
+
if (events.length)
|
|
536
|
+
event = events[0];
|
|
537
|
+
else
|
|
538
|
+
event = await import_helper.helper.waitForEvent(progress, this, Frame.Events.InternalNavigation, predicate).promise;
|
|
561
539
|
}
|
|
562
|
-
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
563
|
-
|
|
564
|
-
const
|
|
540
|
+
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
541
|
+
await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
|
|
542
|
+
const request = event.newDocument ? event.newDocument.request : void 0;
|
|
543
|
+
const response = request ? progress.race(request._finalRequest().response()) : null;
|
|
565
544
|
return response;
|
|
566
545
|
}
|
|
567
546
|
async _waitForNavigation(progress, requiresNewDocument, options) {
|
|
568
|
-
const waitUntil = verifyLifecycle(
|
|
547
|
+
const waitUntil = verifyLifecycle("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
|
|
569
548
|
progress.log(`waiting for navigation until "${waitUntil}"`);
|
|
570
|
-
const navigationEvent = await
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
if (requiresNewDocument && !event.newDocument)
|
|
549
|
+
const navigationEvent = await import_helper.helper.waitForEvent(progress, this, Frame.Events.InternalNavigation, (event) => {
|
|
550
|
+
if (event.error)
|
|
551
|
+
return true;
|
|
552
|
+
if (requiresNewDocument && !event.newDocument)
|
|
553
|
+
return false;
|
|
574
554
|
progress.log(` navigated to "${this._url}"`);
|
|
575
555
|
return true;
|
|
576
556
|
}).promise;
|
|
577
|
-
if (navigationEvent.error)
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
557
|
+
if (navigationEvent.error)
|
|
558
|
+
throw navigationEvent.error;
|
|
559
|
+
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
560
|
+
await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
|
|
561
|
+
const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : void 0;
|
|
562
|
+
return request ? progress.race(request._finalRequest().response()) : null;
|
|
581
563
|
}
|
|
582
564
|
async _waitForLoadState(progress, state) {
|
|
583
|
-
const waitUntil = verifyLifecycle(
|
|
584
|
-
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
565
|
+
const waitUntil = verifyLifecycle("state", state);
|
|
566
|
+
if (!this._firedLifecycleEvents.has(waitUntil))
|
|
567
|
+
await import_helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e) => e === waitUntil).promise;
|
|
585
568
|
}
|
|
586
569
|
async frameElement() {
|
|
587
|
-
return this._page.
|
|
570
|
+
return this._page.delegate.getFrameElement(this);
|
|
588
571
|
}
|
|
589
572
|
_context(world) {
|
|
590
|
-
return this._contextData.get(world).contextPromise.then(contextOrDestroyedReason => {
|
|
591
|
-
if (contextOrDestroyedReason instanceof js.ExecutionContext)
|
|
573
|
+
return this._contextData.get(world).contextPromise.then((contextOrDestroyedReason) => {
|
|
574
|
+
if (contextOrDestroyedReason instanceof js.ExecutionContext)
|
|
575
|
+
return contextOrDestroyedReason;
|
|
592
576
|
throw new Error(contextOrDestroyedReason.destroyedReason);
|
|
593
577
|
});
|
|
594
578
|
}
|
|
595
579
|
_mainContext() {
|
|
596
|
-
return this._context(
|
|
580
|
+
return this._context("main");
|
|
597
581
|
}
|
|
598
582
|
_existingMainContext() {
|
|
599
|
-
|
|
600
|
-
return ((_this$_contextData$ge2 = this._contextData.get('main')) === null || _this$_contextData$ge2 === void 0 ? void 0 : _this$_contextData$ge2.context) || null;
|
|
583
|
+
return this._contextData.get("main")?.context || null;
|
|
601
584
|
}
|
|
602
585
|
_utilityContext() {
|
|
603
|
-
return this._context(
|
|
586
|
+
return this._context("utility");
|
|
604
587
|
}
|
|
605
588
|
async evaluateExpression(expression, options = {}, arg) {
|
|
606
|
-
|
|
607
|
-
const context = await this._context((_options$world = options.world) !== null && _options$world !== void 0 ? _options$world : 'main');
|
|
589
|
+
const context = await this._context(options.world ?? "main");
|
|
608
590
|
const value = await context.evaluateExpression(expression, options, arg);
|
|
609
591
|
return value;
|
|
610
592
|
}
|
|
611
593
|
async evaluateExpressionHandle(expression, options = {}, arg) {
|
|
612
|
-
|
|
613
|
-
const context = await this._context((_options$world2 = options.world) !== null && _options$world2 !== void 0 ? _options$world2 : 'main');
|
|
594
|
+
const context = await this._context(options.world ?? "main");
|
|
614
595
|
const value = await context.evaluateExpressionHandle(expression, options, arg);
|
|
615
596
|
return value;
|
|
616
597
|
}
|
|
617
598
|
async querySelector(selector, options) {
|
|
618
|
-
|
|
599
|
+
import_debugLogger.debugLogger.log("api", ` finding element using the selector "${selector}"`);
|
|
619
600
|
return this.selectors.query(selector, options);
|
|
620
601
|
}
|
|
621
|
-
async waitForSelector(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
if (options.waitFor && options.waitFor !==
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
progress.log(`waiting for ${this._asLocator(selector)}${state ===
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
const {
|
|
636
|
-
state = 'visible'
|
|
637
|
-
} = options;
|
|
638
|
-
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
639
|
-
if (performActionPreChecks) await this._page.performActionPreChecks(progress);
|
|
640
|
-
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
|
|
641
|
-
progress.throwIfAborted();
|
|
602
|
+
async waitForSelector(progress, selector, performActionPreChecksAndLog, options, scope) {
|
|
603
|
+
if (options.visibility)
|
|
604
|
+
throw new Error("options.visibility is not supported, did you mean options.state?");
|
|
605
|
+
if (options.waitFor && options.waitFor !== "visible")
|
|
606
|
+
throw new Error("options.waitFor is not supported, did you mean options.state?");
|
|
607
|
+
const { state = "visible" } = options;
|
|
608
|
+
if (!["attached", "detached", "visible", "hidden"].includes(state))
|
|
609
|
+
throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
|
|
610
|
+
if (performActionPreChecksAndLog)
|
|
611
|
+
progress.log(`waiting for ${this._asLocator(selector)}${state === "attached" ? "" : " to be " + state}`);
|
|
612
|
+
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
|
|
613
|
+
if (performActionPreChecksAndLog)
|
|
614
|
+
await this._page.performActionPreChecks(progress);
|
|
615
|
+
const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector, options, scope));
|
|
642
616
|
if (!resolved) {
|
|
643
|
-
if (state ===
|
|
617
|
+
if (state === "hidden" || state === "detached")
|
|
618
|
+
return null;
|
|
644
619
|
return continuePolling;
|
|
645
620
|
}
|
|
646
|
-
const result = await resolved.injected.evaluateHandle((injected, {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}) => {
|
|
650
|
-
if (root && !root.isConnected) throw injected.createStacklessError('Element is not attached to the DOM');
|
|
621
|
+
const result = await progress.raceWithCleanup(resolved.injected.evaluateHandle((injected, { info, root }) => {
|
|
622
|
+
if (root && !root.isConnected)
|
|
623
|
+
throw injected.createStacklessError("Element is not attached to the DOM");
|
|
651
624
|
const elements = injected.querySelectorAll(info.parsed, root || document);
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
let
|
|
625
|
+
const element2 = elements[0];
|
|
626
|
+
const visible2 = element2 ? injected.utils.isElementVisible(element2) : false;
|
|
627
|
+
let log2 = "";
|
|
655
628
|
if (elements.length > 1) {
|
|
656
|
-
if (info.strict)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
629
|
+
if (info.strict)
|
|
630
|
+
throw injected.strictModeViolationError(info.parsed, elements);
|
|
631
|
+
log2 = ` locator resolved to ${elements.length} elements. Proceeding with the first one: ${injected.previewNode(elements[0])}`;
|
|
632
|
+
} else if (element2) {
|
|
633
|
+
log2 = ` locator resolved to ${visible2 ? "visible" : "hidden"} ${injected.previewNode(element2)}`;
|
|
660
634
|
}
|
|
661
|
-
return {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
}, {
|
|
668
|
-
info: resolved.info,
|
|
669
|
-
root: resolved.frame === this ? scope : undefined
|
|
670
|
-
});
|
|
671
|
-
const {
|
|
672
|
-
log,
|
|
673
|
-
visible,
|
|
674
|
-
attached
|
|
675
|
-
} = await result.evaluate(r => ({
|
|
676
|
-
log: r.log,
|
|
677
|
-
visible: r.visible,
|
|
678
|
-
attached: r.attached
|
|
679
|
-
}));
|
|
680
|
-
if (log) progress.log(log);
|
|
681
|
-
const success = {
|
|
682
|
-
attached,
|
|
683
|
-
detached: !attached,
|
|
684
|
-
visible,
|
|
685
|
-
hidden: !visible
|
|
686
|
-
}[state];
|
|
635
|
+
return { log: log2, element: element2, visible: visible2, attached: !!element2 };
|
|
636
|
+
}, { info: resolved.info, root: resolved.frame === this ? scope : void 0 }), (handle) => handle.dispose());
|
|
637
|
+
const { log, visible, attached } = await progress.race(result.evaluate((r) => ({ log: r.log, visible: r.visible, attached: r.attached })));
|
|
638
|
+
if (log)
|
|
639
|
+
progress.log(log);
|
|
640
|
+
const success = { attached, detached: !attached, visible, hidden: !visible }[state];
|
|
687
641
|
if (!success) {
|
|
688
642
|
result.dispose();
|
|
689
643
|
return continuePolling;
|
|
@@ -692,60 +646,46 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
692
646
|
result.dispose();
|
|
693
647
|
return null;
|
|
694
648
|
}
|
|
695
|
-
const element = state ===
|
|
649
|
+
const element = state === "attached" || state === "visible" ? await progress.race(result.evaluateHandle((r) => r.element)) : null;
|
|
696
650
|
result.dispose();
|
|
697
|
-
if (!element)
|
|
698
|
-
|
|
651
|
+
if (!element)
|
|
652
|
+
return null;
|
|
653
|
+
if (options.__testHookBeforeAdoptNode)
|
|
654
|
+
await progress.race(options.__testHookBeforeAdoptNode());
|
|
699
655
|
try {
|
|
700
|
-
|
|
656
|
+
const mainContext = await progress.race(resolved.frame._mainContext());
|
|
657
|
+
return await progress.race(element._adoptTo(mainContext));
|
|
701
658
|
} catch (e) {
|
|
702
659
|
return continuePolling;
|
|
703
660
|
}
|
|
704
661
|
});
|
|
705
662
|
return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
|
|
706
663
|
}
|
|
707
|
-
async dispatchEvent(
|
|
708
|
-
await this._callOnElementOnceMatches(
|
|
664
|
+
async dispatchEvent(progress, selector, type, eventInit = {}, options, scope) {
|
|
665
|
+
await this._callOnElementOnceMatches(progress, selector, (injectedScript, element, data) => {
|
|
709
666
|
injectedScript.dispatchEvent(element, data.type, data.eventInit);
|
|
710
|
-
}, {
|
|
711
|
-
type,
|
|
712
|
-
eventInit
|
|
713
|
-
}, {
|
|
714
|
-
mainWorld: true,
|
|
715
|
-
...options
|
|
716
|
-
}, scope);
|
|
667
|
+
}, { type, eventInit }, { mainWorld: true, ...options }, scope);
|
|
717
668
|
}
|
|
718
669
|
async evalOnSelector(selector, strict, expression, isFunction, arg, scope) {
|
|
719
|
-
const handle = await this.selectors.query(selector, {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const result = await handle.evaluateExpression(expression, {
|
|
724
|
-
isFunction
|
|
725
|
-
}, arg);
|
|
670
|
+
const handle = await this.selectors.query(selector, { strict }, scope);
|
|
671
|
+
if (!handle)
|
|
672
|
+
throw new Error(`Failed to find element matching selector "${selector}"`);
|
|
673
|
+
const result = await handle.evaluateExpression(expression, { isFunction }, arg);
|
|
726
674
|
handle.dispose();
|
|
727
675
|
return result;
|
|
728
676
|
}
|
|
729
677
|
async evalOnSelectorAll(selector, expression, isFunction, arg, scope) {
|
|
730
678
|
const arrayHandle = await this.selectors.queryArrayInMainWorld(selector, scope);
|
|
731
|
-
const result = await arrayHandle.evaluateExpression(expression, {
|
|
732
|
-
isFunction
|
|
733
|
-
}, arg);
|
|
679
|
+
const result = await arrayHandle.evaluateExpression(expression, { isFunction }, arg);
|
|
734
680
|
arrayHandle.dispose();
|
|
735
681
|
return result;
|
|
736
682
|
}
|
|
737
683
|
async maskSelectors(selectors, color) {
|
|
738
684
|
const context = await this._utilityContext();
|
|
739
685
|
const injectedScript = await context.injectedScript();
|
|
740
|
-
await injectedScript.evaluate((injected, {
|
|
741
|
-
parsed,
|
|
742
|
-
|
|
743
|
-
}) => {
|
|
744
|
-
injected.maskSelectors(parsed, color);
|
|
745
|
-
}, {
|
|
746
|
-
parsed: selectors,
|
|
747
|
-
color: color
|
|
748
|
-
});
|
|
686
|
+
await injectedScript.evaluate((injected, { parsed, color: color2 }) => {
|
|
687
|
+
injected.maskSelectors(parsed, color2);
|
|
688
|
+
}, { parsed: selectors, color });
|
|
749
689
|
}
|
|
750
690
|
async querySelectorAll(selector) {
|
|
751
691
|
return this.selectors.queryAll(selector);
|
|
@@ -757,59 +697,52 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
757
697
|
try {
|
|
758
698
|
const context = await this._utilityContext();
|
|
759
699
|
return await context.evaluate(() => {
|
|
760
|
-
let retVal =
|
|
761
|
-
if (document.doctype)
|
|
762
|
-
|
|
700
|
+
let retVal = "";
|
|
701
|
+
if (document.doctype)
|
|
702
|
+
retVal = new XMLSerializer().serializeToString(document.doctype);
|
|
703
|
+
if (document.documentElement)
|
|
704
|
+
retVal += document.documentElement.outerHTML;
|
|
763
705
|
return retVal;
|
|
764
706
|
});
|
|
765
707
|
} catch (e) {
|
|
766
|
-
if (
|
|
708
|
+
if (this.isNonRetriableError(e))
|
|
709
|
+
throw e;
|
|
767
710
|
throw new Error(`Unable to retrieve content because the page is navigating and changing the content.`);
|
|
768
711
|
}
|
|
769
712
|
}
|
|
770
|
-
async setContent(
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
this._page._frameManager._consoleMessageTags.set(tag, () => {
|
|
781
|
-
// Clear lifecycle right after document.open() - see 'tag' below.
|
|
782
|
-
this._onClearLifecycle();
|
|
783
|
-
this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
|
|
784
|
-
});
|
|
785
|
-
});
|
|
786
|
-
const contentPromise = context.evaluate(({
|
|
787
|
-
html,
|
|
788
|
-
tag
|
|
789
|
-
}) => {
|
|
790
|
-
document.open();
|
|
791
|
-
console.debug(tag); // eslint-disable-line no-console
|
|
792
|
-
document.write(html);
|
|
793
|
-
document.close();
|
|
794
|
-
}, {
|
|
795
|
-
html,
|
|
796
|
-
tag
|
|
797
|
-
});
|
|
798
|
-
await Promise.all([contentPromise, lifecyclePromise]);
|
|
799
|
-
return null;
|
|
713
|
+
async setContent(progress, html, options) {
|
|
714
|
+
await this.raceNavigationAction(progress, async () => {
|
|
715
|
+
const waitUntil = options.waitUntil === void 0 ? "load" : options.waitUntil;
|
|
716
|
+
progress.log(`setting frame content, waiting until "${waitUntil}"`);
|
|
717
|
+
const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
|
|
718
|
+
const context = await progress.race(this._utilityContext());
|
|
719
|
+
const tagPromise = new import_manualPromise.ManualPromise();
|
|
720
|
+
this._page.frameManager._consoleMessageTags.set(tag, () => {
|
|
721
|
+
this._onClearLifecycle();
|
|
722
|
+
tagPromise.resolve();
|
|
800
723
|
});
|
|
801
|
-
|
|
724
|
+
progress.cleanupWhenAborted(() => this._page.frameManager._consoleMessageTags.delete(tag));
|
|
725
|
+
const lifecyclePromise = progress.race(tagPromise).then(() => this._waitForLoadState(progress, waitUntil));
|
|
726
|
+
const contentPromise = progress.race(context.evaluate(({ html: html2, tag: tag2 }) => {
|
|
727
|
+
document.open();
|
|
728
|
+
console.debug(tag2);
|
|
729
|
+
document.write(html2);
|
|
730
|
+
document.close();
|
|
731
|
+
}, { html, tag }));
|
|
732
|
+
await Promise.all([contentPromise, lifecyclePromise]);
|
|
733
|
+
return null;
|
|
734
|
+
});
|
|
802
735
|
}
|
|
803
736
|
name() {
|
|
804
|
-
return this._name ||
|
|
737
|
+
return this._name || "";
|
|
805
738
|
}
|
|
806
739
|
url() {
|
|
807
740
|
return this._url;
|
|
808
741
|
}
|
|
809
742
|
origin() {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
return
|
|
743
|
+
if (!this._url.startsWith("http"))
|
|
744
|
+
return;
|
|
745
|
+
return network.parseURL(this._url)?.origin;
|
|
813
746
|
}
|
|
814
747
|
parentFrame() {
|
|
815
748
|
return this._parentFrame;
|
|
@@ -821,44 +754,41 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
821
754
|
const {
|
|
822
755
|
url = null,
|
|
823
756
|
content = null,
|
|
824
|
-
type =
|
|
757
|
+
type = ""
|
|
825
758
|
} = params;
|
|
826
|
-
if (!url && !content)
|
|
759
|
+
if (!url && !content)
|
|
760
|
+
throw new Error("Provide an object with a `url`, `path` or `content` property");
|
|
827
761
|
const context = await this._mainContext();
|
|
828
762
|
return this._raceWithCSPError(async () => {
|
|
829
|
-
if (url !== null)
|
|
830
|
-
url,
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
content: content,
|
|
835
|
-
type
|
|
836
|
-
})).asElement();
|
|
837
|
-
// Another round trip to the browser to ensure that we receive CSP error messages
|
|
838
|
-
// (if any) logged asynchronously in a separate task on the content main thread.
|
|
839
|
-
if (this._page._delegate.cspErrorsAsynchronousForInlineScripts) await context.evaluate(() => true);
|
|
763
|
+
if (url !== null)
|
|
764
|
+
return (await context.evaluateHandle(addScriptUrl, { url, type })).asElement();
|
|
765
|
+
const result = (await context.evaluateHandle(addScriptContent, { content, type })).asElement();
|
|
766
|
+
if (this._page.delegate.cspErrorsAsynchronousForInlineScripts)
|
|
767
|
+
await context.evaluate(() => true);
|
|
840
768
|
return result;
|
|
841
769
|
});
|
|
842
|
-
async function addScriptUrl(
|
|
843
|
-
const script = document.createElement(
|
|
844
|
-
script.src =
|
|
845
|
-
if (
|
|
770
|
+
async function addScriptUrl(params2) {
|
|
771
|
+
const script = document.createElement("script");
|
|
772
|
+
script.src = params2.url;
|
|
773
|
+
if (params2.type)
|
|
774
|
+
script.type = params2.type;
|
|
846
775
|
const promise = new Promise((res, rej) => {
|
|
847
776
|
script.onload = res;
|
|
848
|
-
script.onerror = e => rej(typeof e ===
|
|
777
|
+
script.onerror = (e) => rej(typeof e === "string" ? new Error(e) : new Error(`Failed to load script at ${script.src}`));
|
|
849
778
|
});
|
|
850
779
|
document.head.appendChild(script);
|
|
851
780
|
await promise;
|
|
852
781
|
return script;
|
|
853
782
|
}
|
|
854
|
-
function addScriptContent(
|
|
855
|
-
const script = document.createElement(
|
|
856
|
-
script.type =
|
|
857
|
-
script.text =
|
|
783
|
+
function addScriptContent(params2) {
|
|
784
|
+
const script = document.createElement("script");
|
|
785
|
+
script.type = params2.type || "text/javascript";
|
|
786
|
+
script.text = params2.content;
|
|
858
787
|
let error = null;
|
|
859
|
-
script.onerror = e => error = e;
|
|
788
|
+
script.onerror = (e) => error = e;
|
|
860
789
|
document.head.appendChild(script);
|
|
861
|
-
if (error)
|
|
790
|
+
if (error)
|
|
791
|
+
throw error;
|
|
862
792
|
return script;
|
|
863
793
|
}
|
|
864
794
|
}
|
|
@@ -867,16 +797,18 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
867
797
|
url = null,
|
|
868
798
|
content = null
|
|
869
799
|
} = params;
|
|
870
|
-
if (!url && !content)
|
|
800
|
+
if (!url && !content)
|
|
801
|
+
throw new Error("Provide an object with a `url`, `path` or `content` property");
|
|
871
802
|
const context = await this._mainContext();
|
|
872
803
|
return this._raceWithCSPError(async () => {
|
|
873
|
-
if (url !== null)
|
|
804
|
+
if (url !== null)
|
|
805
|
+
return (await context.evaluateHandle(addStyleUrl, url)).asElement();
|
|
874
806
|
return (await context.evaluateHandle(addStyleContent, content)).asElement();
|
|
875
807
|
});
|
|
876
|
-
async function addStyleUrl(
|
|
877
|
-
const link = document.createElement(
|
|
878
|
-
link.rel =
|
|
879
|
-
link.href =
|
|
808
|
+
async function addStyleUrl(url2) {
|
|
809
|
+
const link = document.createElement("link");
|
|
810
|
+
link.rel = "stylesheet";
|
|
811
|
+
link.href = url2;
|
|
880
812
|
const promise = new Promise((res, rej) => {
|
|
881
813
|
link.onload = res;
|
|
882
814
|
link.onerror = rej;
|
|
@@ -885,10 +817,10 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
885
817
|
await promise;
|
|
886
818
|
return link;
|
|
887
819
|
}
|
|
888
|
-
async function addStyleContent(
|
|
889
|
-
const style = document.createElement(
|
|
890
|
-
style.type =
|
|
891
|
-
style.appendChild(document.createTextNode(
|
|
820
|
+
async function addStyleContent(content2) {
|
|
821
|
+
const style = document.createElement("style");
|
|
822
|
+
style.type = "text/css";
|
|
823
|
+
style.appendChild(document.createTextNode(content2));
|
|
892
824
|
const promise = new Promise((res, rej) => {
|
|
893
825
|
style.onload = res;
|
|
894
826
|
style.onerror = rej;
|
|
@@ -903,541 +835,426 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
903
835
|
let result;
|
|
904
836
|
let error;
|
|
905
837
|
let cspMessage;
|
|
906
|
-
const actionPromise = func().then(r => result = r).catch(e => error = e);
|
|
907
|
-
const errorPromise = new Promise(resolve => {
|
|
908
|
-
listeners.push(
|
|
909
|
-
if (message.page() !== this._page || message.type() !==
|
|
910
|
-
|
|
838
|
+
const actionPromise = func().then((r) => result = r).catch((e) => error = e);
|
|
839
|
+
const errorPromise = new Promise((resolve) => {
|
|
840
|
+
listeners.push(import_eventsHelper.eventsHelper.addEventListener(this._page.browserContext, import_browserContext.BrowserContext.Events.Console, (message) => {
|
|
841
|
+
if (message.page() !== this._page || message.type() !== "error")
|
|
842
|
+
return;
|
|
843
|
+
if (message.text().includes("Content-Security-Policy") || message.text().includes("Content Security Policy")) {
|
|
911
844
|
cspMessage = message;
|
|
912
845
|
resolve();
|
|
913
846
|
}
|
|
914
847
|
}));
|
|
915
848
|
});
|
|
916
849
|
await Promise.race([actionPromise, errorPromise]);
|
|
917
|
-
|
|
918
|
-
if (cspMessage)
|
|
919
|
-
|
|
850
|
+
import_eventsHelper.eventsHelper.removeEventListeners(listeners);
|
|
851
|
+
if (cspMessage)
|
|
852
|
+
throw new Error(cspMessage.text());
|
|
853
|
+
if (error)
|
|
854
|
+
throw error;
|
|
920
855
|
return result;
|
|
921
856
|
}
|
|
922
857
|
async retryWithProgressAndTimeouts(progress, timeouts, action) {
|
|
923
|
-
const continuePolling = Symbol(
|
|
858
|
+
const continuePolling = Symbol("continuePolling");
|
|
924
859
|
timeouts = [0, ...timeouts];
|
|
925
860
|
let timeoutIndex = 0;
|
|
926
|
-
while (
|
|
861
|
+
while (true) {
|
|
927
862
|
const timeout = timeouts[Math.min(timeoutIndex++, timeouts.length - 1)];
|
|
928
863
|
if (timeout) {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
864
|
+
const actionPromise = new Promise((f) => setTimeout(f, timeout));
|
|
865
|
+
await progress.race(import_utils.LongStandingScope.raceMultiple([
|
|
866
|
+
this._page.openScope,
|
|
867
|
+
this._detachedScope
|
|
868
|
+
], actionPromise));
|
|
933
869
|
}
|
|
934
|
-
progress.throwIfAborted();
|
|
935
870
|
try {
|
|
936
871
|
const result = await action(continuePolling);
|
|
937
|
-
if (result === continuePolling)
|
|
872
|
+
if (result === continuePolling)
|
|
873
|
+
continue;
|
|
938
874
|
return result;
|
|
939
875
|
} catch (e) {
|
|
940
|
-
if (this.
|
|
876
|
+
if (this.isNonRetriableError(e))
|
|
877
|
+
throw e;
|
|
941
878
|
continue;
|
|
942
879
|
}
|
|
943
880
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
// Retry upon all other errors.
|
|
881
|
+
}
|
|
882
|
+
isNonRetriableError(e) {
|
|
883
|
+
if ((0, import_progress.isAbortError)(e))
|
|
884
|
+
return true;
|
|
885
|
+
if (js.isJavaScriptErrorInEvaluate(e) || (0, import_protocolError.isSessionClosedError)(e))
|
|
886
|
+
return true;
|
|
887
|
+
if (dom.isNonRecoverableDOMError(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
|
|
888
|
+
return true;
|
|
889
|
+
if (this.isDetached())
|
|
890
|
+
return true;
|
|
955
891
|
return false;
|
|
956
892
|
}
|
|
957
893
|
async _retryWithProgressIfNotConnected(progress, selector, strict, performActionPreChecks, action) {
|
|
958
894
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
959
|
-
return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
|
|
960
|
-
if (performActionPreChecks)
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
const result = await resolved.injected.evaluateHandle((injected, {
|
|
967
|
-
info,
|
|
968
|
-
callId
|
|
969
|
-
}) => {
|
|
895
|
+
return this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
|
|
896
|
+
if (performActionPreChecks)
|
|
897
|
+
await this._page.performActionPreChecks(progress);
|
|
898
|
+
const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector, { strict }));
|
|
899
|
+
if (!resolved)
|
|
900
|
+
return continuePolling;
|
|
901
|
+
const result = await progress.raceWithCleanup(resolved.injected.evaluateHandle((injected, { info, callId }) => {
|
|
970
902
|
const elements = injected.querySelectorAll(info.parsed, document);
|
|
971
|
-
if (callId)
|
|
972
|
-
|
|
973
|
-
|
|
903
|
+
if (callId)
|
|
904
|
+
injected.markTargetElements(new Set(elements), callId);
|
|
905
|
+
const element2 = elements[0];
|
|
906
|
+
let log2 = "";
|
|
974
907
|
if (elements.length > 1) {
|
|
975
|
-
if (info.strict)
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
908
|
+
if (info.strict)
|
|
909
|
+
throw injected.strictModeViolationError(info.parsed, elements);
|
|
910
|
+
log2 = ` locator resolved to ${elements.length} elements. Proceeding with the first one: ${injected.previewNode(elements[0])}`;
|
|
911
|
+
} else if (element2) {
|
|
912
|
+
log2 = ` locator resolved to ${injected.previewNode(element2)}`;
|
|
979
913
|
}
|
|
980
|
-
return {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
}, {
|
|
986
|
-
info: resolved.info,
|
|
987
|
-
callId: progress.metadata.id
|
|
988
|
-
});
|
|
989
|
-
const {
|
|
990
|
-
log,
|
|
991
|
-
success
|
|
992
|
-
} = await result.evaluate(r => ({
|
|
993
|
-
log: r.log,
|
|
994
|
-
success: r.success
|
|
995
|
-
}));
|
|
996
|
-
if (log) progress.log(log);
|
|
914
|
+
return { log: log2, success: !!element2, element: element2 };
|
|
915
|
+
}, { info: resolved.info, callId: progress.metadata.id }), (handle) => handle.dispose());
|
|
916
|
+
const { log, success } = await progress.race(result.evaluate((r) => ({ log: r.log, success: r.success })));
|
|
917
|
+
if (log)
|
|
918
|
+
progress.log(log);
|
|
997
919
|
if (!success) {
|
|
998
920
|
result.dispose();
|
|
999
921
|
return continuePolling;
|
|
1000
922
|
}
|
|
1001
|
-
const element = await result.evaluateHandle(r => r.element);
|
|
923
|
+
const element = await progress.race(result.evaluateHandle((r) => r.element));
|
|
1002
924
|
result.dispose();
|
|
1003
925
|
try {
|
|
1004
|
-
const
|
|
1005
|
-
if (
|
|
1006
|
-
progress.log(
|
|
926
|
+
const result2 = await action(element);
|
|
927
|
+
if (result2 === "error:notconnected") {
|
|
928
|
+
progress.log("element was detached from the DOM, retrying");
|
|
1007
929
|
return continuePolling;
|
|
1008
930
|
}
|
|
1009
|
-
return
|
|
931
|
+
return result2;
|
|
1010
932
|
} finally {
|
|
1011
|
-
element
|
|
933
|
+
element?.dispose();
|
|
1012
934
|
}
|
|
1013
935
|
});
|
|
1014
936
|
}
|
|
1015
937
|
async rafrafTimeoutScreenshotElementWithProgress(progress, selector, timeout, options) {
|
|
1016
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, true
|
|
1017
|
-
await handle._frame.rafrafTimeout(timeout);
|
|
1018
|
-
return await this._page.
|
|
938
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true, true, async (handle) => {
|
|
939
|
+
await handle._frame.rafrafTimeout(progress, timeout);
|
|
940
|
+
return await this._page.screenshotter.screenshotElement(progress, handle, options);
|
|
1019
941
|
});
|
|
1020
942
|
}
|
|
1021
|
-
async click(
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
943
|
+
async click(progress, selector, options) {
|
|
944
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
|
|
945
|
+
}
|
|
946
|
+
async dblclick(progress, selector, options) {
|
|
947
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._dblclick(progress, options)));
|
|
948
|
+
}
|
|
949
|
+
async dragAndDrop(progress, source, target, options) {
|
|
950
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, !options.force, async (handle) => {
|
|
951
|
+
return handle._retryPointerAction(progress, "move and down", false, async (point) => {
|
|
952
|
+
await this._page.mouse.move(progress, point.x, point.y);
|
|
953
|
+
await this._page.mouse.down(progress);
|
|
954
|
+
}, {
|
|
1025
955
|
...options,
|
|
1026
|
-
waitAfter:
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
}
|
|
1089
|
-
async textContent(metadata, selector, options = {}, scope) {
|
|
1090
|
-
return this._callOnElementOnceMatches(metadata, selector, (injected, element) => element.textContent, undefined, options, scope);
|
|
1091
|
-
}
|
|
1092
|
-
async innerText(metadata, selector, options = {}, scope) {
|
|
1093
|
-
return this._callOnElementOnceMatches(metadata, selector, (injectedScript, element) => {
|
|
1094
|
-
if (element.namespaceURI !== 'http://www.w3.org/1999/xhtml') throw injectedScript.createStacklessError('Node is not an HTMLElement');
|
|
956
|
+
waitAfter: "disabled",
|
|
957
|
+
position: options.sourcePosition
|
|
958
|
+
});
|
|
959
|
+
}));
|
|
960
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, false, async (handle) => {
|
|
961
|
+
return handle._retryPointerAction(progress, "move and up", false, async (point) => {
|
|
962
|
+
await this._page.mouse.move(progress, point.x, point.y);
|
|
963
|
+
await this._page.mouse.up(progress);
|
|
964
|
+
}, {
|
|
965
|
+
...options,
|
|
966
|
+
waitAfter: "disabled",
|
|
967
|
+
position: options.targetPosition
|
|
968
|
+
});
|
|
969
|
+
}));
|
|
970
|
+
}
|
|
971
|
+
async tap(progress, selector, options) {
|
|
972
|
+
if (!this._page.browserContext._options.hasTouch)
|
|
973
|
+
throw new Error("The page does not support tap. Use hasTouch context option to enable touch support.");
|
|
974
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._tap(progress, options)));
|
|
975
|
+
}
|
|
976
|
+
async fill(progress, selector, value, options) {
|
|
977
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._fill(progress, value, options)));
|
|
978
|
+
}
|
|
979
|
+
async focus(progress, selector, options) {
|
|
980
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._focus(progress)));
|
|
981
|
+
}
|
|
982
|
+
async blur(progress, selector, options) {
|
|
983
|
+
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
|
|
984
|
+
}
|
|
985
|
+
async generateLocatorString(progress, selector) {
|
|
986
|
+
const element = await progress.race(this.selectors.query(selector));
|
|
987
|
+
if (!element)
|
|
988
|
+
throw new Error(`No element matching ${this._asLocator(selector)}`);
|
|
989
|
+
const generated = await progress.race(element.evaluateInUtility(async ([injected, node]) => {
|
|
990
|
+
return injected.generateSelectorSimple(node);
|
|
991
|
+
}, {}));
|
|
992
|
+
if (!generated)
|
|
993
|
+
throw new Error(`Unable to generate locator for ${this._asLocator(selector)}`);
|
|
994
|
+
let frame = element._frame;
|
|
995
|
+
const result = [generated];
|
|
996
|
+
while (frame?.parentFrame()) {
|
|
997
|
+
const frameElement = await progress.race(frame.frameElement());
|
|
998
|
+
if (frameElement) {
|
|
999
|
+
const generated2 = await progress.race(frameElement.evaluateInUtility(async ([injected, node]) => {
|
|
1000
|
+
return injected.generateSelectorSimple(node);
|
|
1001
|
+
}, {}));
|
|
1002
|
+
frameElement.dispose();
|
|
1003
|
+
if (generated2 === "error:notconnected" || !generated2)
|
|
1004
|
+
throw new Error(`Unable to generate locator for ${this._asLocator(selector)}`);
|
|
1005
|
+
result.push(generated2);
|
|
1006
|
+
}
|
|
1007
|
+
frame = frame.parentFrame();
|
|
1008
|
+
}
|
|
1009
|
+
return (0, import_utils.asLocator)(this._page.browserContext._browser.sdkLanguage(), result.reverse().join(" >> internal:control=enter-frame >> "));
|
|
1010
|
+
}
|
|
1011
|
+
async textContent(progress, selector, options, scope) {
|
|
1012
|
+
return this._callOnElementOnceMatches(progress, selector, (injected, element) => element.textContent, void 0, options, scope);
|
|
1013
|
+
}
|
|
1014
|
+
async innerText(progress, selector, options, scope) {
|
|
1015
|
+
return this._callOnElementOnceMatches(progress, selector, (injectedScript, element) => {
|
|
1016
|
+
if (element.namespaceURI !== "http://www.w3.org/1999/xhtml")
|
|
1017
|
+
throw injectedScript.createStacklessError("Node is not an HTMLElement");
|
|
1095
1018
|
return element.innerText;
|
|
1096
|
-
},
|
|
1019
|
+
}, void 0, options, scope);
|
|
1097
1020
|
}
|
|
1098
|
-
async innerHTML(
|
|
1099
|
-
return this._callOnElementOnceMatches(
|
|
1021
|
+
async innerHTML(progress, selector, options, scope) {
|
|
1022
|
+
return this._callOnElementOnceMatches(progress, selector, (injected, element) => element.innerHTML, void 0, options, scope);
|
|
1100
1023
|
}
|
|
1101
|
-
async getAttribute(
|
|
1102
|
-
return this._callOnElementOnceMatches(
|
|
1103
|
-
name
|
|
1104
|
-
}, options, scope);
|
|
1024
|
+
async getAttribute(progress, selector, name, options, scope) {
|
|
1025
|
+
return this._callOnElementOnceMatches(progress, selector, (injected, element, data) => element.getAttribute(data.name), { name }, options, scope);
|
|
1105
1026
|
}
|
|
1106
|
-
async inputValue(
|
|
1107
|
-
return this._callOnElementOnceMatches(
|
|
1108
|
-
const element = injectedScript.retarget(node,
|
|
1109
|
-
if (!element || element.nodeName !==
|
|
1027
|
+
async inputValue(progress, selector, options, scope) {
|
|
1028
|
+
return this._callOnElementOnceMatches(progress, selector, (injectedScript, node) => {
|
|
1029
|
+
const element = injectedScript.retarget(node, "follow-label");
|
|
1030
|
+
if (!element || element.nodeName !== "INPUT" && element.nodeName !== "TEXTAREA" && element.nodeName !== "SELECT")
|
|
1031
|
+
throw injectedScript.createStacklessError("Node is not an <input>, <textarea> or <select> element");
|
|
1110
1032
|
return element.value;
|
|
1111
|
-
},
|
|
1112
|
-
}
|
|
1113
|
-
async highlight(selector) {
|
|
1114
|
-
const resolved = await this.selectors.resolveInjectedForSelector(selector);
|
|
1115
|
-
if (!resolved)
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}) => {
|
|
1033
|
+
}, void 0, options, scope);
|
|
1034
|
+
}
|
|
1035
|
+
async highlight(progress, selector) {
|
|
1036
|
+
const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector));
|
|
1037
|
+
if (!resolved)
|
|
1038
|
+
return;
|
|
1039
|
+
return await progress.race(resolved.injected.evaluate((injected, { info }) => {
|
|
1119
1040
|
return injected.highlight(info.parsed);
|
|
1120
|
-
}, {
|
|
1121
|
-
info: resolved.info
|
|
1122
|
-
});
|
|
1041
|
+
}, { info: resolved.info }));
|
|
1123
1042
|
}
|
|
1124
1043
|
async hideHighlight() {
|
|
1125
1044
|
return this.raceAgainstEvaluationStallingEvents(async () => {
|
|
1126
1045
|
const context = await this._utilityContext();
|
|
1127
1046
|
const injectedScript = await context.injectedScript();
|
|
1128
|
-
return await injectedScript.evaluate(injected => {
|
|
1047
|
+
return await injectedScript.evaluate((injected) => {
|
|
1129
1048
|
return injected.hideHighlight();
|
|
1130
1049
|
});
|
|
1131
1050
|
});
|
|
1132
1051
|
}
|
|
1133
|
-
async _elementState(
|
|
1134
|
-
const result = await this._callOnElementOnceMatches(
|
|
1052
|
+
async _elementState(progress, selector, state, options, scope) {
|
|
1053
|
+
const result = await this._callOnElementOnceMatches(progress, selector, (injected, element, data) => {
|
|
1135
1054
|
return injected.elementState(element, data.state);
|
|
1136
|
-
}, {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
if (result.received === 'error:notconnected') dom.throwElementIsNotAttached();
|
|
1055
|
+
}, { state }, options, scope);
|
|
1056
|
+
if (result.received === "error:notconnected")
|
|
1057
|
+
dom.throwElementIsNotAttached();
|
|
1140
1058
|
return result.matches;
|
|
1141
1059
|
}
|
|
1142
|
-
async isVisible(
|
|
1143
|
-
|
|
1144
|
-
return
|
|
1145
|
-
progress.log(` checking visibility of ${this._asLocator(selector)}`);
|
|
1146
|
-
return await this.isVisibleInternal(selector, options, scope);
|
|
1147
|
-
}, this._page._timeoutSettings.timeout({}));
|
|
1060
|
+
async isVisible(progress, selector, options = {}, scope) {
|
|
1061
|
+
progress.log(` checking visibility of ${this._asLocator(selector)}`);
|
|
1062
|
+
return await this.isVisibleInternal(progress, selector, options, scope);
|
|
1148
1063
|
}
|
|
1149
|
-
async isVisibleInternal(selector, options = {}, scope) {
|
|
1064
|
+
async isVisibleInternal(progress, selector, options = {}, scope) {
|
|
1150
1065
|
try {
|
|
1151
|
-
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
|
|
1152
|
-
if (!resolved)
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
root
|
|
1156
|
-
}) => {
|
|
1066
|
+
const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector, options, scope));
|
|
1067
|
+
if (!resolved)
|
|
1068
|
+
return false;
|
|
1069
|
+
return await progress.race(resolved.injected.evaluate((injected, { info, root }) => {
|
|
1157
1070
|
const element = injected.querySelector(info.parsed, root || document, info.strict);
|
|
1158
|
-
const state = element ? injected.elementState(element,
|
|
1159
|
-
matches: false,
|
|
1160
|
-
received: 'error:notconnected'
|
|
1161
|
-
};
|
|
1071
|
+
const state = element ? injected.elementState(element, "visible") : { matches: false, received: "error:notconnected" };
|
|
1162
1072
|
return state.matches;
|
|
1163
|
-
}, {
|
|
1164
|
-
info: resolved.info,
|
|
1165
|
-
root: resolved.frame === this ? scope : undefined
|
|
1166
|
-
});
|
|
1073
|
+
}, { info: resolved.info, root: resolved.frame === this ? scope : void 0 }));
|
|
1167
1074
|
} catch (e) {
|
|
1168
|
-
if (
|
|
1075
|
+
if (this.isNonRetriableError(e))
|
|
1076
|
+
throw e;
|
|
1169
1077
|
return false;
|
|
1170
1078
|
}
|
|
1171
1079
|
}
|
|
1172
|
-
async isHidden(
|
|
1173
|
-
return !
|
|
1174
|
-
}
|
|
1175
|
-
async isDisabled(metadata, selector, options = {}, scope) {
|
|
1176
|
-
return this._elementState(metadata, selector, 'disabled', options, scope);
|
|
1177
|
-
}
|
|
1178
|
-
async isEnabled(metadata, selector, options = {}, scope) {
|
|
1179
|
-
return this._elementState(metadata, selector, 'enabled', options, scope);
|
|
1180
|
-
}
|
|
1181
|
-
async isEditable(metadata, selector, options = {}, scope) {
|
|
1182
|
-
return this._elementState(metadata, selector, 'editable', options, scope);
|
|
1183
|
-
}
|
|
1184
|
-
async isChecked(metadata, selector, options = {}, scope) {
|
|
1185
|
-
return this._elementState(metadata, selector, 'checked', options, scope);
|
|
1186
|
-
}
|
|
1187
|
-
async hover(metadata, selector, options = {}) {
|
|
1188
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1189
|
-
return controller.run(async progress => {
|
|
1190
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._hover(progress, options)));
|
|
1191
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1192
|
-
}
|
|
1193
|
-
async selectOption(metadata, selector, elements, values, options = {}) {
|
|
1194
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1195
|
-
return controller.run(async progress => {
|
|
1196
|
-
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._selectOption(progress, elements, values, options));
|
|
1197
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1198
|
-
}
|
|
1199
|
-
async setInputFiles(metadata, selector, params) {
|
|
1200
|
-
const inputFileItems = await (0, _fileUploadUtils.prepareFilesForUpload)(this, params);
|
|
1201
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1202
|
-
return controller.run(async progress => {
|
|
1203
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /* performActionPreChecks */, handle => handle._setInputFiles(progress, inputFileItems)));
|
|
1204
|
-
}, this._page._timeoutSettings.timeout(params));
|
|
1205
|
-
}
|
|
1206
|
-
async type(metadata, selector, text, options = {}) {
|
|
1207
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1208
|
-
return controller.run(async progress => {
|
|
1209
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._type(progress, text, options)));
|
|
1210
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1211
|
-
}
|
|
1212
|
-
async press(metadata, selector, key, options = {}) {
|
|
1213
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1214
|
-
return controller.run(async progress => {
|
|
1215
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._press(progress, key, options)));
|
|
1216
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1217
|
-
}
|
|
1218
|
-
async check(metadata, selector, options = {}) {
|
|
1219
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1220
|
-
return controller.run(async progress => {
|
|
1221
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, true, options)));
|
|
1222
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1223
|
-
}
|
|
1224
|
-
async uncheck(metadata, selector, options = {}) {
|
|
1225
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1226
|
-
return controller.run(async progress => {
|
|
1227
|
-
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, false, options)));
|
|
1228
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1229
|
-
}
|
|
1230
|
-
async waitForTimeout(metadata, timeout) {
|
|
1231
|
-
const controller = new _progress.ProgressController(metadata, this);
|
|
1232
|
-
return controller.run(async () => {
|
|
1233
|
-
await new Promise(resolve => setTimeout(resolve, timeout));
|
|
1234
|
-
});
|
|
1080
|
+
async isHidden(progress, selector, options = {}, scope) {
|
|
1081
|
+
return !await this.isVisible(progress, selector, options, scope);
|
|
1235
1082
|
}
|
|
1236
|
-
async
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
}
|
|
1242
|
-
async
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1083
|
+
async isDisabled(progress, selector, options, scope) {
|
|
1084
|
+
return this._elementState(progress, selector, "disabled", options, scope);
|
|
1085
|
+
}
|
|
1086
|
+
async isEnabled(progress, selector, options, scope) {
|
|
1087
|
+
return this._elementState(progress, selector, "enabled", options, scope);
|
|
1088
|
+
}
|
|
1089
|
+
async isEditable(progress, selector, options, scope) {
|
|
1090
|
+
return this._elementState(progress, selector, "editable", options, scope);
|
|
1091
|
+
}
|
|
1092
|
+
async isChecked(progress, selector, options, scope) {
|
|
1093
|
+
return this._elementState(progress, selector, "checked", options, scope);
|
|
1094
|
+
}
|
|
1095
|
+
async hover(progress, selector, options) {
|
|
1096
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._hover(progress, options)));
|
|
1097
|
+
}
|
|
1098
|
+
async selectOption(progress, selector, elements, values, options) {
|
|
1099
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._selectOption(progress, elements, values, options));
|
|
1100
|
+
}
|
|
1101
|
+
async setInputFiles(progress, selector, params) {
|
|
1102
|
+
const inputFileItems = await (0, import_fileUploadUtils.prepareFilesForUpload)(this, params);
|
|
1103
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true, (handle) => handle._setInputFiles(progress, inputFileItems)));
|
|
1104
|
+
}
|
|
1105
|
+
async type(progress, selector, text, options) {
|
|
1106
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._type(progress, text, options)));
|
|
1107
|
+
}
|
|
1108
|
+
async press(progress, selector, key, options) {
|
|
1109
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._press(progress, key, options)));
|
|
1110
|
+
}
|
|
1111
|
+
async check(progress, selector, options) {
|
|
1112
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, true, options)));
|
|
1113
|
+
}
|
|
1114
|
+
async uncheck(progress, selector, options) {
|
|
1115
|
+
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force, (handle) => handle._setChecked(progress, false, options)));
|
|
1116
|
+
}
|
|
1117
|
+
async waitForTimeout(progress, timeout) {
|
|
1118
|
+
return progress.wait(timeout);
|
|
1119
|
+
}
|
|
1120
|
+
async ariaSnapshot(progress, selector, options) {
|
|
1121
|
+
return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => progress.race(handle.ariaSnapshot(options)));
|
|
1122
|
+
}
|
|
1123
|
+
// TODO: remove errorResultHandler once legacy progress is removed.
|
|
1124
|
+
async expect(progress, selector, options, timeout, errorResultHandler) {
|
|
1125
|
+
progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${timeout ? ` with timeout ${timeout}ms` : ""}`);
|
|
1126
|
+
const result = await this._expectImpl(progress, selector, options, errorResultHandler);
|
|
1251
1127
|
return result;
|
|
1252
1128
|
}
|
|
1253
|
-
async _expectImpl(
|
|
1254
|
-
const lastIntermediateResult = {
|
|
1255
|
-
|
|
1129
|
+
async _expectImpl(progress, selector, options, errorResultHandler) {
|
|
1130
|
+
const lastIntermediateResult = { isSet: false };
|
|
1131
|
+
const fixupMetadataError = (result) => {
|
|
1132
|
+
if (result.matches === options.isNot)
|
|
1133
|
+
progress.metadata.error = { error: { name: "Expect", message: "Expect failed" } };
|
|
1134
|
+
};
|
|
1135
|
+
const handleError = (e, isProgressError) => {
|
|
1136
|
+
if (js.isJavaScriptErrorInEvaluate(e) || (0, import_selectorParser.isInvalidSelectorError)(e))
|
|
1137
|
+
throw e;
|
|
1138
|
+
const result = { matches: options.isNot, log: (0, import_callLog.compressCallLog)(progress.metadata.log) };
|
|
1139
|
+
if (lastIntermediateResult.isSet)
|
|
1140
|
+
result.received = lastIntermediateResult.received;
|
|
1141
|
+
if (e instanceof import_errors.TimeoutError)
|
|
1142
|
+
result.timedOut = true;
|
|
1143
|
+
fixupMetadataError(result);
|
|
1144
|
+
return isProgressError && errorResultHandler ? errorResultHandler(result) : result;
|
|
1256
1145
|
};
|
|
1146
|
+
progress.legacySetErrorHandler((e) => handleError(e, true));
|
|
1257
1147
|
try {
|
|
1258
|
-
|
|
1259
|
-
const start = timeout > 0 ? (0, _utils.monotonicTime)() : 0;
|
|
1260
|
-
|
|
1261
|
-
// Step 1: perform locator handlers checkpoint with a specified timeout.
|
|
1262
|
-
await new _progress.ProgressController(metadata, this).run(async progress => {
|
|
1263
|
-
progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`);
|
|
1148
|
+
if (selector)
|
|
1264
1149
|
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
// Step 2: perform one-shot expect check without a timeout.
|
|
1269
|
-
// Supports the case of `expect(locator).toBeVisible({ timeout: 1 })`
|
|
1270
|
-
// that should succeed when the locator is already visible.
|
|
1150
|
+
await this._page.performActionPreChecks(progress);
|
|
1151
|
+
progress.legacyDisableTimeout();
|
|
1271
1152
|
try {
|
|
1272
|
-
const resultOneShot = await
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (resultOneShot.matches !== options.isNot) return resultOneShot;
|
|
1153
|
+
const resultOneShot = await this._expectInternal(progress, selector, options, lastIntermediateResult, true);
|
|
1154
|
+
if (resultOneShot.matches !== options.isNot)
|
|
1155
|
+
return resultOneShot;
|
|
1276
1156
|
} catch (e) {
|
|
1277
|
-
if (
|
|
1278
|
-
|
|
1279
|
-
}
|
|
1280
|
-
if (timeout > 0) {
|
|
1281
|
-
const elapsed = (0, _utils.monotonicTime)() - start;
|
|
1282
|
-
timeout -= elapsed;
|
|
1157
|
+
if (this.isNonRetriableError(e))
|
|
1158
|
+
throw e;
|
|
1283
1159
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
await this._page.performActionPreChecks(progress);
|
|
1295
|
-
const {
|
|
1296
|
-
matches,
|
|
1297
|
-
received
|
|
1298
|
-
} = await this._expectInternal(progress, selector, options, lastIntermediateResult);
|
|
1299
|
-
if (matches === options.isNot) {
|
|
1300
|
-
// Keep waiting in these cases:
|
|
1301
|
-
// expect(locator).conditionThatDoesNotMatch
|
|
1302
|
-
// expect(locator).not.conditionThatDoesMatch
|
|
1303
|
-
return continuePolling;
|
|
1304
|
-
}
|
|
1305
|
-
return {
|
|
1306
|
-
matches,
|
|
1307
|
-
received
|
|
1308
|
-
};
|
|
1309
|
-
});
|
|
1310
|
-
}, timeout);
|
|
1311
|
-
} catch (e) {
|
|
1312
|
-
// Q: Why not throw upon isSessionClosedError(e) as in other places?
|
|
1313
|
-
// A: We want user to receive a friendly message containing the last intermediate result.
|
|
1314
|
-
if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;
|
|
1315
|
-
const result = {
|
|
1316
|
-
matches: options.isNot,
|
|
1317
|
-
log: (0, _callLog.compressCallLog)(metadata.log)
|
|
1318
|
-
};
|
|
1319
|
-
if (lastIntermediateResult.isSet) result.received = lastIntermediateResult.received;
|
|
1320
|
-
if (e instanceof _errors.TimeoutError) result.timedOut = true;
|
|
1160
|
+
progress.legacyEnableTimeout();
|
|
1161
|
+
const result = await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1e3], async (continuePolling) => {
|
|
1162
|
+
await this._page.performActionPreChecks(progress);
|
|
1163
|
+
const { matches, received } = await this._expectInternal(progress, selector, options, lastIntermediateResult, false);
|
|
1164
|
+
if (matches === options.isNot) {
|
|
1165
|
+
return continuePolling;
|
|
1166
|
+
}
|
|
1167
|
+
return { matches, received };
|
|
1168
|
+
});
|
|
1169
|
+
fixupMetadataError(result);
|
|
1321
1170
|
return result;
|
|
1171
|
+
} catch (e) {
|
|
1172
|
+
return handleError(e, false);
|
|
1322
1173
|
}
|
|
1323
1174
|
}
|
|
1324
|
-
async _expectInternal(progress, selector, options, lastIntermediateResult) {
|
|
1325
|
-
|
|
1326
|
-
const selectorInFrame = await this.selectors.resolveFrameForSelector(selector, {
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
const
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
info,
|
|
1348
|
-
options,
|
|
1349
|
-
callId
|
|
1350
|
-
}) => {
|
|
1351
|
-
const elements = info ? injected.querySelectorAll(info.parsed, document) : [];
|
|
1352
|
-
if (callId) injected.markTargetElements(new Set(elements), callId);
|
|
1353
|
-
const isArray = options.expression === 'to.have.count' || options.expression.endsWith('.array');
|
|
1354
|
-
let log = '';
|
|
1355
|
-
if (isArray) log = ` locator resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`;else if (elements.length > 1) throw injected.strictModeViolationError(info.parsed, elements);else if (elements.length) log = ` locator resolved to ${injected.previewNode(elements[0])}`;
|
|
1356
|
-
return {
|
|
1357
|
-
log,
|
|
1358
|
-
...(await injected.expect(elements[0], options, elements))
|
|
1359
|
-
};
|
|
1360
|
-
}, {
|
|
1361
|
-
info,
|
|
1362
|
-
options,
|
|
1363
|
-
callId: progress.metadata.id
|
|
1364
|
-
});
|
|
1365
|
-
if (log) progress.log(log);
|
|
1366
|
-
// Note: missingReceived avoids `unexpected value "undefined"` when element was not found.
|
|
1175
|
+
async _expectInternal(progress, selector, options, lastIntermediateResult, noAbort) {
|
|
1176
|
+
const race = (p) => noAbort ? p : progress.race(p);
|
|
1177
|
+
const selectorInFrame = selector ? await race(this.selectors.resolveFrameForSelector(selector, { strict: true })) : void 0;
|
|
1178
|
+
const { frame, info } = selectorInFrame || { frame: this, info: void 0 };
|
|
1179
|
+
const world = options.expression === "to.have.property" ? "main" : info?.world ?? "utility";
|
|
1180
|
+
const context = await race(frame._context(world));
|
|
1181
|
+
const injected = await race(context.injectedScript());
|
|
1182
|
+
const { log, matches, received, missingReceived } = await race(injected.evaluate(async (injected2, { info: info2, options: options2, callId }) => {
|
|
1183
|
+
const elements = info2 ? injected2.querySelectorAll(info2.parsed, document) : [];
|
|
1184
|
+
if (callId)
|
|
1185
|
+
injected2.markTargetElements(new Set(elements), callId);
|
|
1186
|
+
const isArray = options2.expression === "to.have.count" || options2.expression.endsWith(".array");
|
|
1187
|
+
let log2 = "";
|
|
1188
|
+
if (isArray)
|
|
1189
|
+
log2 = ` locator resolved to ${elements.length} element${elements.length === 1 ? "" : "s"}`;
|
|
1190
|
+
else if (elements.length > 1)
|
|
1191
|
+
throw injected2.strictModeViolationError(info2.parsed, elements);
|
|
1192
|
+
else if (elements.length)
|
|
1193
|
+
log2 = ` locator resolved to ${injected2.previewNode(elements[0])}`;
|
|
1194
|
+
return { log: log2, ...await injected2.expect(elements[0], options2, elements) };
|
|
1195
|
+
}, { info, options, callId: progress.metadata.id }));
|
|
1196
|
+
if (log)
|
|
1197
|
+
progress.log(log);
|
|
1367
1198
|
if (matches === options.isNot) {
|
|
1368
|
-
lastIntermediateResult.received = missingReceived ?
|
|
1199
|
+
lastIntermediateResult.received = missingReceived ? "<element(s) not found>" : received;
|
|
1369
1200
|
lastIntermediateResult.isSet = true;
|
|
1370
|
-
if (!missingReceived && !Array.isArray(received))
|
|
1201
|
+
if (!missingReceived && !Array.isArray(received))
|
|
1202
|
+
progress.log(` unexpected value "${renderUnexpectedValue(options.expression, received)}"`);
|
|
1371
1203
|
}
|
|
1372
|
-
return {
|
|
1373
|
-
matches,
|
|
1374
|
-
received
|
|
1375
|
-
};
|
|
1204
|
+
return { matches, received };
|
|
1376
1205
|
}
|
|
1377
|
-
async
|
|
1378
|
-
|
|
1379
|
-
|
|
1206
|
+
async waitForFunctionExpression(progress, expression, isFunction, arg, options, world = "main") {
|
|
1207
|
+
if (typeof options.pollingInterval === "number")
|
|
1208
|
+
(0, import_utils.assert)(options.pollingInterval > 0, "Cannot poll with non-positive interval: " + options.pollingInterval);
|
|
1380
1209
|
expression = js.normalizeEvaluationExpression(expression, isFunction);
|
|
1381
|
-
return
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
return result;
|
|
1405
|
-
};
|
|
1406
|
-
let fulfill;
|
|
1407
|
-
let reject;
|
|
1408
|
-
let aborted = false;
|
|
1409
|
-
const result = new Promise((f, r) => {
|
|
1410
|
-
fulfill = f;
|
|
1411
|
-
reject = r;
|
|
1412
|
-
});
|
|
1413
|
-
const next = () => {
|
|
1414
|
-
if (aborted) return;
|
|
1415
|
-
try {
|
|
1416
|
-
const success = predicate();
|
|
1417
|
-
if (success) {
|
|
1418
|
-
fulfill(success);
|
|
1419
|
-
return;
|
|
1420
|
-
}
|
|
1421
|
-
if (typeof polling !== 'number') injected.builtinRequestAnimationFrame(next);else injected.builtinSetTimeout(next, polling);
|
|
1422
|
-
} catch (e) {
|
|
1423
|
-
reject(e);
|
|
1424
|
-
}
|
|
1425
|
-
};
|
|
1426
|
-
next();
|
|
1427
|
-
return {
|
|
1428
|
-
result,
|
|
1429
|
-
abort: () => aborted = true
|
|
1430
|
-
};
|
|
1431
|
-
}, {
|
|
1432
|
-
expression,
|
|
1433
|
-
isFunction,
|
|
1434
|
-
polling: options.pollingInterval,
|
|
1435
|
-
arg
|
|
1210
|
+
return this.retryWithProgressAndTimeouts(progress, [100], async () => {
|
|
1211
|
+
const context = world === "main" ? await progress.race(this._mainContext()) : await progress.race(this._utilityContext());
|
|
1212
|
+
const injectedScript = await progress.race(context.injectedScript());
|
|
1213
|
+
const handle = await progress.race(injectedScript.evaluateHandle((injected, { expression: expression2, isFunction: isFunction2, polling, arg: arg2 }) => {
|
|
1214
|
+
const predicate = () => {
|
|
1215
|
+
let result3 = globalThis.eval(expression2);
|
|
1216
|
+
if (isFunction2 === true) {
|
|
1217
|
+
result3 = result3(arg2);
|
|
1218
|
+
} else if (isFunction2 === false) {
|
|
1219
|
+
result3 = result3;
|
|
1220
|
+
} else {
|
|
1221
|
+
if (typeof result3 === "function")
|
|
1222
|
+
result3 = result3(arg2);
|
|
1223
|
+
}
|
|
1224
|
+
return result3;
|
|
1225
|
+
};
|
|
1226
|
+
let fulfill;
|
|
1227
|
+
let reject;
|
|
1228
|
+
let aborted = false;
|
|
1229
|
+
const result2 = new Promise((f, r) => {
|
|
1230
|
+
fulfill = f;
|
|
1231
|
+
reject = r;
|
|
1436
1232
|
});
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1233
|
+
const next = () => {
|
|
1234
|
+
if (aborted)
|
|
1235
|
+
return;
|
|
1236
|
+
try {
|
|
1237
|
+
const success = predicate();
|
|
1238
|
+
if (success) {
|
|
1239
|
+
fulfill(success);
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
if (typeof polling !== "number")
|
|
1243
|
+
injected.utils.builtins.requestAnimationFrame(next);
|
|
1244
|
+
else
|
|
1245
|
+
injected.utils.builtins.setTimeout(next, polling);
|
|
1246
|
+
} catch (e) {
|
|
1247
|
+
reject(e);
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1250
|
+
next();
|
|
1251
|
+
return { result: result2, abort: () => aborted = true };
|
|
1252
|
+
}, { expression, isFunction, polling: options.pollingInterval, arg }));
|
|
1253
|
+
progress.cleanupWhenAborted(() => handle.evaluate((h) => h.abort()).finally(() => handle.dispose()));
|
|
1254
|
+
const result = await progress.race(handle.evaluateHandle((h) => h.result));
|
|
1255
|
+
handle.dispose();
|
|
1256
|
+
return result;
|
|
1257
|
+
});
|
|
1441
1258
|
}
|
|
1442
1259
|
async waitForFunctionValueInUtility(progress, pageFunction) {
|
|
1443
1260
|
const expression = `() => {
|
|
@@ -1446,220 +1263,193 @@ class Frame extends _instrumentation.SdkObject {
|
|
|
1446
1263
|
return result;
|
|
1447
1264
|
return JSON.stringify(result);
|
|
1448
1265
|
}`;
|
|
1449
|
-
const handle = await this.
|
|
1450
|
-
timeout: progress.timeUntilDeadline()
|
|
1451
|
-
}, 'utility');
|
|
1266
|
+
const handle = await this.waitForFunctionExpression(progress, expression, true, void 0, {}, "utility");
|
|
1452
1267
|
return JSON.parse(handle.rawValue());
|
|
1453
1268
|
}
|
|
1454
1269
|
async title() {
|
|
1455
1270
|
const context = await this._utilityContext();
|
|
1456
1271
|
return context.evaluate(() => document.title);
|
|
1457
1272
|
}
|
|
1458
|
-
async rafrafTimeout(timeout) {
|
|
1459
|
-
if (timeout === 0)
|
|
1460
|
-
|
|
1273
|
+
async rafrafTimeout(progress, timeout) {
|
|
1274
|
+
if (timeout === 0)
|
|
1275
|
+
return;
|
|
1276
|
+
const context = await progress.race(this._utilityContext());
|
|
1461
1277
|
await Promise.all([
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1278
|
+
// wait for double raf
|
|
1279
|
+
progress.race(context.evaluate(() => new Promise((x) => {
|
|
1280
|
+
requestAnimationFrame(() => {
|
|
1281
|
+
requestAnimationFrame(x);
|
|
1282
|
+
});
|
|
1283
|
+
}))),
|
|
1284
|
+
progress.wait(timeout)
|
|
1285
|
+
]);
|
|
1468
1286
|
}
|
|
1469
1287
|
_onDetached() {
|
|
1470
1288
|
this._stopNetworkIdleTimer();
|
|
1471
|
-
this._detachedScope.close(new Error(
|
|
1289
|
+
this._detachedScope.close(new Error("Frame was detached"));
|
|
1472
1290
|
for (const data of this._contextData.values()) {
|
|
1473
|
-
if (data.context)
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
});
|
|
1291
|
+
if (data.context)
|
|
1292
|
+
data.context.contextDestroyed("Frame was detached");
|
|
1293
|
+
data.contextPromise.resolve({ destroyedReason: "Frame was detached" });
|
|
1477
1294
|
}
|
|
1478
|
-
if (this._parentFrame)
|
|
1295
|
+
if (this._parentFrame)
|
|
1296
|
+
this._parentFrame._childFrames.delete(this);
|
|
1479
1297
|
this._parentFrame = null;
|
|
1480
1298
|
}
|
|
1481
|
-
async _callOnElementOnceMatches(
|
|
1299
|
+
async _callOnElementOnceMatches(progress, selector, body, taskData, options, scope) {
|
|
1482
1300
|
const callbackText = body.toString();
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
progress.
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
const
|
|
1491
|
-
|
|
1492
|
-
success
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
};
|
|
1506
|
-
const log = ` locator resolved to ${injected.previewNode(element)}`;
|
|
1507
|
-
if (callId) injected.markTargetElements(new Set([element]), callId);
|
|
1508
|
-
return {
|
|
1509
|
-
log,
|
|
1510
|
-
success: true,
|
|
1511
|
-
value: callback(injected, element, taskData)
|
|
1512
|
-
};
|
|
1513
|
-
}, {
|
|
1514
|
-
info: resolved.info,
|
|
1515
|
-
callbackText,
|
|
1516
|
-
taskData,
|
|
1517
|
-
callId: progress.metadata.id,
|
|
1518
|
-
root: resolved.frame === this ? scope : undefined
|
|
1519
|
-
});
|
|
1520
|
-
if (log) progress.log(log);
|
|
1521
|
-
if (!success) return continuePolling;
|
|
1522
|
-
return value;
|
|
1523
|
-
});
|
|
1524
|
-
return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
|
|
1525
|
-
}, this._page._timeoutSettings.timeout(options));
|
|
1301
|
+
progress.log(`waiting for ${this._asLocator(selector)}`);
|
|
1302
|
+
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async (continuePolling) => {
|
|
1303
|
+
const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector, options, scope));
|
|
1304
|
+
if (!resolved)
|
|
1305
|
+
return continuePolling;
|
|
1306
|
+
const { log, success, value } = await progress.race(resolved.injected.evaluate((injected, { info, callbackText: callbackText2, taskData: taskData2, callId, root }) => {
|
|
1307
|
+
const callback = injected.eval(callbackText2);
|
|
1308
|
+
const element = injected.querySelector(info.parsed, root || document, info.strict);
|
|
1309
|
+
if (!element)
|
|
1310
|
+
return { success: false };
|
|
1311
|
+
const log2 = ` locator resolved to ${injected.previewNode(element)}`;
|
|
1312
|
+
if (callId)
|
|
1313
|
+
injected.markTargetElements(/* @__PURE__ */ new Set([element]), callId);
|
|
1314
|
+
return { log: log2, success: true, value: callback(injected, element, taskData2) };
|
|
1315
|
+
}, { info: resolved.info, callbackText, taskData, callId: progress.metadata.id, root: resolved.frame === this ? scope : void 0 }));
|
|
1316
|
+
if (log)
|
|
1317
|
+
progress.log(log);
|
|
1318
|
+
if (!success)
|
|
1319
|
+
return continuePolling;
|
|
1320
|
+
return value;
|
|
1321
|
+
});
|
|
1322
|
+
return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
|
|
1526
1323
|
}
|
|
1527
1324
|
_setContext(world, context) {
|
|
1528
1325
|
const data = this._contextData.get(world);
|
|
1529
1326
|
data.context = context;
|
|
1530
|
-
if (context)
|
|
1327
|
+
if (context)
|
|
1328
|
+
data.contextPromise.resolve(context);
|
|
1329
|
+
else
|
|
1330
|
+
data.contextPromise = new import_manualPromise.ManualPromise();
|
|
1531
1331
|
}
|
|
1532
1332
|
_contextCreated(world, context) {
|
|
1533
1333
|
const data = this._contextData.get(world);
|
|
1534
|
-
// In case of multiple sessions to the same target, there's a race between
|
|
1535
|
-
// connections so we might end up creating multiple isolated worlds.
|
|
1536
|
-
// We can use either.
|
|
1537
1334
|
if (data.context) {
|
|
1538
|
-
data.context.contextDestroyed(
|
|
1335
|
+
data.context.contextDestroyed("Execution context was destroyed, most likely because of a navigation");
|
|
1539
1336
|
this._setContext(world, null);
|
|
1540
1337
|
}
|
|
1541
1338
|
this._setContext(world, context);
|
|
1542
1339
|
}
|
|
1543
1340
|
_contextDestroyed(context) {
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
context.contextDestroyed('Execution context was destroyed, most likely because of a navigation');
|
|
1341
|
+
if (this._detachedScope.isClosed())
|
|
1342
|
+
return;
|
|
1343
|
+
context.contextDestroyed("Execution context was destroyed, most likely because of a navigation");
|
|
1548
1344
|
for (const [world, data] of this._contextData) {
|
|
1549
|
-
if (data.context === context)
|
|
1345
|
+
if (data.context === context)
|
|
1346
|
+
this._setContext(world, null);
|
|
1550
1347
|
}
|
|
1551
1348
|
}
|
|
1552
1349
|
_startNetworkIdleTimer() {
|
|
1553
|
-
(0,
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
// after the frame was detached - probably a race in the Firefox itself.
|
|
1557
|
-
if (this._firedLifecycleEvents.has('networkidle') || this._detachedScope.isClosed()) return;
|
|
1350
|
+
(0, import_utils.assert)(!this._networkIdleTimer);
|
|
1351
|
+
if (this._firedLifecycleEvents.has("networkidle") || this._detachedScope.isClosed())
|
|
1352
|
+
return;
|
|
1558
1353
|
this._networkIdleTimer = setTimeout(() => {
|
|
1559
1354
|
this._firedNetworkIdleSelf = true;
|
|
1560
1355
|
this._page.mainFrame()._recalculateNetworkIdle();
|
|
1561
1356
|
}, 500);
|
|
1562
1357
|
}
|
|
1563
1358
|
_stopNetworkIdleTimer() {
|
|
1564
|
-
if (this._networkIdleTimer)
|
|
1565
|
-
|
|
1359
|
+
if (this._networkIdleTimer)
|
|
1360
|
+
clearTimeout(this._networkIdleTimer);
|
|
1361
|
+
this._networkIdleTimer = void 0;
|
|
1566
1362
|
this._firedNetworkIdleSelf = false;
|
|
1567
1363
|
}
|
|
1568
1364
|
async extendInjectedScript(source, arg) {
|
|
1569
|
-
const context = await this._context(
|
|
1365
|
+
const context = await this._context("main");
|
|
1570
1366
|
const injectedScriptHandle = await context.injectedScript();
|
|
1571
|
-
return injectedScriptHandle.evaluateHandle((injectedScript, {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
}) => {
|
|
1575
|
-
return injectedScript.extend(source, arg);
|
|
1576
|
-
}, {
|
|
1577
|
-
source,
|
|
1578
|
-
arg
|
|
1579
|
-
});
|
|
1367
|
+
return injectedScriptHandle.evaluateHandle((injectedScript, { source: source2, arg: arg2 }) => {
|
|
1368
|
+
return injectedScript.extend(source2, arg2);
|
|
1369
|
+
}, { source, arg });
|
|
1580
1370
|
}
|
|
1581
1371
|
async resetStorageForCurrentOriginBestEffort(newStorage) {
|
|
1582
1372
|
const context = await this._utilityContext();
|
|
1583
|
-
await context.evaluate(async ({
|
|
1584
|
-
ls
|
|
1585
|
-
}) => {
|
|
1586
|
-
// Clean DOMStorage.
|
|
1373
|
+
await context.evaluate(async ({ ls }) => {
|
|
1587
1374
|
sessionStorage.clear();
|
|
1588
1375
|
localStorage.clear();
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
for (const entry of ls || []) localStorage[entry.name] = entry.value;
|
|
1592
|
-
|
|
1593
|
-
// Clean Service Workers
|
|
1376
|
+
for (const entry of ls || [])
|
|
1377
|
+
localStorage[entry.name] = entry.value;
|
|
1594
1378
|
const registrations = navigator.serviceWorker ? await navigator.serviceWorker.getRegistrations() : [];
|
|
1595
|
-
await Promise.all(registrations.map(async r => {
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1379
|
+
await Promise.all(registrations.map(async (r) => {
|
|
1380
|
+
if (!r.installing && !r.waiting && !r.active)
|
|
1381
|
+
r.unregister().catch(() => {
|
|
1382
|
+
});
|
|
1383
|
+
else
|
|
1384
|
+
await r.unregister().catch(() => {
|
|
1385
|
+
});
|
|
1602
1386
|
}));
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
var _indexedDB$databases, _indexedDB;
|
|
1607
|
-
// Do not wait for the callback - it is called on timer in Chromium (slow).
|
|
1608
|
-
if (db.name) indexedDB.deleteDatabase(db.name);
|
|
1387
|
+
for (const db of await indexedDB.databases?.() || []) {
|
|
1388
|
+
if (db.name)
|
|
1389
|
+
indexedDB.deleteDatabase(db.name);
|
|
1609
1390
|
}
|
|
1610
|
-
}, {
|
|
1611
|
-
|
|
1612
|
-
}).catch(() => {});
|
|
1391
|
+
}, { ls: newStorage?.localStorage }).catch(() => {
|
|
1392
|
+
});
|
|
1613
1393
|
}
|
|
1614
1394
|
_asLocator(selector) {
|
|
1615
|
-
return (0,
|
|
1395
|
+
return (0, import_utils.asLocator)(this._page.browserContext._browser.sdkLanguage(), selector);
|
|
1616
1396
|
}
|
|
1617
1397
|
}
|
|
1618
|
-
exports.Frame = Frame;
|
|
1619
|
-
Frame.Events = {
|
|
1620
|
-
InternalNavigation: 'internalnavigation',
|
|
1621
|
-
AddLifecycle: 'addlifecycle',
|
|
1622
|
-
RemoveLifecycle: 'removelifecycle'
|
|
1623
|
-
};
|
|
1624
1398
|
class SignalBarrier {
|
|
1625
1399
|
constructor(progress) {
|
|
1626
|
-
this._progress = void 0;
|
|
1627
1400
|
this._protectCount = 0;
|
|
1628
|
-
this._promise = new
|
|
1401
|
+
this._promise = new import_manualPromise.ManualPromise();
|
|
1629
1402
|
this._progress = progress;
|
|
1630
1403
|
this.retain();
|
|
1631
1404
|
}
|
|
1632
1405
|
waitFor() {
|
|
1633
1406
|
this.release();
|
|
1634
|
-
return this._promise;
|
|
1407
|
+
return this._progress.race(this._promise);
|
|
1635
1408
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1409
|
+
addFrameNavigation(frame) {
|
|
1410
|
+
if (frame.parentFrame())
|
|
1411
|
+
return;
|
|
1639
1412
|
this.retain();
|
|
1640
|
-
const waiter =
|
|
1641
|
-
if (!e.isPublic)
|
|
1642
|
-
|
|
1413
|
+
const waiter = import_helper.helper.waitForEvent(this._progress, frame, Frame.Events.InternalNavigation, (e) => {
|
|
1414
|
+
if (!e.isPublic)
|
|
1415
|
+
return false;
|
|
1416
|
+
if (!e.error && this._progress)
|
|
1417
|
+
this._progress.log(` navigated to "${frame._url}"`);
|
|
1643
1418
|
return true;
|
|
1644
1419
|
});
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1420
|
+
import_utils.LongStandingScope.raceMultiple([
|
|
1421
|
+
frame._page.openScope,
|
|
1422
|
+
frame._detachedScope
|
|
1423
|
+
], waiter.promise).catch(() => {
|
|
1424
|
+
}).finally(() => {
|
|
1425
|
+
waiter.dispose();
|
|
1426
|
+
this.release();
|
|
1427
|
+
});
|
|
1648
1428
|
}
|
|
1649
1429
|
retain() {
|
|
1650
1430
|
++this._protectCount;
|
|
1651
1431
|
}
|
|
1652
1432
|
release() {
|
|
1653
1433
|
--this._protectCount;
|
|
1654
|
-
if (!this._protectCount)
|
|
1434
|
+
if (!this._protectCount)
|
|
1435
|
+
this._promise.resolve();
|
|
1655
1436
|
}
|
|
1656
1437
|
}
|
|
1657
1438
|
function verifyLifecycle(name, waitUntil) {
|
|
1658
|
-
if (waitUntil ===
|
|
1659
|
-
|
|
1439
|
+
if (waitUntil === "networkidle0")
|
|
1440
|
+
waitUntil = "networkidle";
|
|
1441
|
+
if (!types.kLifecycleEvents.has(waitUntil))
|
|
1442
|
+
throw new Error(`${name}: expected one of (load|domcontentloaded|networkidle|commit)`);
|
|
1660
1443
|
return waitUntil;
|
|
1661
1444
|
}
|
|
1662
1445
|
function renderUnexpectedValue(expression, received) {
|
|
1663
|
-
if (expression ===
|
|
1446
|
+
if (expression === "to.match.aria")
|
|
1447
|
+
return received ? received.raw : received;
|
|
1664
1448
|
return received;
|
|
1665
|
-
}
|
|
1449
|
+
}
|
|
1450
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1451
|
+
0 && (module.exports = {
|
|
1452
|
+
Frame,
|
|
1453
|
+
FrameManager,
|
|
1454
|
+
NavigationAbortedError
|
|
1455
|
+
});
|