patchright-core 1.56.0 → 1.57.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 +40 -381
- package/bin/install_webkit_wsl.ps1 +1 -3
- package/browsers.json +13 -13
- package/lib/cli/program.js +14 -57
- package/lib/client/api.js +0 -3
- package/lib/client/browserContext.js +22 -4
- package/lib/client/consoleMessage.js +5 -1
- package/lib/client/electron.js +1 -1
- package/lib/client/events.js +2 -1
- package/lib/client/locator.js +4 -1
- package/lib/client/page.js +2 -5
- package/lib/client/playwright.js +1 -5
- package/lib/client/tracing.js +6 -4
- package/lib/client/worker.js +22 -0
- package/lib/generated/clockSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/inProcessFactory.js +0 -2
- package/lib/protocol/validator.js +24 -46
- package/lib/server/android/android.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +26 -11
- package/lib/server/bidi/bidiChromium.js +1 -1
- package/lib/server/bidi/bidiFirefox.js +1 -1
- package/lib/server/bidi/bidiPage.js +25 -5
- package/lib/server/browserContext.js +9 -10
- package/lib/server/chromium/chromium.js +12 -1
- package/lib/server/chromium/chromiumSwitches.js +10 -1
- package/lib/server/chromium/crBrowser.js +10 -1
- package/lib/server/chromium/crNetworkManager.js +15 -6
- package/lib/server/chromium/crPage.js +7 -9
- package/lib/server/chromium/crServiceWorker.js +14 -1
- package/lib/server/chromium/videoRecorder.js +14 -12
- package/lib/server/console.js +5 -1
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +23 -6
- package/lib/server/dispatchers/pageDispatcher.js +10 -22
- package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
- package/lib/server/electron/electron.js +1 -1
- package/lib/server/firefox/ffPage.js +3 -6
- package/lib/server/firefox/firefox.js +12 -1
- package/lib/server/frameSelectors.js +2 -4
- package/lib/server/frames.js +6 -1
- package/lib/server/input.js +7 -3
- package/lib/server/localUtils.js +4 -8
- package/lib/server/page.js +54 -38
- package/lib/server/playwright.js +2 -4
- package/lib/server/recorder/recorderApp.js +1 -1
- package/lib/server/recorder.js +3 -2
- package/lib/server/registry/index.js +114 -48
- package/lib/server/registry/oopDownloadBrowserMain.js +6 -2
- package/lib/server/socksClientCertificatesInterceptor.js +1 -1
- package/lib/server/trace/recorder/tracing.js +2 -0
- package/lib/server/trace/viewer/traceViewer.js +37 -36
- package/lib/server/utils/comparators.js +3 -25
- package/lib/server/utils/hostPlatform.js +15 -3
- package/lib/server/utils/imageUtils.js +141 -0
- package/lib/server/utils/network.js +22 -16
- package/lib/server/webkit/webkit.js +1 -10
- package/lib/server/webkit/wkPage.js +1 -5
- package/lib/server/webkit/wkWorkers.js +2 -1
- package/lib/utils/isomorphic/ariaSnapshot.js +5 -0
- package/lib/utils/isomorphic/locatorGenerators.js +24 -8
- package/lib/utils/isomorphic/mimeType.js +1 -1
- package/lib/utils/isomorphic/protocolFormatter.js +3 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +2 -1
- package/lib/utils/isomorphic/urlMatch.js +19 -5
- package/lib/utils.js +2 -0
- package/lib/utilsBundle.js +6 -3
- package/lib/utilsBundleImpl/index.js +171 -171
- package/lib/vite/htmlReport/index.html +18 -18
- package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +25 -0
- package/lib/vite/recorder/assets/{index-Y-X2TGJv.js → index-CpZVd2nA.js} +32 -32
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +25 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +266 -0
- package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
- package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
- package/lib/vite/traceViewer/index.C8xAeo93.js +2 -0
- package/lib/vite/traceViewer/index.html +6 -6
- package/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/lib/vite/traceViewer/snapshot.html +3 -3
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/{uiMode.B_CpmIpF.js → uiMode.BltraIJB.js} +3 -3
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/package.json +1 -1
- package/types/protocol.d.ts +213 -98
- package/types/types.d.ts +122 -118
- package/lib/client/accessibility.js +0 -49
- package/lib/server/accessibility.js +0 -69
- package/lib/server/chromium/crAccessibility.js +0 -263
- package/lib/server/firefox/ffAccessibility.js +0 -238
- package/lib/server/webkit/wkAccessibility.js +0 -237
- package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
- package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
- package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
- package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
- package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
- package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
- package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
|
@@ -62,12 +62,16 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
62
62
|
browser._bidiSessionInfo = await browser._browserSession.send("session.new", {
|
|
63
63
|
capabilities: {
|
|
64
64
|
alwaysMatch: {
|
|
65
|
-
acceptInsecureCerts: options.persistent?.internalIgnoreHTTPSErrors || options.persistent?.ignoreHTTPSErrors,
|
|
66
|
-
proxy: getProxyConfiguration(options.originalLaunchOptions.proxyOverride ?? options.proxy),
|
|
67
|
-
unhandledPromptBehavior: {
|
|
65
|
+
"acceptInsecureCerts": options.persistent?.internalIgnoreHTTPSErrors || options.persistent?.ignoreHTTPSErrors,
|
|
66
|
+
"proxy": getProxyConfiguration(options.originalLaunchOptions.proxyOverride ?? options.proxy),
|
|
67
|
+
"unhandledPromptBehavior": {
|
|
68
68
|
default: bidi.Session.UserPromptHandlerType.Ignore
|
|
69
69
|
},
|
|
70
|
-
webSocketUrl: true
|
|
70
|
+
"webSocketUrl": true,
|
|
71
|
+
// Chrome with WebDriver BiDi does not support prerendering
|
|
72
|
+
// yet because WebDriver BiDi behavior is not specified. See
|
|
73
|
+
// https://github.com/w3c/webdriver-bidi/issues/321.
|
|
74
|
+
"goog:prerenderingDisabled": true
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
});
|
|
@@ -76,7 +80,8 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
76
80
|
"browsingContext",
|
|
77
81
|
"network",
|
|
78
82
|
"log",
|
|
79
|
-
"script"
|
|
83
|
+
"script",
|
|
84
|
+
"input"
|
|
80
85
|
]
|
|
81
86
|
});
|
|
82
87
|
await browser._browserSession.send("network.addDataCollector", {
|
|
@@ -122,16 +127,13 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
122
127
|
_onBrowsingContextCreated(event) {
|
|
123
128
|
if (event.parent) {
|
|
124
129
|
const parentFrameId = event.parent;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (!parentFrame)
|
|
128
|
-
continue;
|
|
130
|
+
const page2 = this._findPageForFrame(parentFrameId);
|
|
131
|
+
if (page2) {
|
|
129
132
|
page2._session.addFrameBrowsingContext(event.context);
|
|
130
133
|
page2._page.frameManager.frameAttached(event.context, parentFrameId);
|
|
131
134
|
const frame = page2._page.frameManager.frame(event.context);
|
|
132
135
|
if (frame)
|
|
133
136
|
frame._url = event.url;
|
|
134
|
-
return;
|
|
135
137
|
}
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
@@ -141,7 +143,7 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
141
143
|
if (!context)
|
|
142
144
|
return;
|
|
143
145
|
const session = this._connection.createMainFrameBrowsingContextSession(event.context);
|
|
144
|
-
const opener = event.originalOpener && this.
|
|
146
|
+
const opener = event.originalOpener && this._findPageForFrame(event.originalOpener);
|
|
145
147
|
const page = new import_bidiPage.BidiPage(context, session, opener || null);
|
|
146
148
|
page._page.mainFrame()._url = event.url;
|
|
147
149
|
this._bidiPages.set(event.context, page);
|
|
@@ -171,6 +173,12 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
171
173
|
return;
|
|
172
174
|
}
|
|
173
175
|
}
|
|
176
|
+
_findPageForFrame(frameId) {
|
|
177
|
+
for (const page of this._bidiPages.values()) {
|
|
178
|
+
if (page._page.frameManager.frame(frameId))
|
|
179
|
+
return page;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
174
182
|
}
|
|
175
183
|
class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
176
184
|
constructor(browser, browserContextId, options) {
|
|
@@ -207,6 +215,8 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
|
207
215
|
userContexts: [this._userContextId()]
|
|
208
216
|
}));
|
|
209
217
|
}
|
|
218
|
+
if (this._options.extraHTTPHeaders)
|
|
219
|
+
promises.push(this.doUpdateExtraHTTPHeaders());
|
|
210
220
|
await Promise.all(promises);
|
|
211
221
|
}
|
|
212
222
|
possiblyUninitializedPages() {
|
|
@@ -300,6 +310,11 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
|
300
310
|
});
|
|
301
311
|
}
|
|
302
312
|
async doUpdateExtraHTTPHeaders() {
|
|
313
|
+
const allHeaders = this._options.extraHTTPHeaders || [];
|
|
314
|
+
await this._browser._browserSession.send("network.setExtraHeaders", {
|
|
315
|
+
headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
|
|
316
|
+
userContexts: [this._userContextId()]
|
|
317
|
+
});
|
|
303
318
|
}
|
|
304
319
|
async setUserAgent(userAgent) {
|
|
305
320
|
this._options.userAgent = userAgent;
|
|
@@ -40,7 +40,7 @@ var import_chromiumSwitches = require("../chromium/chromiumSwitches");
|
|
|
40
40
|
var import_chromium = require("../chromium/chromium");
|
|
41
41
|
class BidiChromium extends import_browserType.BrowserType {
|
|
42
42
|
constructor(parent) {
|
|
43
|
-
super(parent, "
|
|
43
|
+
super(parent, "chromium");
|
|
44
44
|
}
|
|
45
45
|
async connectToTransport(transport, options, browserLogsCollector) {
|
|
46
46
|
const bidiTransport = await require("./bidiOverCdp").connectBidiOverCdp(transport);
|
|
@@ -41,7 +41,7 @@ var import_firefoxPrefs = require("./third_party/firefoxPrefs");
|
|
|
41
41
|
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
|
42
42
|
class BidiFirefox extends import_browserType.BrowserType {
|
|
43
43
|
constructor(parent) {
|
|
44
|
-
super(parent, "
|
|
44
|
+
super(parent, "firefox");
|
|
45
45
|
}
|
|
46
46
|
executablePath() {
|
|
47
47
|
return "";
|
|
@@ -42,6 +42,7 @@ var import_bidiInput = require("./bidiInput");
|
|
|
42
42
|
var import_bidiNetworkManager = require("./bidiNetworkManager");
|
|
43
43
|
var import_bidiPdf = require("./bidiPdf");
|
|
44
44
|
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
|
45
|
+
var network = __toESM(require("../network"));
|
|
45
46
|
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
|
46
47
|
const kPlaywrightBindingChannel = "playwrightChannel";
|
|
47
48
|
class BidiPage {
|
|
@@ -75,7 +76,8 @@ class BidiPage {
|
|
|
75
76
|
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadWillBegin", this._onDownloadWillBegin.bind(this)),
|
|
76
77
|
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadEnd", this._onDownloadEnded.bind(this)),
|
|
77
78
|
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)),
|
|
78
|
-
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this))
|
|
79
|
+
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this)),
|
|
80
|
+
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "input.fileDialogOpened", this._onFileDialogOpened.bind(this))
|
|
79
81
|
];
|
|
80
82
|
this._initialize().then(
|
|
81
83
|
() => this._page.reportAsNew(this._opener?._page),
|
|
@@ -113,6 +115,7 @@ class BidiPage {
|
|
|
113
115
|
const delegate2 = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
|
|
114
116
|
const worker = new import_page.Worker(this._page, realmInfo.origin);
|
|
115
117
|
this._realmToWorkerContext.set(realmInfo.realm, worker.createExecutionContext(delegate2));
|
|
118
|
+
worker.workerScriptLoaded();
|
|
116
119
|
this._page.addWorker(realmInfo.realm, worker);
|
|
117
120
|
return;
|
|
118
121
|
}
|
|
@@ -260,7 +263,17 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
260
263
|
return;
|
|
261
264
|
const callFrame = params.stackTrace?.callFrames[0];
|
|
262
265
|
const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
|
|
263
|
-
this._page.addConsoleMessage(entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
|
|
266
|
+
this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
|
|
267
|
+
}
|
|
268
|
+
async _onFileDialogOpened(params) {
|
|
269
|
+
if (!params.element)
|
|
270
|
+
return;
|
|
271
|
+
const frame = this._page.frameManager.frame(params.context);
|
|
272
|
+
if (!frame)
|
|
273
|
+
return;
|
|
274
|
+
const executionContext = await frame._mainContext();
|
|
275
|
+
const handle = await toBidiExecutionContext(executionContext).remoteObjectForNodeId(executionContext, { sharedId: params.element.sharedId });
|
|
276
|
+
await this._page._onFileChooserOpened(handle);
|
|
264
277
|
}
|
|
265
278
|
async navigateFrame(frame, url, referrer) {
|
|
266
279
|
const { navigation } = await this._session.send("browsingContext.navigate", {
|
|
@@ -270,6 +283,14 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
270
283
|
return { newDocumentId: navigation || void 0 };
|
|
271
284
|
}
|
|
272
285
|
async updateExtraHTTPHeaders() {
|
|
286
|
+
const allHeaders = network.mergeHeaders([
|
|
287
|
+
this._browserContext._options.extraHTTPHeaders,
|
|
288
|
+
this._page.extraHTTPHeaders()
|
|
289
|
+
]);
|
|
290
|
+
await this._session.send("network.setExtraHeaders", {
|
|
291
|
+
headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
|
|
292
|
+
contexts: [this._session.sessionId]
|
|
293
|
+
});
|
|
273
294
|
}
|
|
274
295
|
async updateEmulateMedia() {
|
|
275
296
|
}
|
|
@@ -379,6 +400,8 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
379
400
|
}
|
|
380
401
|
}
|
|
381
402
|
async setBackgroundColor(color) {
|
|
403
|
+
if (color)
|
|
404
|
+
throw new Error("Not implemented");
|
|
382
405
|
}
|
|
383
406
|
async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) {
|
|
384
407
|
const rect = documentRect || viewportRect;
|
|
@@ -503,9 +526,6 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
503
526
|
const executionContext = toBidiExecutionContext(to);
|
|
504
527
|
return await executionContext.remoteObjectForNodeId(to, nodeId);
|
|
505
528
|
}
|
|
506
|
-
async getAccessibilityTree(needle) {
|
|
507
|
-
throw new Error("Method not implemented.");
|
|
508
|
-
}
|
|
509
529
|
async inputActionEpilogue() {
|
|
510
530
|
}
|
|
511
531
|
async resetForReuse(progress) {
|
|
@@ -69,7 +69,6 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
69
69
|
this._creatingStorageStatePage = false;
|
|
70
70
|
this.initScripts = [];
|
|
71
71
|
this._routesInFlight = /* @__PURE__ */ new Set();
|
|
72
|
-
this._playwrightBindingExposed = false;
|
|
73
72
|
this.attribution.context = this;
|
|
74
73
|
this._browser = browser;
|
|
75
74
|
this._options = options;
|
|
@@ -229,17 +228,17 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
229
228
|
return this._pageBindings.get(name)?.forClient;
|
|
230
229
|
}
|
|
231
230
|
async exposePlaywrightBindingIfNeeded() {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
await this.
|
|
231
|
+
this._playwrightBindingExposed ??= (async () => {
|
|
232
|
+
await this.doExposePlaywrightBinding();
|
|
233
|
+
this.bindingsInitScript = import_page2.PageBinding.createInitScript();
|
|
234
|
+
this.initScripts.push(this.bindingsInitScript);
|
|
235
|
+
await this.doAddInitScript(this.bindingsInitScript);
|
|
236
|
+
await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
|
|
237
|
+
})();
|
|
238
|
+
return await this._playwrightBindingExposed;
|
|
240
239
|
}
|
|
241
240
|
needsPlaywrightBinding() {
|
|
242
|
-
return this._playwrightBindingExposed;
|
|
241
|
+
return this._playwrightBindingExposed !== void 0;
|
|
243
242
|
}
|
|
244
243
|
async exposeBinding(progress, name, needsHandle, playwrightBinding, forClient) {
|
|
245
244
|
if (this._pageBindings.has(name))
|
|
@@ -55,11 +55,22 @@ var import_fileUtils = require("../utils/fileUtils");
|
|
|
55
55
|
var import_processLauncher = require("../utils/processLauncher");
|
|
56
56
|
const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
|
|
57
57
|
class Chromium extends import_browserType.BrowserType {
|
|
58
|
-
constructor(parent) {
|
|
58
|
+
constructor(parent, bidiChromium) {
|
|
59
59
|
super(parent, "chromium");
|
|
60
|
+
this._bidiChromium = bidiChromium;
|
|
60
61
|
if ((0, import_utils.debugMode)() === "inspector")
|
|
61
62
|
this._devtools = this._createDevTools();
|
|
62
63
|
}
|
|
64
|
+
launch(progress, options, protocolLogger) {
|
|
65
|
+
if (options.channel?.startsWith("bidi-"))
|
|
66
|
+
return this._bidiChromium.launch(progress, options, protocolLogger);
|
|
67
|
+
return super.launch(progress, options, protocolLogger);
|
|
68
|
+
}
|
|
69
|
+
async launchPersistentContext(progress, userDataDir, options) {
|
|
70
|
+
if (options.channel?.startsWith("bidi-"))
|
|
71
|
+
return this._bidiChromium.launchPersistentContext(progress, userDataDir, options);
|
|
72
|
+
return super.launchPersistentContext(progress, userDataDir, options);
|
|
73
|
+
}
|
|
63
74
|
async connectOverCDP(progress, endpointURL, options) {
|
|
64
75
|
return await this._connectOverCDPInternal(progress, endpointURL, options);
|
|
65
76
|
}
|
|
@@ -46,9 +46,11 @@ const disabledFeatures = (assistantMode) => [
|
|
|
46
46
|
"AutoDeElevate",
|
|
47
47
|
// See https://github.com/microsoft/playwright/issues/37714
|
|
48
48
|
"RenderDocument",
|
|
49
|
+
// Prevents downloading optimization hints on startup.
|
|
50
|
+
"OptimizationHints",
|
|
49
51
|
assistantMode ? "AutomationControlled" : ""
|
|
50
52
|
].filter(Boolean);
|
|
51
|
-
const chromiumSwitches = (assistantMode, channel) => [
|
|
53
|
+
const chromiumSwitches = (assistantMode, channel, android) => [
|
|
52
54
|
"--disable-field-trial-config",
|
|
53
55
|
// https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
|
|
54
56
|
"--disable-background-networking",
|
|
@@ -75,6 +77,13 @@ const chromiumSwitches = (assistantMode, channel) => [
|
|
|
75
77
|
"--disable-search-engine-choice-screen",
|
|
76
78
|
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
|
|
77
79
|
"--edge-skip-compat-layer-relaunch",
|
|
80
|
+
// This disables Chrome for Testing infobar that is visible in the persistent context.
|
|
81
|
+
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
|
|
82
|
+
"--disable-infobars",
|
|
83
|
+
// Less annoying popups.
|
|
84
|
+
"--disable-search-engine-choice-screen",
|
|
85
|
+
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
|
|
86
|
+
android ? "" : "--disable-sync",
|
|
78
87
|
"--disable-blink-features=AutomationControlled"
|
|
79
88
|
].filter(Boolean);
|
|
80
89
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -53,6 +53,7 @@ class CRBrowser extends import_browser.Browser {
|
|
|
53
53
|
this._crPages = /* @__PURE__ */ new Map();
|
|
54
54
|
this._serviceWorkers = /* @__PURE__ */ new Map();
|
|
55
55
|
this._version = "";
|
|
56
|
+
this._majorVersion = 0;
|
|
56
57
|
this._tracingRecording = false;
|
|
57
58
|
this._userAgent = "";
|
|
58
59
|
this._connection = connection;
|
|
@@ -75,6 +76,10 @@ class CRBrowser extends import_browser.Browser {
|
|
|
75
76
|
await options.__testHookOnConnectToBrowser();
|
|
76
77
|
const version = await session.send("Browser.getVersion");
|
|
77
78
|
browser._version = version.product.substring(version.product.indexOf("/") + 1);
|
|
79
|
+
try {
|
|
80
|
+
browser._majorVersion = +browser._version.split(".")[0];
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
78
83
|
browser._userAgent = version.userAgent;
|
|
79
84
|
browser.options.headful = !version.userAgent.includes("Headless");
|
|
80
85
|
if (!options.persistent) {
|
|
@@ -116,6 +121,9 @@ class CRBrowser extends import_browser.Browser {
|
|
|
116
121
|
version() {
|
|
117
122
|
return this._version;
|
|
118
123
|
}
|
|
124
|
+
majorVersion() {
|
|
125
|
+
return this._majorVersion;
|
|
126
|
+
}
|
|
119
127
|
userAgent() {
|
|
120
128
|
return this._userAgent;
|
|
121
129
|
}
|
|
@@ -379,7 +387,8 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
379
387
|
// chrome-specific permissions we have.
|
|
380
388
|
["midi-sysex", "midiSysex"],
|
|
381
389
|
["storage-access", "storageAccess"],
|
|
382
|
-
["local-fonts", "localFonts"]
|
|
390
|
+
["local-fonts", "localFonts"],
|
|
391
|
+
["local-network-access", "localNetworkAccess"]
|
|
383
392
|
]);
|
|
384
393
|
const filtered = permissions.map((permission) => {
|
|
385
394
|
const protocolPermission = webPermissionToProtocol.get(permission);
|
|
@@ -650,10 +650,13 @@ class RouteImpl {
|
|
|
650
650
|
let hasScriptSrc = false;
|
|
651
651
|
for (let directive of directives) {
|
|
652
652
|
if (!directive.trim()) continue;
|
|
653
|
-
const
|
|
654
|
-
if (
|
|
655
|
-
|
|
656
|
-
|
|
653
|
+
const directiveMatch = directive.match(/^([a-zA-Z-]+)\s+(.*)$/);
|
|
654
|
+
if (!directiveMatch) {
|
|
655
|
+
fixedDirectives.push(directive);
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
const directiveName = directiveMatch[1].toLowerCase();
|
|
659
|
+
const directiveValues = directiveMatch[2].split(/\s+/).filter((v) => v.length > 0);
|
|
657
660
|
switch (directiveName) {
|
|
658
661
|
case "script-src":
|
|
659
662
|
hasScriptSrc = true;
|
|
@@ -664,6 +667,12 @@ class RouteImpl {
|
|
|
664
667
|
if (!values.includes("'unsafe-eval'")) {
|
|
665
668
|
values.push("'unsafe-eval'");
|
|
666
669
|
}
|
|
670
|
+
if (!values.includes("'unsafe-inline'") && !scriptNonce) {
|
|
671
|
+
values.push("'unsafe-inline'");
|
|
672
|
+
}
|
|
673
|
+
if (!values.includes("*") && !values.includes("'self'") && !values.some((v) => v.includes("https:"))) {
|
|
674
|
+
values.push("*");
|
|
675
|
+
}
|
|
667
676
|
fixedDirectives.push(`script-src ${values.join(" ")}`);
|
|
668
677
|
break;
|
|
669
678
|
case "style-src":
|
|
@@ -709,9 +718,9 @@ class RouteImpl {
|
|
|
709
718
|
}
|
|
710
719
|
if (!hasScriptSrc) {
|
|
711
720
|
if (scriptNonce) {
|
|
712
|
-
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}'
|
|
721
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}' *`);
|
|
713
722
|
} else {
|
|
714
|
-
fixedDirectives.push(`script-src 'self' 'unsafe-eval'
|
|
723
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'unsafe-inline' *`);
|
|
715
724
|
}
|
|
716
725
|
}
|
|
717
726
|
return fixedDirectives.join("; ");
|
|
@@ -44,7 +44,6 @@ var import_helper = require("../helper");
|
|
|
44
44
|
var network = __toESM(require("../network"));
|
|
45
45
|
var import_page = require("../page");
|
|
46
46
|
var import_registry = require("../registry");
|
|
47
|
-
var import_crAccessibility = require("./crAccessibility");
|
|
48
47
|
var import_crCoverage = require("./crCoverage");
|
|
49
48
|
var import_crDragDrop = require("./crDragDrop");
|
|
50
49
|
var import_crExecutionContext = require("./crExecutionContext");
|
|
@@ -271,9 +270,6 @@ class CRPage {
|
|
|
271
270
|
async adoptElementHandle(handle, to) {
|
|
272
271
|
return this._sessionForHandle(handle)._adoptElementHandle(handle, to);
|
|
273
272
|
}
|
|
274
|
-
async getAccessibilityTree(needle) {
|
|
275
|
-
return (0, import_crAccessibility.getAccessibilityTree)(this._mainFrameSession._client, needle);
|
|
276
|
-
}
|
|
277
273
|
async inputActionEpilogue() {
|
|
278
274
|
await this._mainFrameSession._client.send("Page.enable").catch((e) => {
|
|
279
275
|
});
|
|
@@ -450,8 +446,6 @@ class FrameSession {
|
|
|
450
446
|
if (!this._page.isStorageStatePage) {
|
|
451
447
|
if (this._crPage._browserContext.needsPlaywrightBinding())
|
|
452
448
|
promises.push(this.exposePlaywrightBinding());
|
|
453
|
-
if (this._isMainFrame())
|
|
454
|
-
promises.push(this._client.send("Emulation.setFocusEmulationEnabled", { enabled: true }));
|
|
455
449
|
const options = this._crPage._browserContext._options;
|
|
456
450
|
if (options.bypassCSP)
|
|
457
451
|
promises.push(this._client.send("Page.setBypassCSP", { enabled: true }));
|
|
@@ -680,6 +674,10 @@ class FrameSession {
|
|
|
680
674
|
var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
|
|
681
675
|
worker.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, { id: executionContextId }));
|
|
682
676
|
}
|
|
677
|
+
if (this._crPage._browserContext._browser.majorVersion() >= 143)
|
|
678
|
+
session.on("Inspector.workerScriptLoaded", () => worker.workerScriptLoaded());
|
|
679
|
+
else
|
|
680
|
+
worker.workerScriptLoaded();
|
|
683
681
|
this._crPage._networkManager.addSession(session, this._page.frameManager.frame(this._targetId) ?? void 0).catch(() => {
|
|
684
682
|
});
|
|
685
683
|
session._sendMayFail("Runtime.runIfWaitingForDebugger");
|
|
@@ -688,7 +686,7 @@ class FrameSession {
|
|
|
688
686
|
session.on("Target.detachedFromTarget", (event2) => this._onDetachedFromTarget(event2));
|
|
689
687
|
session.on("Runtime.consoleAPICalled", (event2) => {
|
|
690
688
|
const args = event2.args.map((o) => (0, import_crExecutionContext.createHandle)(worker.existingExecutionContext, o));
|
|
691
|
-
this._page.addConsoleMessage(event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
|
|
689
|
+
this._page.addConsoleMessage(worker, event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
|
|
692
690
|
});
|
|
693
691
|
session.on("Runtime.exceptionThrown", (exception) => this._page.addPageError((0, import_crProtocolHelper.exceptionToError)(exception.exceptionDetails)));
|
|
694
692
|
}
|
|
@@ -723,7 +721,7 @@ class FrameSession {
|
|
|
723
721
|
if (!context)
|
|
724
722
|
return;
|
|
725
723
|
const values = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(context, arg));
|
|
726
|
-
this._page.addConsoleMessage(event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
724
|
+
this._page.addConsoleMessage(null, event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
727
725
|
}
|
|
728
726
|
async _onBindingCalled(event) {
|
|
729
727
|
const pageOrError = await this._crPage._page.waitForInitializedOrError();
|
|
@@ -765,7 +763,7 @@ class FrameSession {
|
|
|
765
763
|
lineNumber: lineNumber || 0,
|
|
766
764
|
columnNumber: 0
|
|
767
765
|
};
|
|
768
|
-
this._page.addConsoleMessage(level, [], location, text);
|
|
766
|
+
this._page.addConsoleMessage(null, level, [], location, text);
|
|
769
767
|
}
|
|
770
768
|
}
|
|
771
769
|
async _onFileChooserOpened(event) {
|
|
@@ -36,16 +36,22 @@ var import_crExecutionContext = require("./crExecutionContext");
|
|
|
36
36
|
var import_crNetworkManager = require("./crNetworkManager");
|
|
37
37
|
var import_browserContext = require("../browserContext");
|
|
38
38
|
var network = __toESM(require("../network"));
|
|
39
|
+
var import_console = require("../console");
|
|
40
|
+
var import_crProtocolHelper = require("./crProtocolHelper");
|
|
39
41
|
class CRServiceWorker extends import_page.Worker {
|
|
40
42
|
constructor(browserContext, session, url) {
|
|
41
43
|
super(browserContext, url);
|
|
42
44
|
this._session = session;
|
|
43
45
|
this.browserContext = browserContext;
|
|
44
|
-
if (
|
|
46
|
+
if (!process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_NETWORK)
|
|
45
47
|
this._networkManager = new import_crNetworkManager.CRNetworkManager(null, this);
|
|
46
48
|
session.once("Runtime.executionContextCreated", (event) => {
|
|
47
49
|
this.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, event.context));
|
|
48
50
|
});
|
|
51
|
+
if (this.browserContext._browser.majorVersion() >= 143)
|
|
52
|
+
session.on("Inspector.workerScriptLoaded", () => this.workerScriptLoaded());
|
|
53
|
+
else
|
|
54
|
+
this.workerScriptLoaded();
|
|
49
55
|
if (this._networkManager && this._isNetworkInspectionEnabled()) {
|
|
50
56
|
this.updateRequestInterception();
|
|
51
57
|
this.updateExtraHTTPHeaders();
|
|
@@ -59,6 +65,13 @@ class CRServiceWorker extends import_page.Worker {
|
|
|
59
65
|
).catch(() => {
|
|
60
66
|
});
|
|
61
67
|
}
|
|
68
|
+
session.on("Runtime.consoleAPICalled", (event) => {
|
|
69
|
+
if (!this.existingExecutionContext || process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_CONSOLE)
|
|
70
|
+
return;
|
|
71
|
+
const args = event.args.map((o) => (0, import_crExecutionContext.createHandle)(this.existingExecutionContext, o));
|
|
72
|
+
const message = new import_console.ConsoleMessage(null, this, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
73
|
+
this.browserContext.emit(import_browserContext.BrowserContext.Events.Console, message);
|
|
74
|
+
});
|
|
62
75
|
session.send("Runtime.runIfWaitingForDebugger").catch((e) => {
|
|
63
76
|
});
|
|
64
77
|
session.on("Inspector.targetReloadedAfterCrash", () => {
|
|
@@ -30,9 +30,9 @@ class VideoRecorder {
|
|
|
30
30
|
this._process = null;
|
|
31
31
|
this._gracefullyClose = null;
|
|
32
32
|
this._lastWritePromise = Promise.resolve();
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
33
|
+
this._firstFrameTimestamp = 0;
|
|
34
|
+
this._lastFrame = null;
|
|
35
|
+
this._lastWriteNodeTime = 0;
|
|
36
36
|
this._frameQueue = [];
|
|
37
37
|
this._isStopped = false;
|
|
38
38
|
this._ffmpegPath = ffmpegPath;
|
|
@@ -77,16 +77,17 @@ class VideoRecorder {
|
|
|
77
77
|
(0, import_utils.assert)(this._process);
|
|
78
78
|
if (this._isStopped)
|
|
79
79
|
return;
|
|
80
|
-
if (this.
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
if (!this._firstFrameTimestamp)
|
|
81
|
+
this._firstFrameTimestamp = timestamp;
|
|
82
|
+
const frameNumber = Math.floor((timestamp - this._firstFrameTimestamp) * fps);
|
|
83
|
+
if (this._lastFrame) {
|
|
84
|
+
const repeatCount = frameNumber - this._lastFrame.frameNumber;
|
|
83
85
|
for (let i = 0; i < repeatCount; ++i)
|
|
84
|
-
this._frameQueue.push(this.
|
|
86
|
+
this._frameQueue.push(this._lastFrame.buffer);
|
|
85
87
|
this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames());
|
|
86
88
|
}
|
|
87
|
-
this.
|
|
88
|
-
this.
|
|
89
|
-
this._lastWriteTimestamp = (0, import_utils.monotonicTime)();
|
|
89
|
+
this._lastFrame = { buffer: frame, timestamp, frameNumber };
|
|
90
|
+
this._lastWriteNodeTime = (0, import_utils.monotonicTime)();
|
|
90
91
|
}
|
|
91
92
|
async _sendFrames() {
|
|
92
93
|
while (this._frameQueue.length)
|
|
@@ -99,9 +100,10 @@ class VideoRecorder {
|
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
async stop() {
|
|
102
|
-
if (this._isStopped)
|
|
103
|
+
if (this._isStopped || !this._lastFrame)
|
|
103
104
|
return;
|
|
104
|
-
|
|
105
|
+
const addTime = Math.max(((0, import_utils.monotonicTime)() - this._lastWriteNodeTime) / 1e3, 1);
|
|
106
|
+
this.writeFrame(Buffer.from([]), this._lastFrame.timestamp + addTime);
|
|
105
107
|
this._isStopped = true;
|
|
106
108
|
await this._lastWritePromise;
|
|
107
109
|
await this._gracefullyClose();
|
package/lib/server/console.js
CHANGED
|
@@ -22,8 +22,9 @@ __export(console_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(console_exports);
|
|
24
24
|
class ConsoleMessage {
|
|
25
|
-
constructor(page, type, text, args, location) {
|
|
25
|
+
constructor(page, worker, type, text, args, location) {
|
|
26
26
|
this._page = page;
|
|
27
|
+
this._worker = worker;
|
|
27
28
|
this._type = type;
|
|
28
29
|
this._text = text;
|
|
29
30
|
this._args = args;
|
|
@@ -32,6 +33,9 @@ class ConsoleMessage {
|
|
|
32
33
|
page() {
|
|
33
34
|
return this._page;
|
|
34
35
|
}
|
|
36
|
+
worker() {
|
|
37
|
+
return this._worker;
|
|
38
|
+
}
|
|
35
39
|
type() {
|
|
36
40
|
return this._type;
|
|
37
41
|
}
|