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
|
@@ -33,6 +33,9 @@ class SdkObject extends import_events.EventEmitter {
|
|
|
33
33
|
this.attribution = { ...parent.attribution };
|
|
34
34
|
this.instrumentation = parent.instrumentation;
|
|
35
35
|
}
|
|
36
|
+
closeReason() {
|
|
37
|
+
return this.attribution.page?._closeReason || this.attribution.context?._closeReason || this.attribution.browser?._closeReason;
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
function createRootSdkObject() {
|
|
38
41
|
const fakeParent = { attribution: {}, instrumentation: createInstrumentation() };
|
package/lib/server/javascript.js
CHANGED
|
@@ -118,10 +118,12 @@ class JSHandle extends import_instrumentation.SdkObject {
|
|
|
118
118
|
if (context.constructor.name === "FrameExecutionContext") {
|
|
119
119
|
const frame = context.frame;
|
|
120
120
|
if (frame) {
|
|
121
|
-
if (isolatedContext) context = await frame._utilityContext();
|
|
122
|
-
else if (
|
|
121
|
+
if (isolatedContext === true) context = await frame._utilityContext();
|
|
122
|
+
else if (isolatedContext === false) context = await frame._mainContext();
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
+
if (context !== this._context && context.adoptIfNeeded(this) === null)
|
|
126
|
+
context = this._context;
|
|
125
127
|
const value = await evaluateExpression(context, expression, { ...options, returnByValue: true }, this, arg);
|
|
126
128
|
await context.doSlowMo();
|
|
127
129
|
return value;
|
|
@@ -131,10 +133,12 @@ class JSHandle extends import_instrumentation.SdkObject {
|
|
|
131
133
|
if (context.constructor.name === "FrameExecutionContext") {
|
|
132
134
|
const frame = this._context.frame;
|
|
133
135
|
if (frame) {
|
|
134
|
-
if (isolatedContext) context = await frame._utilityContext();
|
|
135
|
-
else if (
|
|
136
|
+
if (isolatedContext === true) context = await frame._utilityContext();
|
|
137
|
+
else if (isolatedContext === false) context = await frame._mainContext();
|
|
136
138
|
}
|
|
137
139
|
}
|
|
140
|
+
if (context !== this._context && context.adoptIfNeeded(this) === null)
|
|
141
|
+
context = this._context;
|
|
138
142
|
const value = await evaluateExpression(context, expression, { ...options, returnByValue: false }, this, arg);
|
|
139
143
|
await context.doSlowMo();
|
|
140
144
|
return value;
|
package/lib/server/launchApp.js
CHANGED
|
@@ -114,7 +114,8 @@ async function syncLocalStorageWithSettings(page, appName) {
|
|
|
114
114
|
return;
|
|
115
115
|
Object.entries(settings2).map(([k, v]) => localStorage[k] = v);
|
|
116
116
|
window.saveSettings = () => {
|
|
117
|
-
window._saveSerializedSettings
|
|
117
|
+
if (typeof window._saveSerializedSettings === "function")
|
|
118
|
+
window._saveSerializedSettings(JSON.stringify({ ...localStorage }));
|
|
118
119
|
};
|
|
119
120
|
})})(${settings});
|
|
120
121
|
`
|
package/lib/server/network.js
CHANGED
|
@@ -22,6 +22,7 @@ __export(network_exports, {
|
|
|
22
22
|
Response: () => Response,
|
|
23
23
|
Route: () => Route,
|
|
24
24
|
WebSocket: () => WebSocket,
|
|
25
|
+
applyHeadersOverrides: () => applyHeadersOverrides,
|
|
25
26
|
filterCookies: () => filterCookies,
|
|
26
27
|
isLocalHostname: () => isLocalHostname,
|
|
27
28
|
kMaxCookieExpiresDateInSeconds: () => kMaxCookieExpiresDateInSeconds,
|
|
@@ -61,6 +62,48 @@ function filterCookies(cookies, urls) {
|
|
|
61
62
|
function isLocalHostname(hostname) {
|
|
62
63
|
return hostname === "localhost" || hostname.endsWith(".localhost");
|
|
63
64
|
}
|
|
65
|
+
const FORBIDDEN_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
66
|
+
"accept-charset",
|
|
67
|
+
"accept-encoding",
|
|
68
|
+
"access-control-request-headers",
|
|
69
|
+
"access-control-request-method",
|
|
70
|
+
"connection",
|
|
71
|
+
"content-length",
|
|
72
|
+
"cookie",
|
|
73
|
+
"date",
|
|
74
|
+
"dnt",
|
|
75
|
+
"expect",
|
|
76
|
+
"host",
|
|
77
|
+
"keep-alive",
|
|
78
|
+
"origin",
|
|
79
|
+
"referer",
|
|
80
|
+
"set-cookie",
|
|
81
|
+
"te",
|
|
82
|
+
"trailer",
|
|
83
|
+
"transfer-encoding",
|
|
84
|
+
"upgrade",
|
|
85
|
+
"via"
|
|
86
|
+
]);
|
|
87
|
+
const FORBIDDEN_METHODS = /* @__PURE__ */ new Set(["CONNECT", "TRACE", "TRACK"]);
|
|
88
|
+
function isForbiddenHeader(name, value) {
|
|
89
|
+
const lowerName = name.toLowerCase();
|
|
90
|
+
if (FORBIDDEN_HEADER_NAMES.has(lowerName))
|
|
91
|
+
return true;
|
|
92
|
+
if (lowerName.startsWith("proxy-"))
|
|
93
|
+
return true;
|
|
94
|
+
if (lowerName.startsWith("sec-"))
|
|
95
|
+
return true;
|
|
96
|
+
if (lowerName === "x-http-method" || lowerName === "x-http-method-override" || lowerName === "x-method-override") {
|
|
97
|
+
if (value && FORBIDDEN_METHODS.has(value.toUpperCase()))
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
function applyHeadersOverrides(original, overrides) {
|
|
103
|
+
const forbiddenHeaders = original.filter((header) => isForbiddenHeader(header.name, header.value));
|
|
104
|
+
const allowedHeaders = overrides.filter((header) => !isForbiddenHeader(header.name, header.value));
|
|
105
|
+
return mergeHeaders([allowedHeaders, forbiddenHeaders]);
|
|
106
|
+
}
|
|
64
107
|
const kMaxCookieExpiresDateInSeconds = 253402300799;
|
|
65
108
|
function rewriteCookies(cookies) {
|
|
66
109
|
return cookies.map((c) => {
|
|
@@ -99,7 +142,6 @@ class Request extends import_instrumentation.SdkObject {
|
|
|
99
142
|
this._response = null;
|
|
100
143
|
this._redirectedTo = null;
|
|
101
144
|
this._failureText = null;
|
|
102
|
-
this._headersMap = /* @__PURE__ */ new Map();
|
|
103
145
|
this._frame = null;
|
|
104
146
|
this._serviceWorker = null;
|
|
105
147
|
this._rawRequestHeadersPromise = new import_manualPromise.ManualPromise();
|
|
@@ -118,7 +160,6 @@ class Request extends import_instrumentation.SdkObject {
|
|
|
118
160
|
this._method = method;
|
|
119
161
|
this._postData = postData;
|
|
120
162
|
this._headers = headers;
|
|
121
|
-
this._updateHeadersMap();
|
|
122
163
|
this._isFavicon = url.endsWith("/favicon.ico") || !!redirectedFrom?._isFavicon;
|
|
123
164
|
}
|
|
124
165
|
static {
|
|
@@ -132,13 +173,8 @@ class Request extends import_instrumentation.SdkObject {
|
|
|
132
173
|
}
|
|
133
174
|
_applyOverrides(overrides) {
|
|
134
175
|
this._overrides = { ...this._overrides, ...overrides };
|
|
135
|
-
this._updateHeadersMap();
|
|
136
176
|
return this._overrides;
|
|
137
177
|
}
|
|
138
|
-
_updateHeadersMap() {
|
|
139
|
-
for (const { name, value } of this.headers())
|
|
140
|
-
this._headersMap.set(name.toLowerCase(), value);
|
|
141
|
-
}
|
|
142
178
|
overrides() {
|
|
143
179
|
return this._overrides;
|
|
144
180
|
}
|
|
@@ -158,7 +194,8 @@ class Request extends import_instrumentation.SdkObject {
|
|
|
158
194
|
return this._overrides?.headers || this._headers;
|
|
159
195
|
}
|
|
160
196
|
headerValue(name) {
|
|
161
|
-
|
|
197
|
+
const lowerCaseName = name.toLowerCase();
|
|
198
|
+
return this.headers().find((h) => h.name.toLowerCase() === lowerCaseName)?.value;
|
|
162
199
|
}
|
|
163
200
|
// "null" means no raw headers available - we'll use provisional headers as raw headers.
|
|
164
201
|
setRawRequestHeaders(headers) {
|
|
@@ -309,10 +346,7 @@ class Route extends import_instrumentation.SdkObject {
|
|
|
309
346
|
throw new Error("New URL must have same protocol as overridden URL");
|
|
310
347
|
}
|
|
311
348
|
if (overrides.headers) {
|
|
312
|
-
overrides.headers = overrides.headers
|
|
313
|
-
const headerName = header.name.toLowerCase();
|
|
314
|
-
return headerName !== "cookie" && headerName !== "host";
|
|
315
|
-
});
|
|
349
|
+
overrides.headers = applyHeadersOverrides(this._request._headers, overrides.headers);
|
|
316
350
|
}
|
|
317
351
|
overrides = this._request._applyOverrides(overrides);
|
|
318
352
|
const nextHandler = this._futureHandlers.shift();
|
|
@@ -436,6 +470,9 @@ class Response extends import_instrumentation.SdkObject {
|
|
|
436
470
|
request() {
|
|
437
471
|
return this._request;
|
|
438
472
|
}
|
|
473
|
+
finished() {
|
|
474
|
+
return this._finishedPromise;
|
|
475
|
+
}
|
|
439
476
|
frame() {
|
|
440
477
|
return this._request.frame();
|
|
441
478
|
}
|
|
@@ -617,6 +654,7 @@ function mergeHeaders(headers) {
|
|
|
617
654
|
Response,
|
|
618
655
|
Route,
|
|
619
656
|
WebSocket,
|
|
657
|
+
applyHeadersOverrides,
|
|
620
658
|
filterCookies,
|
|
621
659
|
isLocalHostname,
|
|
622
660
|
kMaxCookieExpiresDateInSeconds,
|
package/lib/server/page.js
CHANGED
|
@@ -31,7 +31,8 @@ __export(page_exports, {
|
|
|
31
31
|
InitScript: () => InitScript,
|
|
32
32
|
Page: () => Page,
|
|
33
33
|
PageBinding: () => PageBinding,
|
|
34
|
-
Worker: () => Worker
|
|
34
|
+
Worker: () => Worker,
|
|
35
|
+
WorkerEvent: () => WorkerEvent
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(page_exports);
|
|
37
38
|
var import_pageBinding = require("./pageBinding");
|
|
@@ -53,6 +54,22 @@ var import_selectorParser = require("../utils/isomorphic/selectorParser");
|
|
|
53
54
|
var import_manualPromise = require("../utils/isomorphic/manualPromise");
|
|
54
55
|
var import_utilityScriptSerializers = require("../utils/isomorphic/utilityScriptSerializers");
|
|
55
56
|
var import_callLog = require("./callLog");
|
|
57
|
+
var import_screencast = require("./screencast");
|
|
58
|
+
const PageEvent = {
|
|
59
|
+
Close: "close",
|
|
60
|
+
Crash: "crash",
|
|
61
|
+
Download: "download",
|
|
62
|
+
EmulatedSizeChanged: "emulatedsizechanged",
|
|
63
|
+
FileChooser: "filechooser",
|
|
64
|
+
FrameAttached: "frameattached",
|
|
65
|
+
FrameDetached: "framedetached",
|
|
66
|
+
InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument",
|
|
67
|
+
LocatorHandlerTriggered: "locatorhandlertriggered",
|
|
68
|
+
ScreencastFrame: "screencastframe",
|
|
69
|
+
Video: "video",
|
|
70
|
+
WebSocket: "websocket",
|
|
71
|
+
Worker: "worker"
|
|
72
|
+
};
|
|
56
73
|
class Page extends import_instrumentation.SdkObject {
|
|
57
74
|
constructor(delegate, browserContext) {
|
|
58
75
|
super(browserContext, "page");
|
|
@@ -74,9 +91,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
74
91
|
this._lastLocatorHandlerUid = 0;
|
|
75
92
|
this._locatorHandlerRunningCounter = 0;
|
|
76
93
|
this._networkRequests = [];
|
|
77
|
-
// Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
|
|
78
|
-
// When throttling for tracing, 200ms between frames, except for 10 frames around the action.
|
|
79
|
-
this._frameThrottler = new FrameThrottler(10, 35, 200);
|
|
80
94
|
this.attribution.page = this;
|
|
81
95
|
this.delegate = delegate;
|
|
82
96
|
this.browserContext = browserContext;
|
|
@@ -85,27 +99,14 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
85
99
|
this.touchscreen = new input.Touchscreen(delegate.rawTouchscreen, this);
|
|
86
100
|
this.screenshotter = new import_screenshotter.Screenshotter(this);
|
|
87
101
|
this.frameManager = new frames.FrameManager(this);
|
|
102
|
+
this.screencast = new import_screencast.Screencast(this);
|
|
88
103
|
if (delegate.pdf)
|
|
89
104
|
this.pdf = delegate.pdf.bind(delegate);
|
|
90
105
|
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
|
91
106
|
this.isStorageStatePage = browserContext.isCreatingStorageStatePage();
|
|
92
107
|
}
|
|
93
108
|
static {
|
|
94
|
-
this.Events =
|
|
95
|
-
Close: "close",
|
|
96
|
-
Crash: "crash",
|
|
97
|
-
Download: "download",
|
|
98
|
-
EmulatedSizeChanged: "emulatedsizechanged",
|
|
99
|
-
FileChooser: "filechooser",
|
|
100
|
-
FrameAttached: "frameattached",
|
|
101
|
-
FrameDetached: "framedetached",
|
|
102
|
-
InternalFrameNavigatedToNewDocument: "internalframenavigatedtonewdocument",
|
|
103
|
-
LocatorHandlerTriggered: "locatorhandlertriggered",
|
|
104
|
-
ScreencastFrame: "screencastframe",
|
|
105
|
-
Video: "video",
|
|
106
|
-
WebSocket: "websocket",
|
|
107
|
-
Worker: "worker"
|
|
108
|
-
};
|
|
109
|
+
this.Events = PageEvent;
|
|
109
110
|
}
|
|
110
111
|
async reportAsNew(opener, error) {
|
|
111
112
|
if (opener) {
|
|
@@ -158,17 +159,17 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
158
159
|
}
|
|
159
160
|
_didClose() {
|
|
160
161
|
this.frameManager.dispose();
|
|
161
|
-
this.
|
|
162
|
+
this.screencast.stopFrameThrottler();
|
|
162
163
|
(0, import_utils.assert)(this._closedState !== "closed", "Page closed twice");
|
|
163
164
|
this._closedState = "closed";
|
|
164
165
|
this.emit(Page.Events.Close);
|
|
165
166
|
this._closedPromise.resolve();
|
|
166
167
|
this.instrumentation.onPageClose(this);
|
|
167
|
-
this.openScope.close(new import_errors.TargetClosedError());
|
|
168
|
+
this.openScope.close(new import_errors.TargetClosedError(this.closeReason()));
|
|
168
169
|
}
|
|
169
170
|
_didCrash() {
|
|
170
171
|
this.frameManager.dispose();
|
|
171
|
-
this.
|
|
172
|
+
this.screencast.stopFrameThrottler();
|
|
172
173
|
this.emit(Page.Events.Crash);
|
|
173
174
|
this._crashed = true;
|
|
174
175
|
this.instrumentation.onPageClose(this);
|
|
@@ -567,7 +568,7 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
567
568
|
if (this._closedState === "closed")
|
|
568
569
|
return;
|
|
569
570
|
if (options.reason)
|
|
570
|
-
this.
|
|
571
|
+
this._closeReason = options.reason;
|
|
571
572
|
const runBeforeUnload = !!options.runBeforeUnload;
|
|
572
573
|
if (this._closedState !== "closing") {
|
|
573
574
|
if (!runBeforeUnload)
|
|
@@ -624,16 +625,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
624
625
|
getBinding(name) {
|
|
625
626
|
return this._pageBindings.get(name) || this.browserContext._pageBindings.get(name);
|
|
626
627
|
}
|
|
627
|
-
setScreencastOptions(options) {
|
|
628
|
-
this.delegate.setScreencastOptions(options).catch((e) => import_debugLogger.debugLogger.log("error", e));
|
|
629
|
-
this._frameThrottler.setThrottlingEnabled(!!options);
|
|
630
|
-
}
|
|
631
|
-
throttleScreencastFrameAck(ack) {
|
|
632
|
-
this._frameThrottler.ack(ack);
|
|
633
|
-
}
|
|
634
|
-
temporarilyDisableTracingScreencastThrottling() {
|
|
635
|
-
this._frameThrottler.recharge();
|
|
636
|
-
}
|
|
637
628
|
async safeNonStallingEvaluateInAllFrames(expression, world, options = {}) {
|
|
638
629
|
await Promise.all(this.frames().map(async (frame) => {
|
|
639
630
|
try {
|
|
@@ -648,7 +639,7 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
648
639
|
await Promise.all(this.frames().map((frame) => frame.hideHighlight().catch(() => {
|
|
649
640
|
})));
|
|
650
641
|
}
|
|
651
|
-
async snapshotForAI(progress, options) {
|
|
642
|
+
async snapshotForAI(progress, options = {}) {
|
|
652
643
|
const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), options);
|
|
653
644
|
return { full: snapshot.full.join("\n"), incremental: snapshot.incremental?.join("\n") };
|
|
654
645
|
}
|
|
@@ -656,6 +647,9 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
656
647
|
return [...this.browserContext._pageBindings.values(), ...this._pageBindings.values()];
|
|
657
648
|
}
|
|
658
649
|
}
|
|
650
|
+
const WorkerEvent = {
|
|
651
|
+
Close: "close"
|
|
652
|
+
};
|
|
659
653
|
class Worker extends import_instrumentation.SdkObject {
|
|
660
654
|
constructor(parent, url) {
|
|
661
655
|
super(parent, "worker");
|
|
@@ -666,9 +660,7 @@ class Worker extends import_instrumentation.SdkObject {
|
|
|
666
660
|
this.url = url;
|
|
667
661
|
}
|
|
668
662
|
static {
|
|
669
|
-
this.Events =
|
|
670
|
-
Close: "close"
|
|
671
|
-
};
|
|
663
|
+
this.Events = WorkerEvent;
|
|
672
664
|
}
|
|
673
665
|
createExecutionContext(delegate) {
|
|
674
666
|
this.existingExecutionContext = new js.ExecutionContext(this, delegate, "worker");
|
|
@@ -719,6 +711,32 @@ class PageBinding {
|
|
|
719
711
|
}
|
|
720
712
|
static async dispatch(page, payload, context) {
|
|
721
713
|
const { name, seq, serializedArgs } = JSON.parse(payload);
|
|
714
|
+
const deliver = async (deliverPayload) => {
|
|
715
|
+
let deliveryError;
|
|
716
|
+
try {
|
|
717
|
+
await context.evaluate(import_pageBinding.deliverBindingResult, deliverPayload);
|
|
718
|
+
return;
|
|
719
|
+
} catch (e) {
|
|
720
|
+
deliveryError = e;
|
|
721
|
+
}
|
|
722
|
+
const frame = context.frame;
|
|
723
|
+
if (!frame) {
|
|
724
|
+
import_debugLogger.debugLogger.log("error", deliveryError);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
const mainContext = await frame._mainContext().catch(() => null);
|
|
728
|
+
const utilityContext = await frame._utilityContext().catch(() => null);
|
|
729
|
+
for (const ctx of [mainContext, utilityContext]) {
|
|
730
|
+
if (!ctx || ctx === context)
|
|
731
|
+
continue;
|
|
732
|
+
try {
|
|
733
|
+
await ctx.evaluate(import_pageBinding.deliverBindingResult, deliverPayload);
|
|
734
|
+
return;
|
|
735
|
+
} catch {
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
import_debugLogger.debugLogger.log("error", deliveryError);
|
|
739
|
+
};
|
|
722
740
|
try {
|
|
723
741
|
(0, import_utils.assert)(context.world);
|
|
724
742
|
const binding = page.getBinding(name);
|
|
@@ -734,9 +752,9 @@ class PageBinding {
|
|
|
734
752
|
const args = serializedArgs.map((a) => (0, import_utilityScriptSerializers.parseEvaluationResultValue)(a));
|
|
735
753
|
result = await binding.playwrightFunction({ frame: context.frame, page, context: page._browserContext }, ...args);
|
|
736
754
|
}
|
|
737
|
-
|
|
755
|
+
await deliver({ name, seq, result });
|
|
738
756
|
} catch (error) {
|
|
739
|
-
|
|
757
|
+
await deliver({ name, seq, error });
|
|
740
758
|
}
|
|
741
759
|
}
|
|
742
760
|
}
|
|
@@ -745,56 +763,7 @@ class InitScript {
|
|
|
745
763
|
this.source = `(() => { ${source} })();`;
|
|
746
764
|
}
|
|
747
765
|
}
|
|
748
|
-
|
|
749
|
-
constructor(nonThrottledFrames, defaultInterval, throttlingInterval) {
|
|
750
|
-
this._acks = [];
|
|
751
|
-
this._throttlingEnabled = false;
|
|
752
|
-
this._nonThrottledFrames = nonThrottledFrames;
|
|
753
|
-
this._budget = nonThrottledFrames;
|
|
754
|
-
this._defaultInterval = defaultInterval;
|
|
755
|
-
this._throttlingInterval = throttlingInterval;
|
|
756
|
-
this._tick();
|
|
757
|
-
}
|
|
758
|
-
dispose() {
|
|
759
|
-
if (this._timeoutId) {
|
|
760
|
-
clearTimeout(this._timeoutId);
|
|
761
|
-
this._timeoutId = void 0;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
setThrottlingEnabled(enabled) {
|
|
765
|
-
this._throttlingEnabled = enabled;
|
|
766
|
-
}
|
|
767
|
-
recharge() {
|
|
768
|
-
for (const ack of this._acks)
|
|
769
|
-
ack();
|
|
770
|
-
this._acks = [];
|
|
771
|
-
this._budget = this._nonThrottledFrames;
|
|
772
|
-
if (this._timeoutId) {
|
|
773
|
-
clearTimeout(this._timeoutId);
|
|
774
|
-
this._tick();
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
ack(ack) {
|
|
778
|
-
if (!this._timeoutId) {
|
|
779
|
-
ack();
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
this._acks.push(ack);
|
|
783
|
-
}
|
|
784
|
-
_tick() {
|
|
785
|
-
const ack = this._acks.shift();
|
|
786
|
-
if (ack) {
|
|
787
|
-
--this._budget;
|
|
788
|
-
ack();
|
|
789
|
-
}
|
|
790
|
-
if (this._throttlingEnabled && this._budget <= 0) {
|
|
791
|
-
this._timeoutId = setTimeout(() => this._tick(), this._throttlingInterval);
|
|
792
|
-
} else {
|
|
793
|
-
this._timeoutId = setTimeout(() => this._tick(), this._defaultInterval);
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
async function snapshotFrameForAI(progress, frame, options) {
|
|
766
|
+
async function snapshotFrameForAI(progress, frame, options = {}) {
|
|
798
767
|
const snapshot = await frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
|
|
799
768
|
try {
|
|
800
769
|
const context = await progress.race(frame._utilityContext());
|
|
@@ -804,7 +773,7 @@ async function snapshotFrameForAI(progress, frame, options) {
|
|
|
804
773
|
if (!node)
|
|
805
774
|
return true;
|
|
806
775
|
return injected.incrementalAriaSnapshot(node, { mode: "ai", ...options2 });
|
|
807
|
-
}, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track }));
|
|
776
|
+
}, { refPrefix: frame.seq ? "f" + frame.seq : "", track: options.track, doNotRenderActive: options.doNotRenderActive }));
|
|
808
777
|
if (snapshotOrRetry === true)
|
|
809
778
|
return continuePolling;
|
|
810
779
|
return snapshotOrRetry;
|
|
@@ -864,5 +833,6 @@ function ensureArrayLimit(array, limit) {
|
|
|
864
833
|
InitScript,
|
|
865
834
|
Page,
|
|
866
835
|
PageBinding,
|
|
867
|
-
Worker
|
|
836
|
+
Worker,
|
|
837
|
+
WorkerEvent
|
|
868
838
|
});
|
package/lib/server/progress.js
CHANGED
|
@@ -34,19 +34,35 @@ class ProgressController {
|
|
|
34
34
|
this.metadata = metadata || { id: "", startTime: 0, endTime: 0, type: "Internal", method: "", params: {}, log: [], internal: true };
|
|
35
35
|
this._onCallLog = onCallLog;
|
|
36
36
|
this._forceAbortPromise.catch((e) => null);
|
|
37
|
+
this._controller = new AbortController();
|
|
38
|
+
}
|
|
39
|
+
static createForSdkObject(sdkObject, callMetadata) {
|
|
40
|
+
const logName = sdkObject.logName || "api";
|
|
41
|
+
return new ProgressController(callMetadata, (message) => {
|
|
42
|
+
import_utils.debugLogger.log(logName, message);
|
|
43
|
+
sdkObject.instrumentation.onCallLog(sdkObject, callMetadata, logName, message);
|
|
44
|
+
});
|
|
37
45
|
}
|
|
38
46
|
async abort(error) {
|
|
39
47
|
if (this._state === "running") {
|
|
40
48
|
error[kAbortErrorSymbol] = true;
|
|
41
49
|
this._state = { error };
|
|
42
50
|
this._forceAbortPromise.reject(error);
|
|
51
|
+
this._controller.abort(error);
|
|
43
52
|
}
|
|
44
53
|
await this._donePromise;
|
|
45
54
|
}
|
|
46
55
|
async run(task, timeout) {
|
|
56
|
+
const deadline = timeout ? (0, import_utils.monotonicTime)() + timeout : 0;
|
|
47
57
|
(0, import_utils.assert)(this._state === "before");
|
|
48
58
|
this._state = "running";
|
|
59
|
+
let timer;
|
|
49
60
|
const progress = {
|
|
61
|
+
timeout: timeout ?? 0,
|
|
62
|
+
deadline,
|
|
63
|
+
disableTimeout: () => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
},
|
|
50
66
|
log: (message) => {
|
|
51
67
|
if (this._state === "running")
|
|
52
68
|
this.metadata.log.push(message);
|
|
@@ -55,24 +71,28 @@ class ProgressController {
|
|
|
55
71
|
metadata: this.metadata,
|
|
56
72
|
race: (promise) => {
|
|
57
73
|
const promises = Array.isArray(promise) ? promise : [promise];
|
|
74
|
+
if (!promises.length)
|
|
75
|
+
return Promise.resolve();
|
|
58
76
|
return Promise.race([...promises, this._forceAbortPromise]);
|
|
59
77
|
},
|
|
60
78
|
wait: async (timeout2) => {
|
|
61
79
|
let timer2;
|
|
62
80
|
const promise = new Promise((f) => timer2 = setTimeout(f, timeout2));
|
|
63
81
|
return progress.race(promise).finally(() => clearTimeout(timer2));
|
|
64
|
-
}
|
|
82
|
+
},
|
|
83
|
+
signal: this._controller.signal
|
|
65
84
|
};
|
|
66
|
-
|
|
67
|
-
if (timeout) {
|
|
85
|
+
if (deadline) {
|
|
68
86
|
const timeoutError = new import_errors.TimeoutError(`Timeout ${timeout}ms exceeded.`);
|
|
69
87
|
timer = setTimeout(() => {
|
|
88
|
+
if (this.metadata.pauseStartTime && !this.metadata.pauseEndTime)
|
|
89
|
+
return;
|
|
70
90
|
if (this._state === "running") {
|
|
71
|
-
timeoutError[kAbortErrorSymbol] = true;
|
|
72
91
|
this._state = { error: timeoutError };
|
|
73
92
|
this._forceAbortPromise.reject(timeoutError);
|
|
93
|
+
this._controller.abort(timeoutError);
|
|
74
94
|
}
|
|
75
|
-
},
|
|
95
|
+
}, deadline - (0, import_utils.monotonicTime)());
|
|
76
96
|
}
|
|
77
97
|
try {
|
|
78
98
|
const result = await task(progress);
|
|
@@ -89,7 +109,7 @@ class ProgressController {
|
|
|
89
109
|
}
|
|
90
110
|
const kAbortErrorSymbol = Symbol("kAbortError");
|
|
91
111
|
function isAbortError(error) {
|
|
92
|
-
return !!error[kAbortErrorSymbol];
|
|
112
|
+
return error instanceof import_errors.TimeoutError || !!error[kAbortErrorSymbol];
|
|
93
113
|
}
|
|
94
114
|
async function raceUncancellableOperationWithCleanup(progress, run, cleanup) {
|
|
95
115
|
let aborted = false;
|