patchright-core 1.58.2 → 1.59.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 +126 -650
- package/browsers.json +16 -14
- package/lib/bootstrap.js +77 -0
- package/lib/cli/browserActions.js +308 -0
- package/lib/cli/driver.js +3 -2
- package/lib/cli/installActions.js +171 -0
- package/lib/cli/program.js +47 -411
- package/lib/client/android.js +4 -4
- package/lib/client/api.js +3 -3
- package/lib/client/browser.js +8 -0
- package/lib/client/browserContext.js +22 -61
- package/lib/client/browserType.js +19 -51
- package/lib/client/cdpSession.js +6 -2
- package/lib/client/channelOwner.js +1 -1
- package/lib/client/clientHelper.js +2 -1
- package/lib/client/clock.js +0 -1
- package/lib/client/{webSocket.js → connect.js} +57 -7
- package/lib/client/connection.js +8 -4
- package/lib/client/consoleMessage.js +3 -0
- package/lib/client/debugger.js +57 -0
- package/lib/client/dialog.js +8 -1
- package/lib/client/disposable.js +76 -0
- package/lib/client/electron.js +1 -0
- package/lib/client/elementHandle.js +1 -4
- package/lib/client/events.js +3 -3
- package/lib/client/fetch.js +0 -1
- package/lib/client/frame.js +10 -23
- package/lib/client/harRouter.js +13 -1
- package/lib/client/jsHandle.js +4 -8
- package/lib/client/locator.js +13 -44
- package/lib/client/network.js +15 -16
- package/lib/client/page.js +41 -75
- package/lib/client/platform.js +0 -3
- package/lib/client/screencast.js +88 -0
- package/lib/client/selectors.js +3 -1
- package/lib/client/tracing.js +11 -5
- package/lib/client/video.js +13 -20
- package/lib/client/worker.js +6 -6
- package/lib/generated/bindingsControllerSource.js +1 -1
- package/lib/generated/clockSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/generated/storageScriptSource.js +1 -1
- package/lib/generated/utilityScriptSource.js +1 -1
- package/lib/mcpBundle.js +0 -6
- package/lib/mcpBundleImpl.js +91 -0
- package/lib/protocol/validator.js +224 -138
- package/lib/protocol/validatorPrimitives.js +1 -1
- package/lib/remote/playwrightConnection.js +10 -8
- package/lib/remote/playwrightPipeServer.js +100 -0
- package/lib/remote/playwrightServer.js +13 -8
- package/lib/remote/playwrightWebSocketServer.js +73 -0
- package/lib/remote/serverTransport.js +96 -0
- package/lib/server/android/android.js +2 -2
- package/lib/server/bidi/bidiBrowser.js +30 -8
- package/lib/server/bidi/bidiChromium.js +18 -5
- package/lib/server/bidi/bidiNetworkManager.js +39 -11
- package/lib/server/bidi/bidiPage.js +31 -15
- package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
- package/lib/server/browser.js +84 -21
- package/lib/server/browserContext.js +110 -58
- package/lib/server/browserType.js +14 -12
- package/lib/server/chromium/chromium.js +15 -12
- package/lib/server/chromium/chromiumSwitches.js +14 -2
- package/lib/server/chromium/crBrowser.js +20 -17
- package/lib/server/chromium/crCoverage.js +1 -13
- package/lib/server/chromium/crDevTools.js +1 -0
- package/lib/server/chromium/crNetworkManager.js +12 -267
- package/lib/server/chromium/crPage.js +67 -199
- package/lib/server/chromium/crServiceWorker.js +7 -14
- package/lib/server/clock.js +33 -41
- package/lib/server/console.js +5 -1
- package/lib/server/debugController.js +12 -6
- package/lib/server/debugger.js +40 -47
- package/lib/server/deviceDescriptorsSource.json +137 -137
- package/lib/server/dispatchers/browserContextDispatcher.js +29 -30
- package/lib/server/dispatchers/browserDispatcher.js +11 -5
- package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
- package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
- package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
- package/lib/server/dispatchers/dispatcher.js +1 -1
- package/lib/server/dispatchers/disposableDispatcher.js +39 -0
- package/lib/server/dispatchers/electronDispatcher.js +2 -1
- package/lib/server/dispatchers/frameDispatcher.js +6 -6
- package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
- package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
- package/lib/server/dispatchers/networkDispatchers.js +6 -5
- package/lib/server/dispatchers/pageDispatcher.js +101 -38
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
- package/lib/server/disposable.js +41 -0
- package/lib/server/dom.js +44 -26
- package/lib/server/download.js +3 -2
- package/lib/server/electron/electron.js +12 -7
- package/lib/server/firefox/ffBrowser.js +9 -19
- package/lib/server/firefox/ffInput.js +21 -5
- package/lib/server/firefox/ffNetworkManager.js +2 -2
- package/lib/server/firefox/ffPage.js +24 -27
- package/lib/server/frameSelectors.js +5 -172
- package/lib/server/frames.js +234 -687
- package/lib/server/har/harRecorder.js +2 -2
- package/lib/server/har/harTracer.js +5 -4
- package/lib/server/input.js +49 -4
- package/lib/server/instrumentation.js +5 -0
- package/lib/server/javascript.js +6 -26
- package/lib/server/launchApp.js +1 -3
- package/lib/server/localUtils.js +6 -6
- package/lib/server/network.js +9 -8
- package/lib/server/overlay.js +138 -0
- package/lib/server/page.js +157 -105
- package/lib/server/progress.js +6 -0
- package/lib/server/recorder/recorderApp.js +9 -8
- package/lib/server/recorder.js +76 -40
- package/lib/server/registry/index.js +55 -82
- package/lib/server/registry/nativeDeps.js +1 -0
- package/lib/server/screencast.js +90 -143
- package/lib/server/screenshotter.js +0 -6
- package/lib/server/trace/recorder/snapshotter.js +8 -17
- package/lib/server/trace/recorder/snapshotterInjected.js +82 -20
- package/lib/server/trace/recorder/tracing.js +87 -44
- package/lib/server/trace/viewer/traceViewer.js +3 -4
- package/lib/server/usKeyboardLayout.js +7 -0
- package/lib/server/utils/comparators.js +1 -1
- package/lib/server/utils/disposable.js +32 -0
- package/lib/server/utils/eventsHelper.js +3 -1
- package/lib/server/utils/fileUtils.js +16 -2
- package/lib/server/utils/happyEyeballs.js +15 -12
- package/lib/server/utils/hostPlatform.js +0 -15
- package/lib/server/utils/httpServer.js +5 -3
- package/lib/server/utils/network.js +2 -1
- package/lib/server/utils/nodePlatform.js +0 -6
- package/lib/server/utils/processLauncher.js +8 -6
- package/lib/server/utils/zipFile.js +2 -2
- package/lib/server/videoRecorder.js +82 -12
- package/lib/server/webkit/wkBrowser.js +1 -6
- package/lib/server/webkit/wkPage.js +27 -25
- package/lib/server/webkit/wkWorkers.js +2 -1
- package/lib/serverRegistry.js +156 -0
- package/lib/tools/backend/browserBackend.js +79 -0
- package/lib/tools/backend/common.js +63 -0
- package/lib/tools/backend/config.js +41 -0
- package/lib/tools/backend/console.js +66 -0
- package/lib/tools/backend/context.js +296 -0
- package/lib/tools/backend/cookies.js +152 -0
- package/lib/tools/backend/devtools.js +69 -0
- package/lib/tools/backend/dialogs.js +59 -0
- package/lib/tools/backend/evaluate.js +64 -0
- package/lib/tools/backend/files.js +60 -0
- package/lib/tools/backend/form.js +64 -0
- package/lib/tools/backend/keyboard.js +155 -0
- package/lib/tools/backend/logFile.js +95 -0
- package/lib/tools/backend/mouse.js +168 -0
- package/lib/tools/backend/navigate.js +106 -0
- package/lib/tools/backend/network.js +135 -0
- package/lib/tools/backend/pdf.js +48 -0
- package/lib/tools/backend/response.js +305 -0
- package/lib/tools/backend/route.js +140 -0
- package/lib/tools/backend/runCode.js +77 -0
- package/lib/tools/backend/screenshot.js +88 -0
- package/lib/tools/backend/sessionLog.js +74 -0
- package/lib/tools/backend/snapshot.js +208 -0
- package/lib/tools/backend/storage.js +68 -0
- package/lib/tools/backend/tab.js +445 -0
- package/lib/tools/backend/tabs.js +67 -0
- package/lib/tools/backend/tool.js +47 -0
- package/lib/tools/backend/tools.js +102 -0
- package/lib/tools/backend/tracing.js +78 -0
- package/lib/tools/backend/utils.js +83 -0
- package/lib/tools/backend/verify.js +151 -0
- package/lib/tools/backend/video.js +98 -0
- package/lib/tools/backend/wait.js +63 -0
- package/lib/tools/backend/webstorage.js +223 -0
- package/lib/tools/cli-client/cli.js +6 -0
- package/lib/tools/cli-client/help.json +399 -0
- package/lib/tools/cli-client/minimist.js +128 -0
- package/lib/tools/cli-client/program.js +350 -0
- package/lib/tools/cli-client/registry.js +176 -0
- package/lib/tools/cli-client/session.js +289 -0
- package/lib/tools/cli-client/skill/SKILL.md +328 -0
- package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
- package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
- package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
- package/lib/tools/cli-client/skill/references/running-code.md +231 -0
- package/lib/tools/cli-client/skill/references/session-management.md +169 -0
- package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
- package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
- package/lib/tools/cli-client/skill/references/tracing.md +139 -0
- package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
- package/lib/tools/cli-daemon/command.js +73 -0
- package/lib/tools/cli-daemon/commands.js +956 -0
- package/lib/tools/cli-daemon/daemon.js +157 -0
- package/lib/tools/cli-daemon/helpGenerator.js +177 -0
- package/lib/tools/cli-daemon/program.js +129 -0
- package/lib/tools/dashboard/appIcon.png +0 -0
- package/lib/tools/dashboard/dashboardApp.js +284 -0
- package/lib/tools/dashboard/dashboardController.js +296 -0
- package/lib/tools/exports.js +60 -0
- package/lib/tools/mcp/browserFactory.js +233 -0
- package/lib/tools/mcp/cdpRelay.js +352 -0
- package/lib/tools/mcp/cli-stub.js +7 -0
- package/lib/tools/mcp/config.d.js +16 -0
- package/lib/tools/mcp/config.js +446 -0
- package/lib/tools/mcp/configIni.js +189 -0
- package/lib/tools/mcp/extensionContextFactory.js +55 -0
- package/lib/tools/mcp/index.js +62 -0
- package/lib/tools/mcp/log.js +35 -0
- package/lib/tools/mcp/program.js +107 -0
- package/lib/tools/mcp/protocol.js +28 -0
- package/lib/tools/mcp/watchdog.js +44 -0
- package/lib/tools/trace/SKILL.md +171 -0
- package/lib/{server/trace/viewer/traceParser.js → tools/trace/installSkill.js} +15 -39
- package/lib/tools/trace/traceActions.js +142 -0
- package/lib/tools/trace/traceAttachments.js +69 -0
- package/lib/tools/trace/traceCli.js +87 -0
- package/lib/tools/trace/traceConsole.js +97 -0
- package/lib/tools/trace/traceErrors.js +55 -0
- package/lib/tools/trace/traceOpen.js +69 -0
- package/lib/tools/trace/traceParser.js +96 -0
- package/lib/tools/trace/traceRequests.js +182 -0
- package/lib/tools/trace/traceScreenshot.js +68 -0
- package/lib/tools/trace/traceSnapshot.js +149 -0
- package/lib/tools/trace/traceUtils.js +153 -0
- package/lib/tools/utils/connect.js +32 -0
- package/lib/tools/utils/mcp/http.js +152 -0
- package/lib/tools/utils/mcp/server.js +230 -0
- package/lib/tools/utils/mcp/tool.js +47 -0
- package/lib/tools/utils/socketConnection.js +108 -0
- package/lib/utils/isomorphic/formatUtils.js +64 -0
- package/lib/utils/isomorphic/jsonSchema.js +89 -0
- package/lib/utils/isomorphic/mimeType.js +7 -2
- package/lib/utils/isomorphic/protocolFormatter.js +2 -2
- package/lib/utils/isomorphic/protocolMetainfo.js +127 -106
- package/lib/utils/isomorphic/stringUtils.js +3 -3
- package/lib/utils/isomorphic/timeoutRunner.js +3 -3
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +35 -42
- package/lib/utils/isomorphic/trace/traceLoader.js +15 -14
- package/lib/utils/isomorphic/trace/traceModel.js +3 -2
- package/lib/utils/isomorphic/trace/traceModernizer.js +1 -0
- package/lib/utils/isomorphic/urlMatch.js +54 -1
- package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
- package/lib/utils.js +6 -2
- package/lib/utilsBundle.js +3 -21
- package/lib/utilsBundleImpl/index.js +132 -133
- package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
- package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
- package/lib/vite/dashboard/index.html +28 -0
- package/lib/vite/htmlReport/index.html +2 -70
- package/lib/vite/htmlReport/report.css +1 -0
- package/lib/vite/htmlReport/report.js +72 -0
- package/lib/vite/recorder/assets/{codeMirrorModule-CFUTFUO7.js → codeMirrorModule-C8KMvO9L.js} +20 -20
- package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-BVA4h_ZY.js → codeMirrorModule-DS0FLvoc.js} +20 -20
- package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
- package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
- package/lib/vite/traceViewer/{index.BVu7tZDe.css → index.CzXZzn5A.css} +1 -1
- package/lib/vite/traceViewer/{index.BtyWtaE-.js → index.Dtstcb7U.js} +1 -1
- package/lib/vite/traceViewer/index.html +4 -4
- package/lib/vite/traceViewer/sw.bundle.js +4 -4
- package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/lib/zipBundleImpl.js +2 -2
- package/lib/zodBundle.js +39 -0
- package/lib/zodBundleImpl.js +40 -0
- package/package.json +6 -1
- package/types/protocol.d.ts +947 -51
- package/types/types.d.ts +854 -74
- package/lib/client/pageAgent.js +0 -64
- package/lib/mcpBundleImpl/index.js +0 -147
- package/lib/server/agent/actionRunner.js +0 -335
- package/lib/server/agent/actions.js +0 -128
- package/lib/server/agent/codegen.js +0 -111
- package/lib/server/agent/context.js +0 -150
- package/lib/server/agent/expectTools.js +0 -156
- package/lib/server/agent/pageAgent.js +0 -204
- package/lib/server/agent/performTools.js +0 -262
- package/lib/server/agent/tool.js +0 -109
- package/lib/server/dispatchers/pageAgentDispatcher.js +0 -96
- package/lib/server/pageBinding.js +0 -87
- package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +0 -248
- package/lib/vite/recorder/assets/index-CVkBxsGf.js +0 -193
- package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +0 -266
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +0 -1
- package/lib/vite/traceViewer/uiMode.fyrXARf2.js +0 -5
- /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
- /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var browserContext_exports = {};
|
|
30
30
|
__export(browserContext_exports, {
|
|
31
31
|
BrowserContext: () => BrowserContext,
|
|
32
|
+
calculateUserAgentEmulation: () => calculateUserAgentEmulation,
|
|
32
33
|
normalizeProxySettings: () => normalizeProxySettings,
|
|
33
34
|
validateBrowserContextOptions: () => validateBrowserContextOptions,
|
|
34
35
|
verifyClientCertificates: () => verifyClientCertificates,
|
|
@@ -36,14 +37,12 @@ __export(browserContext_exports, {
|
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(browserContext_exports);
|
|
38
39
|
var import_fs = __toESM(require("fs"));
|
|
39
|
-
var import_path = __toESM(require("path"));
|
|
40
40
|
var import_crypto = require("./utils/crypto");
|
|
41
41
|
var import_debug = require("./utils/debug");
|
|
42
42
|
var import_clock = require("./clock");
|
|
43
43
|
var import_debugger = require("./debugger");
|
|
44
44
|
var import_dialog = require("./dialog");
|
|
45
45
|
var import_fetch = require("./fetch");
|
|
46
|
-
var import_fileUtils = require("./utils/fileUtils");
|
|
47
46
|
var import_stackTrace = require("../utils/isomorphic/stackTrace");
|
|
48
47
|
var import_harRecorder = require("./har/harRecorder");
|
|
49
48
|
var import_helper = require("./helper");
|
|
@@ -70,8 +69,9 @@ const BrowserContextEvent = {
|
|
|
70
69
|
RequestFulfilled: "requestfulfilled",
|
|
71
70
|
RequestContinued: "requestcontinued",
|
|
72
71
|
BeforeClose: "beforeclose",
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
RecorderEvent: "recorderevent",
|
|
73
|
+
PageClosed: "pageclosed",
|
|
74
|
+
InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument"
|
|
75
75
|
};
|
|
76
76
|
class BrowserContext extends import_instrumentation.SdkObject {
|
|
77
77
|
constructor(browser, options, browserContextId) {
|
|
@@ -113,18 +113,24 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
113
113
|
if (this.attribution.playwright.options.isInternalPlaywright)
|
|
114
114
|
return;
|
|
115
115
|
this._debugger = new import_debugger.Debugger(this);
|
|
116
|
-
|
|
116
|
+
const shouldEnableDebugger = !this.attribution.playwright.options.isServer && ((0, import_debug.isUnderTest)() || !!this._browser.options.headful);
|
|
117
|
+
if (shouldEnableDebugger) {
|
|
118
|
+
this._debugger.setPauseAt();
|
|
119
|
+
this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
|
|
120
|
+
if (this._debugger.isPaused())
|
|
121
|
+
import_recorderApp.RecorderApp.showInspectorNoReply(this);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if ((0, import_debug.debugMode)() === "inspector") {
|
|
125
|
+
this._debugger.setPauseAt({ next: true });
|
|
117
126
|
await import_recorderApp.RecorderApp.show(this, { pauseOnNextStatement: true });
|
|
118
|
-
|
|
119
|
-
import_recorderApp.RecorderApp.showInspectorNoReply(this);
|
|
120
|
-
this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
|
|
121
|
-
if (this._debugger.isPaused())
|
|
122
|
-
import_recorderApp.RecorderApp.showInspectorNoReply(this);
|
|
123
|
-
});
|
|
127
|
+
}
|
|
124
128
|
if ((0, import_debug.debugMode)() === "console")
|
|
125
129
|
await this.exposeConsoleApi();
|
|
126
130
|
if (this._options.serviceWorkers === "block")
|
|
127
|
-
await this.addInitScript(
|
|
131
|
+
await this.addInitScript(`
|
|
132
|
+
if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { console.warn('Service Worker registration blocked by Playwright'); };
|
|
133
|
+
`);
|
|
128
134
|
if (this._options.permissions)
|
|
129
135
|
await this.grantPermissions(this._options.permissions);
|
|
130
136
|
}
|
|
@@ -140,10 +146,6 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
140
146
|
module.exports = { default: () => installConsoleApi };
|
|
141
147
|
`);
|
|
142
148
|
}
|
|
143
|
-
async _ensureVideosPath() {
|
|
144
|
-
if (this._options.recordVideo)
|
|
145
|
-
await (0, import_fileUtils.mkdirIfNeeded)(import_path.default.join(this._options.recordVideo.dir, "dummy"));
|
|
146
|
-
}
|
|
147
149
|
canResetForReuse() {
|
|
148
150
|
if (this._closedStatus !== "open")
|
|
149
151
|
return false;
|
|
@@ -237,7 +239,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
237
239
|
async exposePlaywrightBindingIfNeeded() {
|
|
238
240
|
this._playwrightBindingExposed ??= (async () => {
|
|
239
241
|
await this.doExposePlaywrightBinding();
|
|
240
|
-
this.bindingsInitScript = import_page2.PageBinding.createInitScript();
|
|
242
|
+
this.bindingsInitScript = import_page2.PageBinding.createInitScript(this);
|
|
241
243
|
this.initScripts.push(this.bindingsInitScript);
|
|
242
244
|
await this.doAddInitScript(this.bindingsInitScript);
|
|
243
245
|
await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
|
|
@@ -254,16 +256,26 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
254
256
|
if (page.getBinding(name))
|
|
255
257
|
throw new Error(`Function "${name}" has been already registered in one of the pages`);
|
|
256
258
|
}
|
|
257
|
-
|
|
259
|
+
await progress.race(this.exposePlaywrightBindingIfNeeded());
|
|
260
|
+
const binding = new import_page2.PageBinding(this, name, playwrightBinding, needsHandle);
|
|
258
261
|
binding.forClient = forClient;
|
|
259
262
|
this._pageBindings.set(name, binding);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
try {
|
|
264
|
+
await progress.race(this.doAddInitScript(binding.initScript));
|
|
265
|
+
await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
|
|
266
|
+
return binding;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
this._pageBindings.delete(name);
|
|
269
|
+
throw error;
|
|
265
270
|
}
|
|
266
|
-
|
|
271
|
+
}
|
|
272
|
+
async removeExposedBinding(binding) {
|
|
273
|
+
if (this._pageBindings.get(binding.name) !== binding)
|
|
274
|
+
return;
|
|
275
|
+
this._pageBindings.delete(binding.name);
|
|
276
|
+
await this.doRemoveInitScripts([binding.initScript]);
|
|
277
|
+
const cleanup = `{ ${binding.cleanupScript} };`;
|
|
278
|
+
await this.safeNonStallingEvaluateInAllFrames(cleanup, "main");
|
|
267
279
|
}
|
|
268
280
|
async grantPermissions(permissions, origin) {
|
|
269
281
|
let resolvedOrigin = "*";
|
|
@@ -349,25 +361,21 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
349
361
|
if (username)
|
|
350
362
|
this._options.httpCredentials = { username, password: password || "" };
|
|
351
363
|
}
|
|
352
|
-
async addInitScript(
|
|
353
|
-
const initScript = new import_page.InitScript(source);
|
|
364
|
+
async addInitScript(source) {
|
|
365
|
+
const initScript = new import_page.InitScript(this, source);
|
|
354
366
|
this.initScripts.push(initScript);
|
|
355
367
|
try {
|
|
356
|
-
|
|
357
|
-
if (progress)
|
|
358
|
-
await progress.race(promise);
|
|
359
|
-
else
|
|
360
|
-
await promise;
|
|
368
|
+
await this.doAddInitScript(initScript);
|
|
361
369
|
return initScript;
|
|
362
370
|
} catch (error) {
|
|
363
|
-
|
|
371
|
+
initScript.dispose().catch(() => {
|
|
364
372
|
});
|
|
365
373
|
throw error;
|
|
366
374
|
}
|
|
367
375
|
}
|
|
368
|
-
async
|
|
369
|
-
this.initScripts
|
|
370
|
-
await this.doRemoveInitScripts();
|
|
376
|
+
async removeInitScript(initScript) {
|
|
377
|
+
this.initScripts = this.initScripts.filter((script) => initScript !== script);
|
|
378
|
+
await this.doRemoveInitScripts([initScript]);
|
|
371
379
|
}
|
|
372
380
|
async addRequestInterceptor(progress, handler) {
|
|
373
381
|
this.requestInterceptors.push(handler);
|
|
@@ -403,16 +411,13 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
403
411
|
for (const harRecorder of this._harRecorders.values())
|
|
404
412
|
await harRecorder.flush();
|
|
405
413
|
await this.tracing.flush();
|
|
406
|
-
|
|
407
|
-
for (const { context, artifact } of this._browser._idToVideo.values()) {
|
|
408
|
-
if (context === this)
|
|
409
|
-
promises.push(artifact.finishedPromise());
|
|
410
|
-
}
|
|
414
|
+
await Promise.all(this.pages().map((page) => page.screencast.handlePageOrContextClose()));
|
|
411
415
|
if (this._customCloseHandler) {
|
|
412
416
|
await this._customCloseHandler();
|
|
413
417
|
} else {
|
|
414
418
|
await this.doClose(options.reason);
|
|
415
419
|
}
|
|
420
|
+
const promises = [];
|
|
416
421
|
promises.push(this._deleteAllDownloads());
|
|
417
422
|
promises.push(this._deleteAllTempDirs());
|
|
418
423
|
await Promise.all(promises);
|
|
@@ -588,22 +593,6 @@ function validateBrowserContextOptions(options, browserOptions) {
|
|
|
588
593
|
options.acceptDownloads = "internal-browser-default";
|
|
589
594
|
if (!options.viewport && !options.noDefaultViewport)
|
|
590
595
|
options.viewport = { width: 1280, height: 720 };
|
|
591
|
-
if (options.recordVideo) {
|
|
592
|
-
if (!options.recordVideo.size) {
|
|
593
|
-
if (options.noDefaultViewport) {
|
|
594
|
-
options.recordVideo.size = { width: 800, height: 600 };
|
|
595
|
-
} else {
|
|
596
|
-
const size = options.viewport;
|
|
597
|
-
const scale = Math.min(1, 800 / Math.max(size.width, size.height));
|
|
598
|
-
options.recordVideo.size = {
|
|
599
|
-
width: Math.floor(size.width * scale),
|
|
600
|
-
height: Math.floor(size.height * scale)
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
options.recordVideo.size.width &= ~1;
|
|
605
|
-
options.recordVideo.size.height &= ~1;
|
|
606
|
-
}
|
|
607
596
|
if (options.proxy)
|
|
608
597
|
options.proxy = normalizeProxySettings(options.proxy);
|
|
609
598
|
verifyGeolocation(options.geolocation);
|
|
@@ -655,6 +644,69 @@ function normalizeProxySettings(proxy) {
|
|
|
655
644
|
bypass = bypass.split(",").map((t) => t.trim()).join(",");
|
|
656
645
|
return { ...proxy, server, bypass };
|
|
657
646
|
}
|
|
647
|
+
function calculateUserAgentEmulation(options) {
|
|
648
|
+
const ua = options.userAgent;
|
|
649
|
+
if (!ua)
|
|
650
|
+
return { navigatorPlatform: void 0, userAgentMetadata: void 0 };
|
|
651
|
+
const userAgentMetadata = {
|
|
652
|
+
mobile: !!options.isMobile,
|
|
653
|
+
model: "",
|
|
654
|
+
architecture: "x86",
|
|
655
|
+
platform: "Windows",
|
|
656
|
+
platformVersion: ""
|
|
657
|
+
};
|
|
658
|
+
const androidMatch = ua.match(/Android (\d+(\.\d+)?(\.\d+)?)/);
|
|
659
|
+
const iPhoneMatch = ua.match(/iPhone OS (\d+(_\d+)?)/);
|
|
660
|
+
const iPadMatch = ua.match(/iPad; CPU OS (\d+(_\d+)?)/);
|
|
661
|
+
const macOSMatch = ua.match(/Mac OS X (\d+(_\d+)?(_\d+)?)/);
|
|
662
|
+
const windowsMatch = ua.match(/Windows\D+(\d+(\.\d+)?(\.\d+)?)/);
|
|
663
|
+
if (androidMatch) {
|
|
664
|
+
userAgentMetadata.platform = "Android";
|
|
665
|
+
userAgentMetadata.platformVersion = androidMatch[1];
|
|
666
|
+
userAgentMetadata.architecture = "arm";
|
|
667
|
+
} else if (iPhoneMatch) {
|
|
668
|
+
userAgentMetadata.platform = "iOS";
|
|
669
|
+
userAgentMetadata.platformVersion = iPhoneMatch[1].replace(/_/g, ".");
|
|
670
|
+
userAgentMetadata.architecture = "arm";
|
|
671
|
+
} else if (iPadMatch) {
|
|
672
|
+
userAgentMetadata.platform = "iOS";
|
|
673
|
+
userAgentMetadata.platformVersion = iPadMatch[1].replace(/_/g, ".");
|
|
674
|
+
userAgentMetadata.architecture = "arm";
|
|
675
|
+
} else if (macOSMatch) {
|
|
676
|
+
userAgentMetadata.platform = "macOS";
|
|
677
|
+
userAgentMetadata.platformVersion = macOSMatch[1].replace(/_/g, ".");
|
|
678
|
+
if (!ua.includes("Intel"))
|
|
679
|
+
userAgentMetadata.architecture = "arm";
|
|
680
|
+
} else if (windowsMatch) {
|
|
681
|
+
userAgentMetadata.platform = "Windows";
|
|
682
|
+
userAgentMetadata.platformVersion = windowsMatch[1];
|
|
683
|
+
} else if (ua.toLowerCase().includes("linux")) {
|
|
684
|
+
userAgentMetadata.platform = "Linux";
|
|
685
|
+
}
|
|
686
|
+
if (ua.includes("ARM") || ua.includes("aarch64"))
|
|
687
|
+
userAgentMetadata.architecture = "arm";
|
|
688
|
+
let navigatorPlatform;
|
|
689
|
+
if (!process.env.PLAYWRIGHT_NO_UA_PLATFORM) {
|
|
690
|
+
switch (userAgentMetadata.platform) {
|
|
691
|
+
case "Android":
|
|
692
|
+
navigatorPlatform = userAgentMetadata.architecture === "arm" ? "Linux armv8l" : "Linux x86_64";
|
|
693
|
+
break;
|
|
694
|
+
case "iOS":
|
|
695
|
+
navigatorPlatform = ua.includes("iPad") ? "iPad" : "iPhone";
|
|
696
|
+
break;
|
|
697
|
+
case "macOS":
|
|
698
|
+
navigatorPlatform = "MacIntel";
|
|
699
|
+
break;
|
|
700
|
+
case "Linux":
|
|
701
|
+
navigatorPlatform = userAgentMetadata.architecture === "arm" ? "Linux aarch64" : "Linux x86_64";
|
|
702
|
+
break;
|
|
703
|
+
case "Windows":
|
|
704
|
+
navigatorPlatform = "Win32";
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return { navigatorPlatform, userAgentMetadata };
|
|
709
|
+
}
|
|
658
710
|
const paramsThatAllowContextReuse = [
|
|
659
711
|
"colorScheme",
|
|
660
712
|
"forcedColors",
|
|
@@ -676,12 +728,12 @@ const defaultNewContextParamValues = {
|
|
|
676
728
|
acceptDownloads: "accept",
|
|
677
729
|
strictSelectors: false,
|
|
678
730
|
serviceWorkers: "allow",
|
|
679
|
-
locale: "en-US"
|
|
680
|
-
focusControl: false
|
|
731
|
+
locale: "en-US"
|
|
681
732
|
};
|
|
682
733
|
// Annotate the CommonJS export names for ESM import in node:
|
|
683
734
|
0 && (module.exports = {
|
|
684
735
|
BrowserContext,
|
|
736
|
+
calculateUserAgentEmulation,
|
|
685
737
|
normalizeProxySettings,
|
|
686
738
|
validateBrowserContextOptions,
|
|
687
739
|
verifyClientCertificates,
|
|
@@ -59,7 +59,7 @@ class BrowserType extends import_instrumentation.SdkObject {
|
|
|
59
59
|
this.logName = "browser";
|
|
60
60
|
}
|
|
61
61
|
executablePath() {
|
|
62
|
-
return import_registry.registry.findExecutable(this._name).executablePath(
|
|
62
|
+
return import_registry.registry.findExecutable(this._name).executablePath() || "";
|
|
63
63
|
}
|
|
64
64
|
name() {
|
|
65
65
|
return this._name;
|
|
@@ -115,7 +115,7 @@ class BrowserType extends import_instrumentation.SdkObject {
|
|
|
115
115
|
await progress.race(options.__testHookBeforeCreateBrowser());
|
|
116
116
|
const browserOptions = {
|
|
117
117
|
name: this._name,
|
|
118
|
-
|
|
118
|
+
browserType: this._name,
|
|
119
119
|
channel: options.channel,
|
|
120
120
|
slowMo: options.slowMo,
|
|
121
121
|
persistent,
|
|
@@ -129,7 +129,8 @@ class BrowserType extends import_instrumentation.SdkObject {
|
|
|
129
129
|
protocolLogger,
|
|
130
130
|
browserLogsCollector,
|
|
131
131
|
wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
|
|
132
|
-
originalLaunchOptions: options
|
|
132
|
+
originalLaunchOptions: options,
|
|
133
|
+
userDataDir: persistent ? userDataDir : void 0
|
|
133
134
|
};
|
|
134
135
|
if (persistent)
|
|
135
136
|
(0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
|
|
@@ -152,10 +153,14 @@ class BrowserType extends import_instrumentation.SdkObject {
|
|
|
152
153
|
args = [],
|
|
153
154
|
executablePath = null
|
|
154
155
|
} = options;
|
|
155
|
-
await this._createArtifactDirs(options);
|
|
156
156
|
const tempDirectories = [];
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
let artifactsDir;
|
|
158
|
+
if (options.artifactsDir) {
|
|
159
|
+
artifactsDir = options.artifactsDir;
|
|
160
|
+
} else {
|
|
161
|
+
artifactsDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-"));
|
|
162
|
+
tempDirectories.push(artifactsDir);
|
|
163
|
+
}
|
|
159
164
|
if (userDataDir) {
|
|
160
165
|
(0, import_assert.assert)(import_path.default.isAbsolute(userDataDir), "userDataDir must be an absolute path");
|
|
161
166
|
if (!await (0, import_fileUtils.existsAsync)(userDataDir))
|
|
@@ -270,15 +275,12 @@ ${updatedLog}`);
|
|
|
270
275
|
throw error;
|
|
271
276
|
}
|
|
272
277
|
}
|
|
273
|
-
async _createArtifactDirs(options) {
|
|
274
|
-
if (options.downloadsPath)
|
|
275
|
-
await import_fs.default.promises.mkdir(options.downloadsPath, { recursive: true });
|
|
276
|
-
if (options.tracesDir)
|
|
277
|
-
await import_fs.default.promises.mkdir(options.tracesDir, { recursive: true });
|
|
278
|
-
}
|
|
279
278
|
async connectOverCDP(progress, endpointURL, options) {
|
|
280
279
|
throw new Error("CDP connections are only supported by Chromium");
|
|
281
280
|
}
|
|
281
|
+
async connectOverCDPTransport(progress, transport) {
|
|
282
|
+
throw new Error("CDP connections are only supported by Chromium");
|
|
283
|
+
}
|
|
282
284
|
async _launchWithSeleniumHub(progress, hubUrl, options) {
|
|
283
285
|
throw new Error("Connecting to SELENIUM_REMOTE_URL is only supported by Chromium");
|
|
284
286
|
}
|
|
@@ -82,6 +82,12 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
82
82
|
headersMap = { "User-Agent": (0, import_userAgent.getUserAgent)() };
|
|
83
83
|
else if (headersMap && !Object.keys(headersMap).some((key) => key.toLowerCase() === "user-agent"))
|
|
84
84
|
headersMap["User-Agent"] = (0, import_userAgent.getUserAgent)();
|
|
85
|
+
const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
|
|
86
|
+
const chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap, followRedirects: true, debugLogHeader: "x-playwright-debug-log" });
|
|
87
|
+
const closeAndWait = async () => await chromeTransport.closeAndWait();
|
|
88
|
+
return this._connectOverCDPImpl(progress, chromeTransport, closeAndWait, options, onClose);
|
|
89
|
+
}
|
|
90
|
+
async _connectOverCDPImpl(progress, transport, closeAndWait, options, onClose) {
|
|
85
91
|
const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
|
|
86
92
|
const doCleanup = async () => {
|
|
87
93
|
await (0, import_fileUtils.removeFolders)([artifactsDir]);
|
|
@@ -89,20 +95,17 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
89
95
|
onClose = void 0;
|
|
90
96
|
await cb?.();
|
|
91
97
|
};
|
|
92
|
-
let chromeTransport;
|
|
93
98
|
const doClose = async () => {
|
|
94
|
-
await
|
|
99
|
+
await closeAndWait();
|
|
95
100
|
await doCleanup();
|
|
96
101
|
};
|
|
97
102
|
try {
|
|
98
|
-
const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
|
|
99
|
-
chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
|
|
100
103
|
const browserProcess = { close: doClose, kill: doClose };
|
|
101
104
|
const persistent = { noDefaultViewport: true };
|
|
102
105
|
const browserOptions = {
|
|
103
106
|
slowMo: options.slowMo,
|
|
104
107
|
name: "chromium",
|
|
105
|
-
|
|
108
|
+
browserType: "chromium",
|
|
106
109
|
persistent,
|
|
107
110
|
browserProcess,
|
|
108
111
|
protocolLogger: import_helper.helper.debugProtocolLogger(),
|
|
@@ -113,7 +116,7 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
113
116
|
originalLaunchOptions: {}
|
|
114
117
|
};
|
|
115
118
|
(0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
|
|
116
|
-
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright,
|
|
119
|
+
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, browserOptions));
|
|
117
120
|
if (!options.isLocal)
|
|
118
121
|
browser._isCollocatedWithServer = false;
|
|
119
122
|
browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
|
|
@@ -124,6 +127,10 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
124
127
|
throw error;
|
|
125
128
|
}
|
|
126
129
|
}
|
|
130
|
+
async connectOverCDPTransport(progress, transport) {
|
|
131
|
+
const closeAndWait = async () => transport.close();
|
|
132
|
+
return this._connectOverCDPImpl(progress, transport, closeAndWait, { isLocal: true });
|
|
133
|
+
}
|
|
127
134
|
_createDevTools() {
|
|
128
135
|
const directory = import_registry.registry.findExecutable("chromium").directory;
|
|
129
136
|
return directory ? new import_crDevTools.CRDevTools(import_path.default.join(directory, "devtools-preferences.json")) : void 0;
|
|
@@ -163,7 +170,6 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
163
170
|
transport.send(message);
|
|
164
171
|
}
|
|
165
172
|
async _launchWithSeleniumHub(progress, hubUrl, options) {
|
|
166
|
-
await progress.race(this._createArtifactDirs(options));
|
|
167
173
|
if (!hubUrl.endsWith("/"))
|
|
168
174
|
hubUrl = hubUrl + "/";
|
|
169
175
|
const args = this._innerDefaultArgs(options);
|
|
@@ -277,8 +283,7 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
277
283
|
if (args.find((arg) => !arg.startsWith("-")))
|
|
278
284
|
throw new Error("Arguments can not specify page to be opened");
|
|
279
285
|
const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode, options.channel)];
|
|
280
|
-
|
|
281
|
-
}
|
|
286
|
+
chromeArguments.push("--enable-unsafe-swiftshader");
|
|
282
287
|
if (options.headless) {
|
|
283
288
|
chromeArguments.push("--headless");
|
|
284
289
|
chromeArguments.push(
|
|
@@ -298,11 +303,9 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
298
303
|
}
|
|
299
304
|
chromeArguments.push(`--proxy-server=${proxy.server}`);
|
|
300
305
|
const proxyBypassRules = [];
|
|
301
|
-
if (options.socksProxyPort)
|
|
302
|
-
proxyBypassRules.push("<-loopback>");
|
|
303
306
|
if (proxy.bypass)
|
|
304
307
|
proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
|
|
305
|
-
if (
|
|
308
|
+
if (options.socksProxyPort || (0, import_crBrowser.shouldProxyLoopback)(proxy.bypass))
|
|
306
309
|
proxyBypassRules.push("<-loopback>");
|
|
307
310
|
if (proxyBypassRules.length > 0)
|
|
308
311
|
chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(";")}`);
|
|
@@ -56,17 +56,27 @@ const chromiumSwitches = (assistantMode, channel, android) => [
|
|
|
56
56
|
"--disable-background-networking",
|
|
57
57
|
"--disable-background-timer-throttling",
|
|
58
58
|
"--disable-backgrounding-occluded-windows",
|
|
59
|
+
"--disable-back-forward-cache",
|
|
59
60
|
// Avoids surprises like main request not being intercepted during page.goBack().
|
|
60
61
|
"--disable-breakpad",
|
|
62
|
+
"--disable-client-side-phishing-detection",
|
|
63
|
+
"--disable-component-extensions-with-background-pages",
|
|
64
|
+
"--disable-component-update",
|
|
61
65
|
// Avoids unneeded network activity after startup.
|
|
62
66
|
"--no-default-browser-check",
|
|
67
|
+
"--disable-default-apps",
|
|
63
68
|
"--disable-dev-shm-usage",
|
|
69
|
+
"--disable-extensions",
|
|
64
70
|
"--disable-features=" + disabledFeatures(assistantMode).join(","),
|
|
65
71
|
process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? "" : "--enable-features=CDPScreenshotNewSurface",
|
|
72
|
+
"--allow-pre-commit-input",
|
|
66
73
|
"--disable-hang-monitor",
|
|
74
|
+
"--disable-ipc-flooding-protection",
|
|
75
|
+
"--disable-popup-blocking",
|
|
67
76
|
"--disable-prompt-on-repost",
|
|
68
77
|
"--disable-renderer-backgrounding",
|
|
69
78
|
"--force-color-profile=srgb",
|
|
79
|
+
"--metrics-recording-only",
|
|
70
80
|
"--no-first-run",
|
|
71
81
|
"--password-store=basic",
|
|
72
82
|
"--use-mock-keychain",
|
|
@@ -75,16 +85,18 @@ const chromiumSwitches = (assistantMode, channel, android) => [
|
|
|
75
85
|
"--export-tagged-pdf",
|
|
76
86
|
// https://chromium-review.googlesource.com/c/chromium/src/+/4853540
|
|
77
87
|
"--disable-search-engine-choice-screen",
|
|
88
|
+
// https://issues.chromium.org/41491762
|
|
89
|
+
"--unsafely-disable-devtools-self-xss-warnings",
|
|
78
90
|
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
|
|
79
91
|
"--edge-skip-compat-layer-relaunch",
|
|
92
|
+
assistantMode ? "" : "--enable-automation",
|
|
80
93
|
// This disables Chrome for Testing infobar that is visible in the persistent context.
|
|
81
94
|
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
|
|
82
95
|
"--disable-infobars",
|
|
83
96
|
// Less annoying popups.
|
|
84
97
|
"--disable-search-engine-choice-screen",
|
|
85
98
|
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
|
|
86
|
-
android ? "" : "--disable-sync"
|
|
87
|
-
"--disable-blink-features=AutomationControlled"
|
|
99
|
+
android ? "" : "--disable-sync"
|
|
88
100
|
].filter(Boolean);
|
|
89
101
|
// Annotate the CommonJS export names for ESM import in node:
|
|
90
102
|
0 && (module.exports = {
|
|
@@ -29,7 +29,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var crBrowser_exports = {};
|
|
30
30
|
__export(crBrowser_exports, {
|
|
31
31
|
CRBrowser: () => CRBrowser,
|
|
32
|
-
CRBrowserContext: () => CRBrowserContext
|
|
32
|
+
CRBrowserContext: () => CRBrowserContext,
|
|
33
|
+
shouldProxyLoopback: () => shouldProxyLoopback
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(crBrowser_exports);
|
|
35
36
|
var import_path = __toESM(require("path"));
|
|
@@ -54,6 +55,7 @@ class CRBrowser extends import_browser.Browser {
|
|
|
54
55
|
this._serviceWorkers = /* @__PURE__ */ new Map();
|
|
55
56
|
this._version = "";
|
|
56
57
|
this._majorVersion = 0;
|
|
58
|
+
this._revision = "";
|
|
57
59
|
this._tracingRecording = false;
|
|
58
60
|
this._userAgent = "";
|
|
59
61
|
this._connection = connection;
|
|
@@ -75,6 +77,7 @@ class CRBrowser extends import_browser.Browser {
|
|
|
75
77
|
if (options.__testHookOnConnectToBrowser)
|
|
76
78
|
await options.__testHookOnConnectToBrowser();
|
|
77
79
|
const version = await session.send("Browser.getVersion");
|
|
80
|
+
browser._revision = version.revision;
|
|
78
81
|
browser._version = version.product.substring(version.product.indexOf("/") + 1);
|
|
79
82
|
try {
|
|
80
83
|
browser._majorVersion = +browser._version.split(".")[0];
|
|
@@ -100,10 +103,10 @@ class CRBrowser extends import_browser.Browser {
|
|
|
100
103
|
const proxy = options.proxyOverride || options.proxy;
|
|
101
104
|
let proxyBypassList = void 0;
|
|
102
105
|
if (proxy) {
|
|
103
|
-
if (
|
|
104
|
-
proxyBypassList = proxy.bypass;
|
|
105
|
-
else
|
|
106
|
+
if (shouldProxyLoopback(proxy.bypass))
|
|
106
107
|
proxyBypassList = "<-loopback>" + (proxy.bypass ? `,${proxy.bypass}` : "");
|
|
108
|
+
else
|
|
109
|
+
proxyBypassList = proxy.bypass;
|
|
107
110
|
}
|
|
108
111
|
const { browserContextId } = await this._session.send("Target.createBrowserContext", {
|
|
109
112
|
disposeOnDetach: true,
|
|
@@ -389,7 +392,8 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
389
392
|
["midi-sysex", "midiSysex"],
|
|
390
393
|
["storage-access", "storageAccess"],
|
|
391
394
|
["local-fonts", "localFonts"],
|
|
392
|
-
["local-network-access", ["localNetworkAccess", "localNetwork", "loopbackNetwork"]]
|
|
395
|
+
["local-network-access", ["localNetworkAccess", "localNetwork", "loopbackNetwork"]],
|
|
396
|
+
["screen-wake-lock", "wakeLockScreen"]
|
|
393
397
|
]);
|
|
394
398
|
const grantPermissions = async (mapping) => {
|
|
395
399
|
const filtered = permissions.flatMap((permission) => {
|
|
@@ -446,7 +450,8 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
446
450
|
await page.delegate.addInitScript(initScript);
|
|
447
451
|
}
|
|
448
452
|
async doRemoveInitScripts(initScripts) {
|
|
449
|
-
for (const page of this.pages())
|
|
453
|
+
for (const page of this.pages())
|
|
454
|
+
await page.delegate.removeInitScripts(initScripts);
|
|
450
455
|
}
|
|
451
456
|
async doUpdateRequestInterception() {
|
|
452
457
|
for (const page of this.pages())
|
|
@@ -465,7 +470,6 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
465
470
|
async doClose(reason) {
|
|
466
471
|
await this.dialogManager.closeBeforeUnloadDialogs();
|
|
467
472
|
if (!this._browserContextId) {
|
|
468
|
-
await this.stopVideoRecording();
|
|
469
473
|
await this._browser.close({ reason });
|
|
470
474
|
return;
|
|
471
475
|
}
|
|
@@ -478,9 +482,6 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
478
482
|
this._browser._serviceWorkers.delete(targetId);
|
|
479
483
|
}
|
|
480
484
|
}
|
|
481
|
-
async stopVideoRecording() {
|
|
482
|
-
await Promise.all(this._crPages().map((crPage) => crPage._page.screencast.stopVideoRecording()));
|
|
483
|
-
}
|
|
484
485
|
onClosePersistent() {
|
|
485
486
|
}
|
|
486
487
|
async clearCache() {
|
|
@@ -511,15 +512,17 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
511
512
|
const rootSession = await this._browser._clientRootSession();
|
|
512
513
|
return rootSession.attachToTarget(targetId);
|
|
513
514
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
515
|
+
}
|
|
516
|
+
function shouldProxyLoopback(bypass) {
|
|
517
|
+
if (process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK)
|
|
518
|
+
return false;
|
|
519
|
+
const hosts = (bypass || "").split(",").map((s) => s.trim());
|
|
520
|
+
const shouldBypassSomeLoopback = ["localhost", "127.0.0.1", "::1", "[::]", "[::1]", "<loopback>", "<-loopback>"].some((host) => hosts.includes(host));
|
|
521
|
+
return !shouldBypassSomeLoopback;
|
|
520
522
|
}
|
|
521
523
|
// Annotate the CommonJS export names for ESM import in node:
|
|
522
524
|
0 && (module.exports = {
|
|
523
525
|
CRBrowser,
|
|
524
|
-
CRBrowserContext
|
|
526
|
+
CRBrowserContext,
|
|
527
|
+
shouldProxyLoopback
|
|
525
528
|
});
|
|
@@ -66,7 +66,6 @@ class JSCoverage {
|
|
|
66
66
|
this._eventListeners = [
|
|
67
67
|
import_eventsHelper.eventsHelper.addEventListener(this._client, "Debugger.scriptParsed", this._onScriptParsed.bind(this)),
|
|
68
68
|
import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this)),
|
|
69
|
-
import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.frameNavigated", this._onFrameNavigated.bind(this)),
|
|
70
69
|
import_eventsHelper.eventsHelper.addEventListener(this._client, "Debugger.paused", this._onDebuggerPaused.bind(this))
|
|
71
70
|
];
|
|
72
71
|
await Promise.all([
|
|
@@ -118,11 +117,6 @@ class JSCoverage {
|
|
|
118
117
|
}
|
|
119
118
|
return coverage;
|
|
120
119
|
}
|
|
121
|
-
_onFrameNavigated(event) {
|
|
122
|
-
if (event.frame.parentId)
|
|
123
|
-
return;
|
|
124
|
-
this._onExecutionContextsCleared();
|
|
125
|
-
}
|
|
126
120
|
}
|
|
127
121
|
class CSSCoverage {
|
|
128
122
|
constructor(client) {
|
|
@@ -142,8 +136,7 @@ class CSSCoverage {
|
|
|
142
136
|
this._stylesheetSources.clear();
|
|
143
137
|
this._eventListeners = [
|
|
144
138
|
import_eventsHelper.eventsHelper.addEventListener(this._client, "CSS.styleSheetAdded", this._onStyleSheet.bind(this)),
|
|
145
|
-
import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this))
|
|
146
|
-
import_eventsHelper.eventsHelper.addEventListener(this._client, "Page.frameNavigated", this._onFrameNavigated.bind(this))
|
|
139
|
+
import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this))
|
|
147
140
|
];
|
|
148
141
|
await Promise.all([
|
|
149
142
|
this._client.send("DOM.enable"),
|
|
@@ -199,11 +192,6 @@ class CSSCoverage {
|
|
|
199
192
|
}
|
|
200
193
|
return coverage;
|
|
201
194
|
}
|
|
202
|
-
_onFrameNavigated(event) {
|
|
203
|
-
if (event.frame.parentId)
|
|
204
|
-
return;
|
|
205
|
-
this._onExecutionContextsCleared();
|
|
206
|
-
}
|
|
207
195
|
}
|
|
208
196
|
function convertToDisjointRanges(nestedRanges) {
|
|
209
197
|
const points = [];
|
|
@@ -70,6 +70,7 @@ class CRDevTools {
|
|
|
70
70
|
}).catch((e) => null);
|
|
71
71
|
});
|
|
72
72
|
Promise.all([
|
|
73
|
+
session.send("Runtime.enable"),
|
|
73
74
|
session.send("Runtime.addBinding", { name: kBindingName }),
|
|
74
75
|
session.send("Page.enable"),
|
|
75
76
|
session.send("Page.addScriptToEvaluateOnNewDocument", { source: `
|