playwright-core 1.58.0-alpha-2025-12-18 → 1.58.0-alpha-2025-12-19
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/browsers.json +2 -2
- package/lib/client/browserType.js +2 -1
- package/lib/protocol/validator.js +17 -16
- package/lib/server/agent/agent.js +26 -21
- package/lib/server/chromium/chromium.js +2 -1
- package/lib/server/chromium/crPage.js +1 -2
- package/lib/server/firefox/ffBrowser.js +9 -19
- package/lib/server/firefox/ffPage.js +8 -12
- package/lib/server/registry/index.js +59 -41
- package/lib/server/webkit/wkPage.js +1 -2
- package/package.json +1 -1
- package/types/types.d.ts +12 -6
package/browsers.json
CHANGED
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"name": "firefox",
|
|
34
|
-
"revision": "
|
|
34
|
+
"revision": "1507",
|
|
35
35
|
"installByDefault": true,
|
|
36
36
|
"browserVersion": "145.0.2",
|
|
37
37
|
"title": "Firefox"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"name": "firefox-beta",
|
|
41
|
-
"revision": "
|
|
41
|
+
"revision": "1502",
|
|
42
42
|
"installByDefault": false,
|
|
43
43
|
"browserVersion": "146.0b8",
|
|
44
44
|
"title": "Firefox Beta"
|
|
@@ -169,7 +169,8 @@ class BrowserType extends import_channelOwner.ChannelOwner {
|
|
|
169
169
|
endpointURL,
|
|
170
170
|
headers,
|
|
171
171
|
slowMo: params.slowMo,
|
|
172
|
-
timeout: new import_timeoutSettings.TimeoutSettings(this._platform).timeout(params)
|
|
172
|
+
timeout: new import_timeoutSettings.TimeoutSettings(this._platform).timeout(params),
|
|
173
|
+
isLocal: params.isLocal
|
|
173
174
|
});
|
|
174
175
|
const browser = import_browser.Browser.from(result.browser);
|
|
175
176
|
browser._connectToBrowserType(this, {}, params.logger);
|
|
@@ -609,10 +609,10 @@ import_validatorPrimitives.scheme.BrowserTypeLaunchPersistentContextParams = (0,
|
|
|
609
609
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
610
610
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
611
611
|
agent: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
612
|
-
provider: import_validatorPrimitives.tString,
|
|
613
|
-
model: import_validatorPrimitives.tString,
|
|
612
|
+
provider: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
613
|
+
model: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
614
614
|
cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
615
|
-
|
|
615
|
+
cacheOutFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
616
616
|
secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
617
617
|
maxTurns: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt),
|
|
618
618
|
maxTokens: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt)
|
|
@@ -628,7 +628,8 @@ import_validatorPrimitives.scheme.BrowserTypeConnectOverCDPParams = (0, import_v
|
|
|
628
628
|
endpointURL: import_validatorPrimitives.tString,
|
|
629
629
|
headers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
630
630
|
slowMo: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tFloat),
|
|
631
|
-
timeout: import_validatorPrimitives.tFloat
|
|
631
|
+
timeout: import_validatorPrimitives.tFloat,
|
|
632
|
+
isLocal: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
632
633
|
});
|
|
633
634
|
import_validatorPrimitives.scheme.BrowserTypeConnectOverCDPResult = (0, import_validatorPrimitives.tObject)({
|
|
634
635
|
browser: (0, import_validatorPrimitives.tChannel)(["Browser"]),
|
|
@@ -710,10 +711,10 @@ import_validatorPrimitives.scheme.BrowserNewContextParams = (0, import_validator
|
|
|
710
711
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
711
712
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
712
713
|
agent: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
713
|
-
provider: import_validatorPrimitives.tString,
|
|
714
|
-
model: import_validatorPrimitives.tString,
|
|
714
|
+
provider: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
715
|
+
model: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
715
716
|
cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
716
|
-
|
|
717
|
+
cacheOutFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
717
718
|
secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
718
719
|
maxTurns: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt),
|
|
719
720
|
maxTokens: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt)
|
|
@@ -790,10 +791,10 @@ import_validatorPrimitives.scheme.BrowserNewContextForReuseParams = (0, import_v
|
|
|
790
791
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
791
792
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
792
793
|
agent: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
793
|
-
provider: import_validatorPrimitives.tString,
|
|
794
|
-
model: import_validatorPrimitives.tString,
|
|
794
|
+
provider: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
795
|
+
model: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
795
796
|
cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
796
|
-
|
|
797
|
+
cacheOutFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
797
798
|
secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
798
799
|
maxTurns: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt),
|
|
799
800
|
maxTokens: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt)
|
|
@@ -915,10 +916,10 @@ import_validatorPrimitives.scheme.BrowserContextInitializer = (0, import_validat
|
|
|
915
916
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
916
917
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
917
918
|
agent: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
918
|
-
provider: import_validatorPrimitives.tString,
|
|
919
|
-
model: import_validatorPrimitives.tString,
|
|
919
|
+
provider: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
920
|
+
model: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
920
921
|
cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
921
|
-
|
|
922
|
+
cacheOutFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
922
923
|
secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
923
924
|
maxTurns: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt),
|
|
924
925
|
maxTokens: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt)
|
|
@@ -2843,10 +2844,10 @@ import_validatorPrimitives.scheme.AndroidDeviceLaunchBrowserParams = (0, import_
|
|
|
2843
2844
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
2844
2845
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2845
2846
|
agent: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
2846
|
-
provider: import_validatorPrimitives.tString,
|
|
2847
|
-
model: import_validatorPrimitives.tString,
|
|
2847
|
+
provider: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2848
|
+
model: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2848
2849
|
cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2849
|
-
|
|
2850
|
+
cacheOutFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2850
2851
|
secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue"))),
|
|
2851
2852
|
maxTurns: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt),
|
|
2852
2853
|
maxTokens: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tInt)
|
|
@@ -61,8 +61,8 @@ ${options.query}`;
|
|
|
61
61
|
async function perform(progress, context, userTask, resultSchema, options = {}) {
|
|
62
62
|
const { page } = context;
|
|
63
63
|
const browserContext = page.browserContext;
|
|
64
|
-
if (!browserContext._options.agent)
|
|
65
|
-
throw new Error(`
|
|
64
|
+
if (!browserContext._options.agent?.provider || !browserContext._options.agent?.model)
|
|
65
|
+
throw new Error(`This action requires the agent provider and model to be set on the browser context`);
|
|
66
66
|
const { full } = await page.snapshotForAI(progress);
|
|
67
67
|
const { tools, callTool } = (0, import_backend.toolsForLoop)(context);
|
|
68
68
|
page.emit(import_page.Page.Events.AgentTurn, { role: "user", message: userTask });
|
|
@@ -121,44 +121,49 @@ ${full}
|
|
|
121
121
|
}
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
-
const allCaches = /* @__PURE__ */ new Map();
|
|
125
124
|
async function cachedPerform(progress, context, options) {
|
|
126
|
-
if (!context.options?.cacheFile
|
|
125
|
+
if (!context.options?.cacheFile)
|
|
127
126
|
return false;
|
|
128
|
-
const cache = await cachedActions(context.options
|
|
127
|
+
const cache = await cachedActions(context, context.options?.cacheFile);
|
|
129
128
|
const cacheKey = (options.key ?? options.task).trim();
|
|
130
|
-
const entry = cache[cacheKey];
|
|
131
|
-
if (!entry)
|
|
132
|
-
if (context.options.cacheMode === "force")
|
|
133
|
-
throw new Error(`No cached actions for key "${cacheKey}", but cache mode is set to "force"`);
|
|
129
|
+
const entry = cache.actions[cacheKey];
|
|
130
|
+
if (!entry)
|
|
134
131
|
return false;
|
|
135
|
-
}
|
|
136
132
|
for (const action of entry.actions)
|
|
137
133
|
await (0, import_actionRunner.runAction)(progress, "run", context.page, action, context.options.secrets ?? []);
|
|
138
134
|
return true;
|
|
139
135
|
}
|
|
140
136
|
async function updateCache(context, options) {
|
|
141
137
|
const cacheFile = context.options?.cacheFile;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const cache = await cachedActions(cacheFile);
|
|
138
|
+
const cacheOutFile = context.options?.cacheOutFile;
|
|
139
|
+
const cache = cacheFile ? await cachedActions(context, cacheFile) : { actions: {}, newActions: {} };
|
|
145
140
|
const cacheKey = (options.key ?? options.task).trim();
|
|
146
|
-
|
|
141
|
+
const newEntry = {
|
|
147
142
|
timestamp: Date.now(),
|
|
148
143
|
actions: context.actions
|
|
149
144
|
};
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
cache.actions[cacheKey] = newEntry;
|
|
146
|
+
cache.newActions[cacheKey] = newEntry;
|
|
147
|
+
if (cacheOutFile) {
|
|
148
|
+
const entries = Object.entries(cache.newActions);
|
|
149
|
+
entries.sort((e1, e2) => e1[0].localeCompare(e2[0]));
|
|
150
|
+
await import_fs.default.promises.writeFile(cacheOutFile, JSON.stringify(Object.fromEntries(entries), void 0, 2));
|
|
151
|
+
} else if (cacheFile) {
|
|
152
|
+
const entries = Object.entries(cache.actions);
|
|
153
|
+
entries.sort((e1, e2) => e1[0].localeCompare(e2[0]));
|
|
154
|
+
await import_fs.default.promises.writeFile(cacheFile, JSON.stringify(Object.fromEntries(entries), void 0, 2));
|
|
155
|
+
}
|
|
153
156
|
}
|
|
154
|
-
async function cachedActions(cacheFile) {
|
|
155
|
-
let cache =
|
|
157
|
+
async function cachedActions(context, cacheFile) {
|
|
158
|
+
let cache = context[agentCacheSymbol];
|
|
156
159
|
if (!cache) {
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
const actions = await import_fs.default.promises.readFile(cacheFile, "utf-8").then((text) => JSON.parse(text)).catch(() => ({}));
|
|
161
|
+
cache = { actions, newActions: {} };
|
|
162
|
+
context[agentCacheSymbol] = cache;
|
|
159
163
|
}
|
|
160
164
|
return cache;
|
|
161
165
|
}
|
|
166
|
+
const agentCacheSymbol = Symbol("agentCache");
|
|
162
167
|
// Annotate the CommonJS export names for ESM import in node:
|
|
163
168
|
0 && (module.exports = {
|
|
164
169
|
pageExtract,
|
|
@@ -114,7 +114,8 @@ class Chromium extends import_browserType.BrowserType {
|
|
|
114
114
|
};
|
|
115
115
|
(0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
|
|
116
116
|
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
|
|
117
|
-
|
|
117
|
+
if (!options.isLocal)
|
|
118
|
+
browser._isCollocatedWithServer = false;
|
|
118
119
|
browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
|
|
119
120
|
return browser;
|
|
120
121
|
} catch (error) {
|
|
@@ -709,8 +709,7 @@ class FrameSession {
|
|
|
709
709
|
}
|
|
710
710
|
_onScreencastFrame(payload) {
|
|
711
711
|
this._page.screencast.throttleFrameAck(() => {
|
|
712
|
-
this._client.
|
|
713
|
-
});
|
|
712
|
+
this._client._sendMayFail("Page.screencastFrameAck", { sessionId: payload.sessionId });
|
|
714
713
|
});
|
|
715
714
|
const buffer = Buffer.from(payload.data, "base64");
|
|
716
715
|
this._page.emit(import_page.Page.Events.ScreencastFrame, {
|
|
@@ -54,7 +54,6 @@ class FFBrowser extends import_browser.Browser {
|
|
|
54
54
|
this.session.on("Browser.detachedFromTarget", this._onDetachedFromTarget.bind(this));
|
|
55
55
|
this.session.on("Browser.downloadCreated", this._onDownloadCreated.bind(this));
|
|
56
56
|
this.session.on("Browser.downloadFinished", this._onDownloadFinished.bind(this));
|
|
57
|
-
this.session.on("Browser.videoRecordingFinished", this._onVideoRecordingFinished.bind(this));
|
|
58
57
|
}
|
|
59
58
|
static async connect(parent, transport, options) {
|
|
60
59
|
const connection = new import_ffConnection.FFConnection(transport, options.protocolLogger, options.browserLogsCollector);
|
|
@@ -141,9 +140,6 @@ class FFBrowser extends import_browser.Browser {
|
|
|
141
140
|
const error = payload.canceled ? "canceled" : payload.error;
|
|
142
141
|
this._downloadFinished(payload.uuid, error);
|
|
143
142
|
}
|
|
144
|
-
_onVideoRecordingFinished(payload) {
|
|
145
|
-
this._takeVideo(payload.screencastId)?.reportFinished();
|
|
146
|
-
}
|
|
147
143
|
_onDisconnect() {
|
|
148
144
|
for (const video of this._idToVideo.values())
|
|
149
145
|
video.artifact.reportFinished(new import_errors.TargetClosedError(this.closeReason()));
|
|
@@ -199,15 +195,13 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
199
195
|
promises.push(this.doUpdateOffline());
|
|
200
196
|
promises.push(this.doUpdateDefaultEmulatedMedia());
|
|
201
197
|
if (this._options.recordVideo) {
|
|
202
|
-
promises.push(this.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
browserContextId: this._browserContextId
|
|
210
|
-
});
|
|
198
|
+
promises.push(this._browser.session.send("Browser.setScreencastOptions", {
|
|
199
|
+
// validateBrowserContextOptions ensures correct video size.
|
|
200
|
+
options: {
|
|
201
|
+
...this._options.recordVideo.size,
|
|
202
|
+
quality: 90
|
|
203
|
+
},
|
|
204
|
+
browserContextId: this._browserContextId
|
|
211
205
|
}));
|
|
212
206
|
}
|
|
213
207
|
const proxy = this._options.proxyOverride || this._options.proxy;
|
|
@@ -379,12 +373,8 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
379
373
|
}
|
|
380
374
|
async doClose(reason) {
|
|
381
375
|
if (!this._browserContextId) {
|
|
382
|
-
if (this._options.recordVideo)
|
|
383
|
-
await this.
|
|
384
|
-
options: void 0,
|
|
385
|
-
browserContextId: this._browserContextId
|
|
386
|
-
});
|
|
387
|
-
}
|
|
376
|
+
if (this._options.recordVideo)
|
|
377
|
+
await Promise.all(this._ffPages().map((ffPage) => ffPage._page.screencast.stopVideoRecording()));
|
|
388
378
|
await this._browser.close({ reason });
|
|
389
379
|
} else {
|
|
390
380
|
await this._browser.session.send("Browser.removeBrowserContext", { browserContextId: this._browserContextId });
|
|
@@ -41,9 +41,9 @@ var import_ffConnection = require("./ffConnection");
|
|
|
41
41
|
var import_ffExecutionContext = require("./ffExecutionContext");
|
|
42
42
|
var import_ffInput = require("./ffInput");
|
|
43
43
|
var import_ffNetworkManager = require("./ffNetworkManager");
|
|
44
|
-
var import_debugLogger = require("../utils/debugLogger");
|
|
45
44
|
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
|
46
45
|
var import_errors = require("../errors");
|
|
46
|
+
var import_debugLogger = require("../utils/debugLogger");
|
|
47
47
|
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
|
48
48
|
class FFPage {
|
|
49
49
|
constructor(session, browserContext, opener) {
|
|
@@ -83,13 +83,16 @@ class FFPage {
|
|
|
83
83
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.workerDestroyed", this._onWorkerDestroyed.bind(this)),
|
|
84
84
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.dispatchMessageFromWorker", this._onDispatchMessageFromWorker.bind(this)),
|
|
85
85
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.crashed", this._onCrashed.bind(this)),
|
|
86
|
-
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.videoRecordingStarted", this._onVideoRecordingStarted.bind(this)),
|
|
87
86
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketCreated", this._onWebSocketCreated.bind(this)),
|
|
88
87
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketClosed", this._onWebSocketClosed.bind(this)),
|
|
89
88
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameReceived", this._onWebSocketFrameReceived.bind(this)),
|
|
90
89
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameSent", this._onWebSocketFrameSent.bind(this)),
|
|
91
90
|
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.screencastFrame", this._onScreencastFrame.bind(this))
|
|
92
91
|
];
|
|
92
|
+
const screencast = this._page.screencast;
|
|
93
|
+
const videoOptions = screencast.launchVideoRecorder();
|
|
94
|
+
if (videoOptions)
|
|
95
|
+
screencast.startVideoRecording(videoOptions).catch((e) => import_debugLogger.debugLogger.log("error", e));
|
|
93
96
|
this._session.once("Page.ready", () => {
|
|
94
97
|
if (this._reportedAsNew)
|
|
95
98
|
return;
|
|
@@ -272,9 +275,6 @@ class FFPage {
|
|
|
272
275
|
this._session.markAsCrashed();
|
|
273
276
|
this._page._didCrash();
|
|
274
277
|
}
|
|
275
|
-
_onVideoRecordingStarted(event) {
|
|
276
|
-
this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this._page.waitForInitializedOrError());
|
|
277
|
-
}
|
|
278
278
|
didClose() {
|
|
279
279
|
this._markAsError(new import_errors.TargetClosedError(this._page.closeReason()));
|
|
280
280
|
this._session.dispose();
|
|
@@ -418,18 +418,14 @@ class FFPage {
|
|
|
418
418
|
});
|
|
419
419
|
}
|
|
420
420
|
async startScreencast(options) {
|
|
421
|
-
|
|
422
|
-
this._screencastId = screencastId;
|
|
421
|
+
await this._session.send("Page.startScreencast", options);
|
|
423
422
|
}
|
|
424
423
|
async stopScreencast() {
|
|
425
|
-
await this._session.
|
|
424
|
+
await this._session.sendMayFail("Page.stopScreencast");
|
|
426
425
|
}
|
|
427
426
|
_onScreencastFrame(event) {
|
|
428
|
-
if (!this._screencastId)
|
|
429
|
-
return;
|
|
430
|
-
const screencastId = this._screencastId;
|
|
431
427
|
this._page.screencast.throttleFrameAck(() => {
|
|
432
|
-
this._session.
|
|
428
|
+
this._session.sendMayFail("Page.screencastFrameAck");
|
|
433
429
|
});
|
|
434
430
|
const buffer = Buffer.from(event.data, "base64");
|
|
435
431
|
this._page.emit(import_page2.Page.Events.ScreencastFrame, {
|
|
@@ -145,68 +145,78 @@ const EXECUTABLE_PATHS = {
|
|
|
145
145
|
"win-x64": ["PrintDeps.exe"]
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
|
+
function cftUrl(suffix) {
|
|
149
|
+
return ({ browserVersion }) => {
|
|
150
|
+
return {
|
|
151
|
+
path: `${browserVersion}/${suffix}`,
|
|
152
|
+
mirrors: [
|
|
153
|
+
"https://cdn.playwright.dev/chrome-for-testing-public"
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
}
|
|
148
158
|
const DOWNLOAD_PATHS = {
|
|
149
159
|
"chromium": {
|
|
150
160
|
"<unknown>": void 0,
|
|
151
161
|
"ubuntu18.04-x64": void 0,
|
|
152
|
-
"ubuntu20.04-x64": "
|
|
153
|
-
"ubuntu22.04-x64": "
|
|
154
|
-
"ubuntu24.04-x64": "
|
|
162
|
+
"ubuntu20.04-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
163
|
+
"ubuntu22.04-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
164
|
+
"ubuntu24.04-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
155
165
|
"ubuntu18.04-arm64": void 0,
|
|
156
166
|
"ubuntu20.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
157
167
|
"ubuntu22.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
158
168
|
"ubuntu24.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
159
|
-
"debian11-x64": "
|
|
169
|
+
"debian11-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
160
170
|
"debian11-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
161
|
-
"debian12-x64": "
|
|
171
|
+
"debian12-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
162
172
|
"debian12-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
163
|
-
"debian13-x64": "
|
|
173
|
+
"debian13-x64": cftUrl("linux64/chrome-linux64.zip"),
|
|
164
174
|
"debian13-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
|
|
165
|
-
"mac10.13": "
|
|
166
|
-
"mac10.14": "
|
|
167
|
-
"mac10.15": "
|
|
168
|
-
"mac11": "
|
|
169
|
-
"mac11-arm64": "
|
|
170
|
-
"mac12": "
|
|
171
|
-
"mac12-arm64": "
|
|
172
|
-
"mac13": "
|
|
173
|
-
"mac13-arm64": "
|
|
174
|
-
"mac14": "
|
|
175
|
-
"mac14-arm64": "
|
|
176
|
-
"mac15": "
|
|
177
|
-
"mac15-arm64": "
|
|
178
|
-
"win64": "
|
|
175
|
+
"mac10.13": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
176
|
+
"mac10.14": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
177
|
+
"mac10.15": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
178
|
+
"mac11": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
179
|
+
"mac11-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
|
|
180
|
+
"mac12": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
181
|
+
"mac12-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
|
|
182
|
+
"mac13": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
183
|
+
"mac13-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
|
|
184
|
+
"mac14": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
185
|
+
"mac14-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
|
|
186
|
+
"mac15": cftUrl("mac-x64/chrome-mac-x64.zip"),
|
|
187
|
+
"mac15-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
|
|
188
|
+
"win64": cftUrl("win64/chrome-win64.zip")
|
|
179
189
|
},
|
|
180
190
|
"chromium-headless-shell": {
|
|
181
191
|
"<unknown>": void 0,
|
|
182
192
|
"ubuntu18.04-x64": void 0,
|
|
183
|
-
"ubuntu20.04-x64": "
|
|
184
|
-
"ubuntu22.04-x64": "
|
|
185
|
-
"ubuntu24.04-x64": "
|
|
193
|
+
"ubuntu20.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
194
|
+
"ubuntu22.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
195
|
+
"ubuntu24.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
186
196
|
"ubuntu18.04-arm64": void 0,
|
|
187
197
|
"ubuntu20.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
188
198
|
"ubuntu22.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
189
199
|
"ubuntu24.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
190
|
-
"debian11-x64": "
|
|
200
|
+
"debian11-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
191
201
|
"debian11-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
192
|
-
"debian12-x64": "
|
|
202
|
+
"debian12-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
193
203
|
"debian12-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
194
|
-
"debian13-x64": "
|
|
204
|
+
"debian13-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
|
|
195
205
|
"debian13-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
|
|
196
206
|
"mac10.13": void 0,
|
|
197
207
|
"mac10.14": void 0,
|
|
198
208
|
"mac10.15": void 0,
|
|
199
|
-
"mac11": "
|
|
200
|
-
"mac11-arm64": "
|
|
201
|
-
"mac12": "
|
|
202
|
-
"mac12-arm64": "
|
|
203
|
-
"mac13": "
|
|
204
|
-
"mac13-arm64": "
|
|
205
|
-
"mac14": "
|
|
206
|
-
"mac14-arm64": "
|
|
207
|
-
"mac15": "
|
|
208
|
-
"mac15-arm64": "
|
|
209
|
-
"win64": "
|
|
209
|
+
"mac11": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
|
|
210
|
+
"mac11-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
|
|
211
|
+
"mac12": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
|
|
212
|
+
"mac12-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
|
|
213
|
+
"mac13": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
|
|
214
|
+
"mac13-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
|
|
215
|
+
"mac14": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
|
|
216
|
+
"mac14-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
|
|
217
|
+
"mac15": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
|
|
218
|
+
"mac15-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
|
|
219
|
+
"win64": cftUrl("win64/chrome-headless-shell-win64.zip")
|
|
210
220
|
},
|
|
211
221
|
"chromium-tip-of-tree": {
|
|
212
222
|
"<unknown>": void 0,
|
|
@@ -1124,8 +1134,16 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
|
|
|
1124
1134
|
const downloadPathTemplate = paths[import_hostPlatform.hostPlatform] || paths["<unknown>"];
|
|
1125
1135
|
if (!downloadPathTemplate)
|
|
1126
1136
|
return [];
|
|
1127
|
-
|
|
1128
|
-
let
|
|
1137
|
+
let downloadPath;
|
|
1138
|
+
let mirrors;
|
|
1139
|
+
if (typeof downloadPathTemplate === "function") {
|
|
1140
|
+
const result = downloadPathTemplate(descriptor);
|
|
1141
|
+
downloadPath = result.path;
|
|
1142
|
+
mirrors = result.mirrors;
|
|
1143
|
+
} else {
|
|
1144
|
+
downloadPath = util.format(downloadPathTemplate, descriptor.revision);
|
|
1145
|
+
mirrors = PLAYWRIGHT_CDN_MIRRORS;
|
|
1146
|
+
}
|
|
1129
1147
|
let downloadHostEnv;
|
|
1130
1148
|
if (descriptor.name.startsWith("chromium"))
|
|
1131
1149
|
downloadHostEnv = "PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST";
|
|
@@ -1135,8 +1153,8 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
|
|
|
1135
1153
|
downloadHostEnv = "PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST";
|
|
1136
1154
|
const customHostOverride = downloadHostEnv && (0, import_utils.getFromENV)(downloadHostEnv) || (0, import_utils.getFromENV)("PLAYWRIGHT_DOWNLOAD_HOST");
|
|
1137
1155
|
if (customHostOverride)
|
|
1138
|
-
|
|
1139
|
-
return
|
|
1156
|
+
mirrors = [customHostOverride];
|
|
1157
|
+
return mirrors.map((mirror) => `${mirror}/${downloadPath}`);
|
|
1140
1158
|
}
|
|
1141
1159
|
async _downloadExecutable(descriptor, executablePath) {
|
|
1142
1160
|
const downloadURLs = this._downloadURLs(descriptor);
|
|
@@ -49,7 +49,6 @@ var import_wkInput = require("./wkInput");
|
|
|
49
49
|
var import_wkInterceptableRequest = require("./wkInterceptableRequest");
|
|
50
50
|
var import_wkProvisionalPage = require("./wkProvisionalPage");
|
|
51
51
|
var import_wkWorkers = require("./wkWorkers");
|
|
52
|
-
var import_debugLogger = require("../utils/debugLogger");
|
|
53
52
|
var import_webkit = require("./webkit");
|
|
54
53
|
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
|
55
54
|
class WKPage {
|
|
@@ -836,7 +835,7 @@ class WKPage {
|
|
|
836
835
|
_onScreencastFrame(event) {
|
|
837
836
|
const generation = this._screencastGeneration;
|
|
838
837
|
this._page.screencast.throttleFrameAck(() => {
|
|
839
|
-
this._pageProxySession.
|
|
838
|
+
this._pageProxySession.sendMayFail("Screencast.screencastFrameAck", { generation });
|
|
840
839
|
});
|
|
841
840
|
const buffer = Buffer.from(event.data, "base64");
|
|
842
841
|
this._page.emit(import_page.Page.Events.ScreencastFrame, {
|
package/package.json
CHANGED
package/types/types.d.ts
CHANGED
|
@@ -22046,6 +22046,12 @@ export interface ConnectOverCDPOptions {
|
|
|
22046
22046
|
*/
|
|
22047
22047
|
headers?: { [key: string]: string; };
|
|
22048
22048
|
|
|
22049
|
+
/**
|
|
22050
|
+
* Tells Playwright that it runs on the same host as the CDP server. It will enable certain optimizations that rely
|
|
22051
|
+
* upon the file system being the same between Playwright and the Browser.
|
|
22052
|
+
*/
|
|
22053
|
+
isLocal?: boolean;
|
|
22054
|
+
|
|
22049
22055
|
/**
|
|
22050
22056
|
* Logger sink for Playwright logging. Optional.
|
|
22051
22057
|
* @deprecated The logs received by the logger are incomplete. Please use tracing instead.
|
|
@@ -22226,14 +22232,14 @@ export interface BrowserContextOptions {
|
|
|
22226
22232
|
*/
|
|
22227
22233
|
agent?: {
|
|
22228
22234
|
/**
|
|
22229
|
-
* LLM provider to use.
|
|
22235
|
+
* LLM provider to use. Required in non-cache mode.
|
|
22230
22236
|
*/
|
|
22231
|
-
provider
|
|
22237
|
+
provider?: string;
|
|
22232
22238
|
|
|
22233
22239
|
/**
|
|
22234
|
-
* Model identifier within provider.
|
|
22240
|
+
* Model identifier within the provider. Required in non-cache mode.
|
|
22235
22241
|
*/
|
|
22236
|
-
model
|
|
22242
|
+
model?: string;
|
|
22237
22243
|
|
|
22238
22244
|
/**
|
|
22239
22245
|
* Cache file to use/generate code for performed actions into. Cache is not used if not specified (default).
|
|
@@ -22241,9 +22247,9 @@ export interface BrowserContextOptions {
|
|
|
22241
22247
|
cacheFile?: string;
|
|
22242
22248
|
|
|
22243
22249
|
/**
|
|
22244
|
-
*
|
|
22250
|
+
* When specified, generated entries are written into the `cacheOutFile` instead of updating the `cacheFile`.
|
|
22245
22251
|
*/
|
|
22246
|
-
|
|
22252
|
+
cacheOutFile?: string;
|
|
22247
22253
|
|
|
22248
22254
|
/**
|
|
22249
22255
|
* Secrets to hide from the LLM.
|