patchright-core 1.57.0 → 1.58.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ThirdPartyNotices.txt +3223 -308
- package/browsers.json +21 -22
- package/lib/cli/program.js +4 -5
- package/lib/client/api.js +3 -0
- package/lib/client/browser.js +3 -5
- package/lib/client/browserContext.js +40 -4
- package/lib/client/browserType.js +4 -3
- package/lib/client/connection.js +4 -0
- package/lib/client/elementHandle.js +3 -0
- package/lib/client/events.js +3 -0
- package/lib/client/fetch.js +3 -4
- package/lib/client/frame.js +10 -1
- package/lib/client/locator.js +8 -0
- package/lib/client/network.js +5 -1
- package/lib/client/page.js +29 -1
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +3 -0
- package/lib/client/tracing.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/mcpBundle.js +84 -0
- package/lib/mcpBundleImpl/index.js +147 -0
- package/lib/protocol/serializers.js +5 -0
- package/lib/protocol/validator.js +88 -4
- package/lib/remote/playwrightServer.js +1 -2
- package/lib/server/agent/actionRunner.js +335 -0
- package/lib/server/agent/actions.js +128 -0
- package/lib/server/agent/codegen.js +111 -0
- package/lib/server/agent/context.js +150 -0
- package/lib/server/agent/expectTools.js +156 -0
- package/lib/server/agent/pageAgent.js +204 -0
- package/lib/server/agent/performTools.js +262 -0
- package/lib/server/agent/tool.js +109 -0
- package/lib/server/artifact.js +1 -1
- package/lib/server/bidi/bidiBrowser.js +56 -12
- package/lib/server/bidi/bidiChromium.js +8 -12
- package/lib/server/bidi/bidiConnection.js +1 -0
- package/lib/server/bidi/bidiDeserializer.js +116 -0
- package/lib/server/bidi/bidiExecutionContext.js +75 -29
- package/lib/server/bidi/bidiFirefox.js +6 -8
- package/lib/server/bidi/bidiNetworkManager.js +1 -1
- package/lib/server/bidi/bidiPage.js +39 -28
- package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
- package/lib/server/browserContext.js +34 -26
- package/lib/server/browserType.js +12 -4
- package/lib/server/chromium/chromium.js +14 -20
- package/lib/server/chromium/chromiumSwitches.js +2 -2
- package/lib/server/chromium/crBrowser.js +22 -12
- package/lib/server/chromium/crConnection.js +0 -5
- package/lib/server/chromium/crCoverage.js +13 -1
- package/lib/server/chromium/crDevTools.js +0 -2
- package/lib/server/chromium/crNetworkManager.js +92 -12
- package/lib/server/chromium/crPage.js +62 -116
- package/lib/server/codegen/javascript.js +6 -29
- package/lib/server/deviceDescriptorsSource.json +56 -56
- package/lib/server/dispatchers/browserContextDispatcher.js +3 -2
- package/lib/server/dispatchers/dispatcher.js +6 -13
- package/lib/server/dispatchers/frameDispatcher.js +1 -1
- package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
- package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
- package/lib/server/dispatchers/pageDispatcher.js +4 -0
- package/lib/server/dom.js +12 -3
- package/lib/server/electron/electron.js +5 -2
- package/lib/server/firefox/ffBrowser.js +10 -20
- package/lib/server/firefox/ffConnection.js +0 -5
- package/lib/server/firefox/ffNetworkManager.js +2 -2
- package/lib/server/firefox/ffPage.js +15 -18
- package/lib/server/firefox/firefox.js +6 -8
- package/lib/server/frameSelectors.js +16 -4
- package/lib/server/frames.js +251 -86
- package/lib/server/instrumentation.js +3 -0
- package/lib/server/javascript.js +8 -4
- package/lib/server/launchApp.js +2 -1
- package/lib/server/network.js +50 -12
- package/lib/server/page.js +61 -91
- package/lib/server/progress.js +26 -6
- package/lib/server/recorder/recorderApp.js +79 -100
- package/lib/server/registry/browserFetcher.js +6 -4
- package/lib/server/registry/index.js +172 -149
- package/lib/server/registry/oopDownloadBrowserMain.js +3 -0
- package/lib/server/screencast.js +190 -0
- package/lib/server/screenshotter.js +6 -0
- package/lib/server/trace/recorder/snapshotter.js +17 -8
- package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
- package/lib/server/trace/recorder/tracing.js +29 -21
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +21 -17
- package/lib/server/utils/expectUtils.js +87 -2
- package/lib/server/utils/hostPlatform.js +15 -0
- package/lib/server/utils/httpServer.js +5 -20
- package/lib/server/utils/network.js +37 -28
- package/lib/server/utils/nodePlatform.js +6 -0
- package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +22 -13
- package/lib/server/webkit/webkit.js +4 -6
- package/lib/server/webkit/wkBrowser.js +2 -6
- package/lib/server/webkit/wkConnection.js +1 -6
- package/lib/server/webkit/wkInterceptableRequest.js +29 -1
- package/lib/server/webkit/wkPage.js +75 -46
- package/lib/utils/isomorphic/ariaSnapshot.js +60 -2
- package/lib/utils/isomorphic/lruCache.js +51 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +9 -1
- package/lib/utils/isomorphic/stringUtils.js +49 -0
- package/lib/utils/isomorphic/trace/entries.js +16 -0
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
- package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
- package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
- package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
- package/lib/utils/isomorphic/trace/traceModel.js +365 -0
- package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
- package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
- package/lib/utils/isomorphic/yaml.js +84 -0
- package/lib/utils.js +2 -0
- package/lib/utilsBundle.js +2 -5
- package/lib/utilsBundleImpl/index.js +165 -165
- package/lib/vite/htmlReport/index.html +21 -21
- package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
- package/lib/vite/{traceViewer/codeMirrorModule.C3UTv-Ge.css → recorder/assets/codeMirrorModule-DYBRYzYX.css} +1 -1
- package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
- package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
- package/lib/vite/{recorder/assets/codeMirrorModule-C3UTv-Ge.css → traceViewer/codeMirrorModule.DYBRYzYX.css} +1 -1
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
- package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
- package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
- package/lib/vite/traceViewer/index.html +4 -4
- package/lib/vite/traceViewer/sw.bundle.js +5 -3
- package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/package.json +2 -1
- package/types/protocol.d.ts +738 -159
- package/types/types.d.ts +25 -38
- package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
- package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
- package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +0 -25
- package/lib/vite/recorder/assets/index-CpZVd2nA.js +0 -193
- package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +0 -25
- package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +0 -266
- package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +0 -1
- package/lib/vite/traceViewer/index.C4Y3Aw8n.css +0 -1
- package/lib/vite/traceViewer/index.C8xAeo93.js +0 -2
- package/lib/vite/traceViewer/uiMode.BltraIJB.js +0 -5
|
@@ -130,10 +130,13 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
130
130
|
const page2 = this._findPageForFrame(parentFrameId);
|
|
131
131
|
if (page2) {
|
|
132
132
|
page2._session.addFrameBrowsingContext(event.context);
|
|
133
|
-
page2._page.frameManager.frameAttached(event.context, parentFrameId);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
const frame = page2._page.frameManager.frameAttached(event.context, parentFrameId);
|
|
134
|
+
frame._url = event.url;
|
|
135
|
+
page2._getFrameNode(frame).then((node) => {
|
|
136
|
+
const attributes = node?.value?.attributes;
|
|
137
|
+
frame._name = attributes?.name ?? attributes?.id ?? "";
|
|
138
|
+
});
|
|
139
|
+
return;
|
|
137
140
|
}
|
|
138
141
|
return;
|
|
139
142
|
}
|
|
@@ -142,6 +145,7 @@ class BidiBrowser extends import_browser.Browser {
|
|
|
142
145
|
context = this._defaultContext;
|
|
143
146
|
if (!context)
|
|
144
147
|
return;
|
|
148
|
+
context.doGrantGlobalPermissionsForURL(event.url);
|
|
145
149
|
const session = this._connection.createMainFrameBrowsingContextSession(event.context);
|
|
146
150
|
const opener = event.originalOpener && this._findPageForFrame(event.originalOpener);
|
|
147
151
|
const page = new import_bidiPage.BidiPage(context, session, opener || null);
|
|
@@ -217,6 +221,8 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
|
217
221
|
}
|
|
218
222
|
if (this._options.extraHTTPHeaders)
|
|
219
223
|
promises.push(this.doUpdateExtraHTTPHeaders());
|
|
224
|
+
if (this._options.permissions)
|
|
225
|
+
promises.push(this.doGrantPermissions("*", this._options.permissions));
|
|
220
226
|
await Promise.all(promises);
|
|
221
227
|
}
|
|
222
228
|
possiblyUninitializedPages() {
|
|
@@ -275,17 +281,34 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
|
275
281
|
);
|
|
276
282
|
}
|
|
277
283
|
async doGrantPermissions(origin, permissions) {
|
|
284
|
+
if (origin === "null")
|
|
285
|
+
return;
|
|
278
286
|
const currentPermissions = this._originToPermissions.get(origin) || [];
|
|
279
287
|
const toGrant = permissions.filter((permission) => !currentPermissions.includes(permission));
|
|
280
288
|
this._originToPermissions.set(origin, [...currentPermissions, ...toGrant]);
|
|
281
|
-
|
|
289
|
+
if (origin === "*") {
|
|
290
|
+
await Promise.all(this._bidiPages().flatMap(
|
|
291
|
+
(page) => page._page.frames().map(
|
|
292
|
+
(frame) => this.doGrantPermissions(new URL(frame._url).origin, permissions)
|
|
293
|
+
)
|
|
294
|
+
));
|
|
295
|
+
} else {
|
|
296
|
+
await Promise.all(toGrant.map((permission) => this._setPermission(origin, permission, bidi.Permissions.PermissionState.Granted)));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async doGrantGlobalPermissionsForURL(url) {
|
|
300
|
+
const permissions = this._originToPermissions.get("*");
|
|
301
|
+
if (!permissions)
|
|
302
|
+
return;
|
|
303
|
+
await this.doGrantPermissions(new URL(url).origin, permissions);
|
|
282
304
|
}
|
|
283
305
|
async doClearPermissions() {
|
|
284
306
|
const currentPermissions = [...this._originToPermissions.entries()];
|
|
285
307
|
this._originToPermissions = /* @__PURE__ */ new Map();
|
|
286
|
-
await Promise.all(currentPermissions.
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
await Promise.all(currentPermissions.flatMap(([origin, permissions]) => {
|
|
309
|
+
if (origin !== "*")
|
|
310
|
+
return permissions.map((p) => this._setPermission(origin, p, bidi.Permissions.PermissionState.Prompt));
|
|
311
|
+
}));
|
|
289
312
|
}
|
|
290
313
|
async _setPermission(origin, permission, state) {
|
|
291
314
|
await this._browser._browserSession.send("permissions.setPermission", {
|
|
@@ -349,21 +372,42 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
|
|
|
349
372
|
await Promise.all(ids.map((script) => this._browser._browserSession.send("script.removePreloadScript", { script })));
|
|
350
373
|
}
|
|
351
374
|
async doUpdateRequestInterception() {
|
|
375
|
+
if (this.requestInterceptors.length > 0 && !this._interceptId) {
|
|
376
|
+
const { intercept } = await this._browser._browserSession.send("network.addIntercept", {
|
|
377
|
+
phases: [bidi.Network.InterceptPhase.BeforeRequestSent],
|
|
378
|
+
urlPatterns: [{ type: "pattern" }]
|
|
379
|
+
});
|
|
380
|
+
this._interceptId = intercept;
|
|
381
|
+
}
|
|
382
|
+
if (this.requestInterceptors.length === 0 && this._interceptId) {
|
|
383
|
+
const intercept = this._interceptId;
|
|
384
|
+
this._interceptId = void 0;
|
|
385
|
+
await this._browser._browserSession.send("network.removeIntercept", { intercept });
|
|
386
|
+
}
|
|
352
387
|
}
|
|
353
388
|
async doUpdateDefaultViewport() {
|
|
354
|
-
if (!this._options.viewport)
|
|
389
|
+
if (!this._options.viewport && !this._options.screen)
|
|
355
390
|
return;
|
|
391
|
+
const screenSize = this._options.screen || this._options.viewport;
|
|
392
|
+
const viewportSize = this._options.viewport || this._options.screen;
|
|
356
393
|
await Promise.all([
|
|
357
394
|
this._browser._browserSession.send("browsingContext.setViewport", {
|
|
358
395
|
viewport: {
|
|
359
|
-
width:
|
|
360
|
-
height:
|
|
396
|
+
width: viewportSize.width,
|
|
397
|
+
height: viewportSize.height
|
|
361
398
|
},
|
|
362
399
|
devicePixelRatio: this._options.deviceScaleFactor || 1,
|
|
363
400
|
userContexts: [this._userContextId()]
|
|
364
401
|
}),
|
|
365
402
|
this._browser._browserSession.send("emulation.setScreenOrientationOverride", {
|
|
366
|
-
screenOrientation: getScreenOrientation(!!this._options.isMobile,
|
|
403
|
+
screenOrientation: getScreenOrientation(!!this._options.isMobile, screenSize),
|
|
404
|
+
userContexts: [this._userContextId()]
|
|
405
|
+
}),
|
|
406
|
+
this._browser._browserSession.send("emulation.setScreenSettingsOverride", {
|
|
407
|
+
screenArea: {
|
|
408
|
+
width: screenSize.width,
|
|
409
|
+
height: screenSize.height
|
|
410
|
+
},
|
|
367
411
|
userContexts: [this._userContextId()]
|
|
368
412
|
})
|
|
369
413
|
]);
|
|
@@ -38,6 +38,7 @@ var import_bidiBrowser = require("./bidiBrowser");
|
|
|
38
38
|
var import_bidiConnection = require("./bidiConnection");
|
|
39
39
|
var import_chromiumSwitches = require("../chromium/chromiumSwitches");
|
|
40
40
|
var import_chromium = require("../chromium/chromium");
|
|
41
|
+
var import_hostPlatform = require("../utils/hostPlatform");
|
|
41
42
|
class BidiChromium extends import_browserType.BrowserType {
|
|
42
43
|
constructor(parent) {
|
|
43
44
|
super(parent, "chromium");
|
|
@@ -56,14 +57,12 @@ class BidiChromium extends import_browserType.BrowserType {
|
|
|
56
57
|
throw e;
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
doRewriteStartupLog(
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return error;
|
|
66
|
-
error.logs = [
|
|
60
|
+
doRewriteStartupLog(logs) {
|
|
61
|
+
if (logs.includes("Missing X server"))
|
|
62
|
+
logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
|
63
|
+
if (!logs.includes("crbug.com/357670") && !logs.includes("No usable sandbox!") && !logs.includes("crbug.com/638180"))
|
|
64
|
+
return logs;
|
|
65
|
+
return [
|
|
67
66
|
`Chromium sandboxing failed!`,
|
|
68
67
|
`================================`,
|
|
69
68
|
`To avoid the sandboxing issue, do either of the following:`,
|
|
@@ -72,7 +71,6 @@ class BidiChromium extends import_browserType.BrowserType {
|
|
|
72
71
|
`================================`,
|
|
73
72
|
``
|
|
74
73
|
].join("\n");
|
|
75
|
-
return error;
|
|
76
74
|
}
|
|
77
75
|
amendEnvironment(env) {
|
|
78
76
|
return env;
|
|
@@ -109,11 +107,9 @@ class BidiChromium extends import_browserType.BrowserType {
|
|
|
109
107
|
if (args.find((arg) => !arg.startsWith("-")))
|
|
110
108
|
throw new Error("Arguments can not specify page to be opened");
|
|
111
109
|
const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode)];
|
|
112
|
-
if (import_os.default.platform()
|
|
110
|
+
if (import_os.default.platform() !== "darwin" || !(0, import_hostPlatform.hasGpuMac)()) {
|
|
113
111
|
chromeArguments.push("--enable-unsafe-swiftshader");
|
|
114
112
|
}
|
|
115
|
-
if (options.devtools)
|
|
116
|
-
chromeArguments.push("--auto-open-devtools-for-tabs");
|
|
117
113
|
if (options.headless) {
|
|
118
114
|
chromeArguments.push("--headless");
|
|
119
115
|
chromeArguments.push(
|
|
@@ -173,6 +173,7 @@ class BidiSession extends import_events.EventEmitter {
|
|
|
173
173
|
this._browsingContexts.clear();
|
|
174
174
|
for (const callback of this._callbacks.values()) {
|
|
175
175
|
callback.error.type = this._crashed ? "crashed" : "closed";
|
|
176
|
+
callback.error.setMessage(`Internal server error, session ${callback.error.type}.`);
|
|
176
177
|
callback.error.logs = this.connection._browserDisconnectedLogs;
|
|
177
178
|
callback.reject(callback.error);
|
|
178
179
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var bidiDeserializer_exports = {};
|
|
20
|
+
__export(bidiDeserializer_exports, {
|
|
21
|
+
deserializeBidiValue: () => deserializeBidiValue
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(bidiDeserializer_exports);
|
|
24
|
+
var import_javascript = require("../javascript");
|
|
25
|
+
function deserializeBidiValue(result, internalIdMap = /* @__PURE__ */ new Map()) {
|
|
26
|
+
switch (result.type) {
|
|
27
|
+
case "undefined":
|
|
28
|
+
return void 0;
|
|
29
|
+
case "null":
|
|
30
|
+
return null;
|
|
31
|
+
case "number":
|
|
32
|
+
return typeof result.value === "number" ? result.value : (0, import_javascript.parseUnserializableValue)(result.value);
|
|
33
|
+
case "boolean":
|
|
34
|
+
return Boolean(result.value);
|
|
35
|
+
case "string":
|
|
36
|
+
return result.value;
|
|
37
|
+
case "bigint":
|
|
38
|
+
return BigInt(result.value);
|
|
39
|
+
case "array":
|
|
40
|
+
return deserializeBidiList(result, internalIdMap);
|
|
41
|
+
case "arraybuffer":
|
|
42
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
43
|
+
case "date":
|
|
44
|
+
return getValue(result, internalIdMap, () => new Date(result.value));
|
|
45
|
+
case "error":
|
|
46
|
+
return getValue(result, internalIdMap, () => {
|
|
47
|
+
const error = new Error();
|
|
48
|
+
error.stack = "";
|
|
49
|
+
return error;
|
|
50
|
+
});
|
|
51
|
+
case "function":
|
|
52
|
+
return void 0;
|
|
53
|
+
case "generator":
|
|
54
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
55
|
+
case "htmlcollection":
|
|
56
|
+
return { ...deserializeBidiList(result, internalIdMap) };
|
|
57
|
+
case "map":
|
|
58
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
59
|
+
case "node":
|
|
60
|
+
return "ref: <Node>";
|
|
61
|
+
case "nodelist":
|
|
62
|
+
return { ...deserializeBidiList(result, internalIdMap) };
|
|
63
|
+
case "object":
|
|
64
|
+
return deserializeBidiMapping(result, internalIdMap);
|
|
65
|
+
case "promise":
|
|
66
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
67
|
+
case "proxy":
|
|
68
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
69
|
+
case "regexp":
|
|
70
|
+
return getValue(result, internalIdMap, () => new RegExp(result.value.pattern, result.value.flags));
|
|
71
|
+
case "set":
|
|
72
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
73
|
+
case "symbol":
|
|
74
|
+
return void 0;
|
|
75
|
+
case "typedarray":
|
|
76
|
+
return void 0;
|
|
77
|
+
case "weakmap":
|
|
78
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
79
|
+
case "weakset":
|
|
80
|
+
return getValue(result, internalIdMap, () => ({}));
|
|
81
|
+
case "window":
|
|
82
|
+
return "ref: <Window>";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function getValue(bidiValue, internalIdMap, defaultValue) {
|
|
86
|
+
if ("internalId" in bidiValue && bidiValue.internalId) {
|
|
87
|
+
if (internalIdMap.has(bidiValue.internalId)) {
|
|
88
|
+
return internalIdMap.get(bidiValue.internalId);
|
|
89
|
+
} else {
|
|
90
|
+
const value = defaultValue();
|
|
91
|
+
internalIdMap.set(bidiValue.internalId, value);
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
return defaultValue();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function deserializeBidiList(bidiValue, internalIdMap) {
|
|
99
|
+
const result = getValue(bidiValue, internalIdMap, () => []);
|
|
100
|
+
for (const val of bidiValue.value || [])
|
|
101
|
+
result.push(deserializeBidiValue(val, internalIdMap));
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
function deserializeBidiMapping(bidiValue, internalIdMap) {
|
|
105
|
+
const result = getValue(bidiValue, internalIdMap, () => ({}));
|
|
106
|
+
for (const [serializedKey, serializedValue] of bidiValue.value || []) {
|
|
107
|
+
const key = typeof serializedKey === "string" ? serializedKey : deserializeBidiValue(serializedKey, internalIdMap);
|
|
108
|
+
const value = deserializeBidiValue(serializedValue, internalIdMap);
|
|
109
|
+
result[key] = value;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
114
|
+
0 && (module.exports = {
|
|
115
|
+
deserializeBidiValue
|
|
116
|
+
});
|
|
@@ -36,9 +36,9 @@ var import_utils = require("../../utils");
|
|
|
36
36
|
var import_utilityScriptSerializers = require("../../utils/isomorphic/utilityScriptSerializers");
|
|
37
37
|
var js = __toESM(require("../javascript"));
|
|
38
38
|
var dom = __toESM(require("../dom"));
|
|
39
|
-
var import_bidiDeserializer = require("./third_party/bidiDeserializer");
|
|
40
39
|
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
|
41
40
|
var import_bidiSerializer = require("./third_party/bidiSerializer");
|
|
41
|
+
var import_bidiDeserializer = require("./bidiDeserializer");
|
|
42
42
|
class BidiExecutionContext {
|
|
43
43
|
constructor(session, realmInfo) {
|
|
44
44
|
this._session = session;
|
|
@@ -65,7 +65,7 @@ class BidiExecutionContext {
|
|
|
65
65
|
userActivation: true
|
|
66
66
|
});
|
|
67
67
|
if (response.type === "success")
|
|
68
|
-
return import_bidiDeserializer.
|
|
68
|
+
return (0, import_bidiDeserializer.deserializeBidiValue)(response.result);
|
|
69
69
|
if (response.type === "exception")
|
|
70
70
|
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
|
71
71
|
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
|
@@ -108,7 +108,7 @@ class BidiExecutionContext {
|
|
|
108
108
|
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
|
109
109
|
if (response.type === "success") {
|
|
110
110
|
if (returnByValue)
|
|
111
|
-
return (0, import_utilityScriptSerializers.parseEvaluationResultValue)(import_bidiDeserializer.
|
|
111
|
+
return (0, import_utilityScriptSerializers.parseEvaluationResultValue)((0, import_bidiDeserializer.deserializeBidiValue)(response.result));
|
|
112
112
|
return createHandle(utilityScript._context, response.result);
|
|
113
113
|
}
|
|
114
114
|
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
|
@@ -123,7 +123,10 @@ class BidiExecutionContext {
|
|
|
123
123
|
}
|
|
124
124
|
return names2;
|
|
125
125
|
});
|
|
126
|
-
const values = await Promise.all(names.map((name) =>
|
|
126
|
+
const values = await Promise.all(names.map(async (name) => {
|
|
127
|
+
const value = await this._rawCallFunction("(object, name) => object[name]", [{ handle: handle._objectId }, { type: "string", value: name }], true, false);
|
|
128
|
+
return createHandle(handle._context, value);
|
|
129
|
+
}));
|
|
127
130
|
const map = /* @__PURE__ */ new Map();
|
|
128
131
|
for (let i = 0; i < names.length; i++)
|
|
129
132
|
map.set(names[i], values[i]);
|
|
@@ -152,7 +155,7 @@ class BidiExecutionContext {
|
|
|
152
155
|
return createHandle(context, result);
|
|
153
156
|
}
|
|
154
157
|
async contentFrameIdForFrame(handle) {
|
|
155
|
-
const contentWindow = await this._rawCallFunction("e => e.contentWindow", { handle: handle._objectId });
|
|
158
|
+
const contentWindow = await this._rawCallFunction("e => e.contentWindow", [{ handle: handle._objectId }]);
|
|
156
159
|
if (contentWindow?.type === "window")
|
|
157
160
|
return contentWindow.value.context;
|
|
158
161
|
return null;
|
|
@@ -166,17 +169,17 @@ class BidiExecutionContext {
|
|
|
166
169
|
return null;
|
|
167
170
|
}
|
|
168
171
|
async _remoteValueForReference(reference, createHandle2) {
|
|
169
|
-
return await this._rawCallFunction("e => e", reference, createHandle2);
|
|
172
|
+
return await this._rawCallFunction("e => e", [reference], createHandle2);
|
|
170
173
|
}
|
|
171
|
-
async _rawCallFunction(functionDeclaration,
|
|
174
|
+
async _rawCallFunction(functionDeclaration, args, createHandle2, awaitPromise = true) {
|
|
172
175
|
const response = await this._session.send("script.callFunction", {
|
|
173
176
|
functionDeclaration,
|
|
174
177
|
target: this._target,
|
|
175
|
-
arguments:
|
|
178
|
+
arguments: args,
|
|
176
179
|
// "Root" is necessary for the handle to be returned.
|
|
177
180
|
resultOwnership: createHandle2 ? bidi.Script.ResultOwnership.Root : bidi.Script.ResultOwnership.None,
|
|
178
181
|
serializationOptions: { maxObjectDepth: 0, maxDomDepth: 0 },
|
|
179
|
-
awaitPromise
|
|
182
|
+
awaitPromise,
|
|
180
183
|
userActivation: true
|
|
181
184
|
});
|
|
182
185
|
if (response.type === "exception")
|
|
@@ -186,25 +189,65 @@ class BidiExecutionContext {
|
|
|
186
189
|
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
|
187
190
|
}
|
|
188
191
|
}
|
|
189
|
-
function renderPreview(remoteObject) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
192
|
+
function renderPreview(remoteObject, nested = false) {
|
|
193
|
+
switch (remoteObject.type) {
|
|
194
|
+
case "undefined":
|
|
195
|
+
case "null":
|
|
196
|
+
return remoteObject.type;
|
|
197
|
+
case "number":
|
|
198
|
+
case "boolean":
|
|
199
|
+
case "string":
|
|
200
|
+
return String(remoteObject.value);
|
|
201
|
+
case "bigint":
|
|
202
|
+
return `${remoteObject.value}n`;
|
|
203
|
+
case "date":
|
|
204
|
+
return String(new Date(remoteObject.value));
|
|
205
|
+
case "regexp":
|
|
206
|
+
return String(new RegExp(remoteObject.value.pattern, remoteObject.value.flags));
|
|
207
|
+
case "node":
|
|
208
|
+
return remoteObject.value?.localName || "Node";
|
|
209
|
+
case "object":
|
|
210
|
+
if (nested)
|
|
211
|
+
return "Object";
|
|
212
|
+
const tokens = [];
|
|
213
|
+
for (const [name, value] of remoteObject.value || []) {
|
|
214
|
+
if (typeof name === "string")
|
|
215
|
+
tokens.push(`${name}: ${renderPreview(value, true)}`);
|
|
216
|
+
}
|
|
217
|
+
return `{${tokens.join(", ")}}`;
|
|
218
|
+
case "array":
|
|
219
|
+
case "htmlcollection":
|
|
220
|
+
case "nodelist":
|
|
221
|
+
if (nested || !remoteObject.value)
|
|
222
|
+
return remoteObject.value ? `Array(${remoteObject.value.length})` : "Array";
|
|
223
|
+
return `[${remoteObject.value.map((v) => renderPreview(v, true)).join(", ")}]`;
|
|
224
|
+
case "map":
|
|
225
|
+
return remoteObject.value ? `Map(${remoteObject.value.length})` : "Map";
|
|
226
|
+
case "set":
|
|
227
|
+
return remoteObject.value ? `Set(${remoteObject.value.length})` : "Set";
|
|
228
|
+
case "arraybuffer":
|
|
229
|
+
return "ArrayBuffer";
|
|
230
|
+
case "error":
|
|
231
|
+
return "Error";
|
|
232
|
+
case "function":
|
|
233
|
+
return "Function";
|
|
234
|
+
case "generator":
|
|
235
|
+
return "Generator";
|
|
236
|
+
case "promise":
|
|
237
|
+
return "Promise";
|
|
238
|
+
case "proxy":
|
|
239
|
+
return "Proxy";
|
|
240
|
+
case "symbol":
|
|
241
|
+
return "Symbol()";
|
|
242
|
+
case "typedarray":
|
|
243
|
+
return "TypedArray";
|
|
244
|
+
case "weakmap":
|
|
245
|
+
return "WeakMap";
|
|
246
|
+
case "weakset":
|
|
247
|
+
return "WeakSet";
|
|
248
|
+
case "window":
|
|
249
|
+
return "Window";
|
|
250
|
+
}
|
|
208
251
|
}
|
|
209
252
|
function createHandle(context, remoteObject) {
|
|
210
253
|
if (remoteObject.type === "node") {
|
|
@@ -212,7 +255,10 @@ function createHandle(context, remoteObject) {
|
|
|
212
255
|
return new dom.ElementHandle(context, remoteObject.handle);
|
|
213
256
|
}
|
|
214
257
|
const objectId = "handle" in remoteObject ? remoteObject.handle : void 0;
|
|
215
|
-
|
|
258
|
+
const preview = renderPreview(remoteObject);
|
|
259
|
+
const handle = new js.JSHandle(context, remoteObject.type, preview, objectId, (0, import_bidiDeserializer.deserializeBidiValue)(remoteObject));
|
|
260
|
+
handle._setPreview(preview);
|
|
261
|
+
return handle;
|
|
216
262
|
}
|
|
217
263
|
// Annotate the CommonJS export names for ESM import in node:
|
|
218
264
|
0 && (module.exports = {
|
|
@@ -49,15 +49,13 @@ class BidiFirefox extends import_browserType.BrowserType {
|
|
|
49
49
|
async connectToTransport(transport, options) {
|
|
50
50
|
return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, transport, options);
|
|
51
51
|
}
|
|
52
|
-
doRewriteStartupLog(
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
if (error.logs.includes(`as root in a regular user's session is not supported.`))
|
|
56
|
-
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
|
52
|
+
doRewriteStartupLog(logs) {
|
|
53
|
+
if (logs.includes(`as root in a regular user's session is not supported.`))
|
|
54
|
+
logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
|
57
55
|
Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? " in your GitHub Actions workflow file" : ""} when running Playwright.`, 1);
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
return
|
|
56
|
+
if (logs.includes("no DISPLAY environment variable specified"))
|
|
57
|
+
logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
|
58
|
+
return logs;
|
|
61
59
|
}
|
|
62
60
|
amendEnvironment(env) {
|
|
63
61
|
if (!import_path.default.isAbsolute(import_os.default.homedir()))
|
|
@@ -32,6 +32,7 @@ __export(bidiPage_exports, {
|
|
|
32
32
|
kPlaywrightBindingChannel: () => kPlaywrightBindingChannel
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(bidiPage_exports);
|
|
35
|
+
var import_debugLogger = require("../utils/debugLogger");
|
|
35
36
|
var import_eventsHelper = require("../utils/eventsHelper");
|
|
36
37
|
var dialog = __toESM(require("../dialog"));
|
|
37
38
|
var dom = __toESM(require("../dom"));
|
|
@@ -87,8 +88,7 @@ class BidiPage {
|
|
|
87
88
|
async _initialize() {
|
|
88
89
|
this._onFrameAttached(this._session.sessionId, null);
|
|
89
90
|
await Promise.all([
|
|
90
|
-
this.updateHttpCredentials()
|
|
91
|
-
this.updateRequestInterception()
|
|
91
|
+
this.updateHttpCredentials()
|
|
92
92
|
// If the page is created by the Playwright client's call, some initialization
|
|
93
93
|
// may be pending. Wait for it to complete before reporting the page as new.
|
|
94
94
|
]);
|
|
@@ -179,10 +179,12 @@ class BidiPage {
|
|
|
179
179
|
}
|
|
180
180
|
_onNavigationCommitted(params) {
|
|
181
181
|
const frameId = params.context;
|
|
182
|
+
const frame = this._page.frameManager.frame(frameId);
|
|
183
|
+
this._browserContext.doGrantGlobalPermissionsForURL(params.url).catch((error) => import_debugLogger.debugLogger.log("error", error));
|
|
182
184
|
this._page.frameManager.frameCommittedNewDocumentNavigation(
|
|
183
185
|
frameId,
|
|
184
186
|
params.url,
|
|
185
|
-
|
|
187
|
+
frame._name,
|
|
186
188
|
params.navigation,
|
|
187
189
|
/* initial */
|
|
188
190
|
false
|
|
@@ -263,7 +265,7 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
263
265
|
return;
|
|
264
266
|
const callFrame = params.stackTrace?.callFrames[0];
|
|
265
267
|
const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
|
|
266
|
-
this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location
|
|
268
|
+
this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location);
|
|
267
269
|
}
|
|
268
270
|
async _onFileDialogOpened(params) {
|
|
269
271
|
if (!params.element)
|
|
@@ -272,8 +274,11 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
272
274
|
if (!frame)
|
|
273
275
|
return;
|
|
274
276
|
const executionContext = await frame._mainContext();
|
|
275
|
-
|
|
276
|
-
|
|
277
|
+
try {
|
|
278
|
+
const handle = await toBidiExecutionContext(executionContext).remoteObjectForNodeId(executionContext, { sharedId: params.element.sharedId });
|
|
279
|
+
await this._page._onFileChooserOpened(handle);
|
|
280
|
+
} catch {
|
|
281
|
+
}
|
|
277
282
|
}
|
|
278
283
|
async navigateFrame(frame, url, referrer) {
|
|
279
284
|
const { navigation } = await this._session.send("browsingContext.navigate", {
|
|
@@ -306,6 +311,7 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
306
311
|
const emulatedSize = this._page.emulatedSize();
|
|
307
312
|
if (!emulatedSize)
|
|
308
313
|
return;
|
|
314
|
+
const screenSize = emulatedSize.screen;
|
|
309
315
|
const viewportSize = emulatedSize.viewport;
|
|
310
316
|
await Promise.all([
|
|
311
317
|
this._session.send("browsingContext.setViewport", {
|
|
@@ -318,12 +324,19 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
318
324
|
}),
|
|
319
325
|
this._session.send("emulation.setScreenOrientationOverride", {
|
|
320
326
|
contexts: [this._session.sessionId],
|
|
321
|
-
screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile,
|
|
327
|
+
screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile, screenSize)
|
|
328
|
+
}),
|
|
329
|
+
this._session.send("emulation.setScreenSettingsOverride", {
|
|
330
|
+
contexts: [this._session.sessionId],
|
|
331
|
+
screenArea: {
|
|
332
|
+
width: screenSize.width,
|
|
333
|
+
height: screenSize.height
|
|
334
|
+
}
|
|
322
335
|
})
|
|
323
336
|
]);
|
|
324
337
|
}
|
|
325
338
|
async updateRequestInterception() {
|
|
326
|
-
await this._networkManager.setRequestInterception(this._page.
|
|
339
|
+
await this._networkManager.setRequestInterception(this._page.requestInterceptors.length > 0);
|
|
327
340
|
}
|
|
328
341
|
async updateOffline() {
|
|
329
342
|
}
|
|
@@ -482,7 +495,9 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
482
495
|
throw e;
|
|
483
496
|
});
|
|
484
497
|
}
|
|
485
|
-
async
|
|
498
|
+
async startScreencast(options) {
|
|
499
|
+
}
|
|
500
|
+
async stopScreencast() {
|
|
486
501
|
}
|
|
487
502
|
rafCountForStablePosition() {
|
|
488
503
|
return 1;
|
|
@@ -537,26 +552,22 @@ ${params.stackTrace?.callFrames.map((f) => {
|
|
|
537
552
|
const parent = frame.parentFrame();
|
|
538
553
|
if (!parent)
|
|
539
554
|
throw new Error("Frame has been detached.");
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
return [...document.querySelectorAll("iframe,frame")];
|
|
543
|
-
});
|
|
544
|
-
const length = await list.evaluate((list2) => list2.length);
|
|
545
|
-
let foundElement = null;
|
|
546
|
-
for (let i = 0; i < length; i++) {
|
|
547
|
-
const element = await list.evaluateHandle((list2, i2) => list2[i2], i);
|
|
548
|
-
const candidate = await element.contentFrame();
|
|
549
|
-
if (frame === candidate) {
|
|
550
|
-
foundElement = element;
|
|
551
|
-
break;
|
|
552
|
-
} else {
|
|
553
|
-
element.dispose();
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
list.dispose();
|
|
557
|
-
if (!foundElement)
|
|
555
|
+
const node = await this._getFrameNode(frame);
|
|
556
|
+
if (!node?.sharedId)
|
|
558
557
|
throw new Error("Frame has been detached.");
|
|
559
|
-
|
|
558
|
+
const parentFrameExecutionContext = await parent._mainContext();
|
|
559
|
+
return await toBidiExecutionContext(parentFrameExecutionContext).remoteObjectForNodeId(parentFrameExecutionContext, { sharedId: node.sharedId });
|
|
560
|
+
}
|
|
561
|
+
async _getFrameNode(frame) {
|
|
562
|
+
const parent = frame.parentFrame();
|
|
563
|
+
if (!parent)
|
|
564
|
+
return void 0;
|
|
565
|
+
const result = await this._session.send("browsingContext.locateNodes", {
|
|
566
|
+
context: parent._id,
|
|
567
|
+
locator: { type: "context", value: { context: frame._id } }
|
|
568
|
+
});
|
|
569
|
+
const node = result.nodes[0];
|
|
570
|
+
return node;
|
|
560
571
|
}
|
|
561
572
|
shouldToggleStyleSheetToSyncAnimations() {
|
|
562
573
|
return true;
|