playwright-core 1.54.0-alpha-2025-06-19 → 1.54.0-alpha-2025-06-20
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/lib/remote/playwrightConnection.js +16 -24
- package/lib/remote/playwrightServer.js +4 -14
- package/lib/server/dispatchers/androidDispatcher.js +6 -1
- package/lib/server/dispatchers/browserTypeDispatcher.js +8 -1
- package/lib/server/dispatchers/electronDispatcher.js +4 -1
- package/lib/server/dispatchers/playwrightDispatcher.js +8 -7
- package/lib/server/utils/wsServer.js +0 -1
- package/package.json +1 -1
|
@@ -33,15 +33,14 @@ var import_profiler = require("../server/utils/profiler");
|
|
|
33
33
|
var import_utils = require("../utils");
|
|
34
34
|
var import_debugLogger = require("../server/utils/debugLogger");
|
|
35
35
|
class PlaywrightConnection {
|
|
36
|
-
constructor(lock, clientType, ws, options, preLaunched, id, onClose) {
|
|
36
|
+
constructor(lock, clientType, ws, options, playwright, preLaunched, id, onClose) {
|
|
37
37
|
this._cleanups = [];
|
|
38
38
|
this._disconnected = false;
|
|
39
39
|
this._ws = ws;
|
|
40
|
+
this._playwright = playwright;
|
|
40
41
|
this._preLaunched = preLaunched;
|
|
41
42
|
this._options = options;
|
|
42
43
|
options.launchOptions = filterLaunchOptions(options.launchOptions, options.allowFSPaths);
|
|
43
|
-
if (clientType === "reuse-browser" || clientType === "pre-launched-browser-or-android")
|
|
44
|
-
(0, import_assert.assert)(preLaunched.playwright);
|
|
45
44
|
if (clientType === "pre-launched-browser-or-android")
|
|
46
45
|
(0, import_assert.assert)(preLaunched.browser || preLaunched.androidDevice);
|
|
47
46
|
this._onClose = onClose;
|
|
@@ -88,7 +87,6 @@ class PlaywrightConnection {
|
|
|
88
87
|
}
|
|
89
88
|
async _initLaunchBrowserMode(scope, options) {
|
|
90
89
|
import_debugLogger.debugLogger.log("server", `[${this._id}] engaged launch mode for "${this._options.browserName}"`);
|
|
91
|
-
const playwright = (0, import_server.createPlaywright)({ sdkLanguage: options.sdkLanguage, isServer: true });
|
|
92
90
|
const ownedSocksProxy = await this._createOwnedSocksProxy();
|
|
93
91
|
let browserName = this._options.browserName;
|
|
94
92
|
if ("bidi" === browserName) {
|
|
@@ -97,32 +95,29 @@ class PlaywrightConnection {
|
|
|
97
95
|
else
|
|
98
96
|
browserName = "bidiChromium";
|
|
99
97
|
}
|
|
100
|
-
const browser = await
|
|
98
|
+
const browser = await this._playwright[browserName].launch((0, import_instrumentation.serverSideCallMetadata)(), this._options.launchOptions);
|
|
101
99
|
browser.options.sdkLanguage = options.sdkLanguage;
|
|
102
|
-
this._cleanups.push(
|
|
103
|
-
for (const browser2 of playwright.allBrowsers())
|
|
104
|
-
await browser2.close({ reason: "Connection terminated" });
|
|
105
|
-
});
|
|
100
|
+
this._cleanups.push(() => browser.close({ reason: "Connection terminated" }));
|
|
106
101
|
browser.on(import_browser.Browser.Events.Disconnected, () => {
|
|
107
102
|
this.close({ code: 1001, reason: "Browser closed" });
|
|
108
103
|
});
|
|
109
|
-
return new import_server.PlaywrightDispatcher(scope,
|
|
104
|
+
return new import_server.PlaywrightDispatcher(scope, this._playwright, { socksProxy: ownedSocksProxy, preLaunchedBrowser: browser, denyLaunch: true });
|
|
110
105
|
}
|
|
111
106
|
async _initPreLaunchedBrowserMode(scope, options) {
|
|
112
107
|
import_debugLogger.debugLogger.log("server", `[${this._id}] engaged pre-launched (browser) mode`);
|
|
113
|
-
const playwright = this._preLaunched.playwright;
|
|
114
108
|
this._preLaunched.socksProxy?.setPattern(this._options.socksProxyPattern);
|
|
115
109
|
const browser = this._preLaunched.browser;
|
|
116
110
|
browser.options.sdkLanguage = options.sdkLanguage;
|
|
117
111
|
browser.on(import_browser.Browser.Events.Disconnected, () => {
|
|
118
112
|
this.close({ code: 1001, reason: "Browser closed" });
|
|
119
113
|
});
|
|
120
|
-
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope,
|
|
114
|
+
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope, this._playwright, {
|
|
121
115
|
socksProxy: this._preLaunched.socksProxy,
|
|
122
116
|
preLaunchedBrowser: browser,
|
|
123
|
-
sharedBrowser: this._options.sharedBrowser
|
|
117
|
+
sharedBrowser: this._options.sharedBrowser,
|
|
118
|
+
denyLaunch: true
|
|
124
119
|
});
|
|
125
|
-
for (const b of
|
|
120
|
+
for (const b of this._playwright.allBrowsers()) {
|
|
126
121
|
if (b !== browser)
|
|
127
122
|
await b.close({ reason: "Connection terminated" });
|
|
128
123
|
}
|
|
@@ -131,38 +126,35 @@ class PlaywrightConnection {
|
|
|
131
126
|
}
|
|
132
127
|
async _initPreLaunchedAndroidMode(scope) {
|
|
133
128
|
import_debugLogger.debugLogger.log("server", `[${this._id}] engaged pre-launched (Android) mode`);
|
|
134
|
-
const playwright = this._preLaunched.playwright;
|
|
135
129
|
const androidDevice = this._preLaunched.androidDevice;
|
|
136
130
|
androidDevice.on(import_android.AndroidDevice.Events.Close, () => {
|
|
137
131
|
this.close({ code: 1001, reason: "Android device disconnected" });
|
|
138
132
|
});
|
|
139
|
-
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope,
|
|
133
|
+
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope, this._playwright, { preLaunchedAndroidDevice: androidDevice, denyLaunch: true });
|
|
140
134
|
this._cleanups.push(() => playwrightDispatcher.cleanup());
|
|
141
135
|
return playwrightDispatcher;
|
|
142
136
|
}
|
|
143
137
|
_initDebugControllerMode() {
|
|
144
138
|
import_debugLogger.debugLogger.log("server", `[${this._id}] engaged reuse controller mode`);
|
|
145
|
-
|
|
146
|
-
return new import_debugControllerDispatcher.DebugControllerDispatcher(this._dispatcherConnection, playwright.debugController);
|
|
139
|
+
return new import_debugControllerDispatcher.DebugControllerDispatcher(this._dispatcherConnection, this._playwright.debugController);
|
|
147
140
|
}
|
|
148
141
|
async _initReuseBrowsersMode(scope, options) {
|
|
149
142
|
import_debugLogger.debugLogger.log("server", `[${this._id}] engaged reuse browsers mode for ${this._options.browserName}`);
|
|
150
|
-
const playwright = this._preLaunched.playwright;
|
|
151
143
|
const requestedOptions = launchOptionsHash(this._options.launchOptions);
|
|
152
|
-
let browser =
|
|
144
|
+
let browser = this._playwright.allBrowsers().find((b) => {
|
|
153
145
|
if (b.options.name !== this._options.browserName)
|
|
154
146
|
return false;
|
|
155
147
|
const existingOptions = launchOptionsHash(b.options.originalLaunchOptions);
|
|
156
148
|
return existingOptions === requestedOptions;
|
|
157
149
|
});
|
|
158
|
-
for (const b of
|
|
150
|
+
for (const b of this._playwright.allBrowsers()) {
|
|
159
151
|
if (b === browser)
|
|
160
152
|
continue;
|
|
161
153
|
if (b.options.name === this._options.browserName && b.options.channel === this._options.launchOptions.channel)
|
|
162
154
|
await b.close({ reason: "Connection terminated" });
|
|
163
155
|
}
|
|
164
156
|
if (!browser) {
|
|
165
|
-
browser = await
|
|
157
|
+
browser = await this._playwright[this._options.browserName || "chromium"].launch((0, import_instrumentation.serverSideCallMetadata)(), {
|
|
166
158
|
...this._options.launchOptions,
|
|
167
159
|
headless: !!process.env.PW_DEBUG_CONTROLLER_HEADLESS
|
|
168
160
|
});
|
|
@@ -172,7 +164,7 @@ class PlaywrightConnection {
|
|
|
172
164
|
}
|
|
173
165
|
browser.options.sdkLanguage = options.sdkLanguage;
|
|
174
166
|
this._cleanups.push(async () => {
|
|
175
|
-
for (const browser2 of
|
|
167
|
+
for (const browser2 of this._playwright.allBrowsers()) {
|
|
176
168
|
for (const context of browser2.contexts()) {
|
|
177
169
|
if (!context.pages().length)
|
|
178
170
|
await context.close({ reason: "Connection terminated" });
|
|
@@ -183,7 +175,7 @@ class PlaywrightConnection {
|
|
|
183
175
|
await browser2.close({ reason: "Connection terminated" });
|
|
184
176
|
}
|
|
185
177
|
});
|
|
186
|
-
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope,
|
|
178
|
+
const playwrightDispatcher = new import_server.PlaywrightDispatcher(scope, this._playwright, { preLaunchedBrowser: browser, denyLaunch: true });
|
|
187
179
|
return playwrightDispatcher;
|
|
188
180
|
}
|
|
189
181
|
async _createOwnedSocksProxy() {
|
|
@@ -23,7 +23,6 @@ __export(playwrightServer_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(playwrightServer_exports);
|
|
24
24
|
var import_playwrightConnection = require("./playwrightConnection");
|
|
25
25
|
var import_playwright = require("../server/playwright");
|
|
26
|
-
var import_debugLogger = require("../server/utils/debugLogger");
|
|
27
26
|
var import_semaphore = require("../utils/isomorphic/semaphore");
|
|
28
27
|
var import_time = require("../utils/isomorphic/time");
|
|
29
28
|
var import_wsServer = require("../server/utils/wsServer");
|
|
@@ -33,9 +32,10 @@ class PlaywrightServer {
|
|
|
33
32
|
constructor(options) {
|
|
34
33
|
this._options = options;
|
|
35
34
|
if (options.preLaunchedBrowser)
|
|
36
|
-
this.
|
|
35
|
+
this._playwright = options.preLaunchedBrowser.attribution.playwright;
|
|
37
36
|
if (options.preLaunchedAndroidDevice)
|
|
38
|
-
this.
|
|
37
|
+
this._playwright = options.preLaunchedAndroidDevice._android.attribution.playwright;
|
|
38
|
+
this._playwright ??= (0, import_playwright.createPlaywright)({ sdkLanguage: "javascript", isServer: true });
|
|
39
39
|
const browserSemaphore = new import_semaphore.Semaphore(this._options.maxConnections);
|
|
40
40
|
const controllerSemaphore = new import_semaphore.Semaphore(1);
|
|
41
41
|
const reuseBrowserSemaphore = new import_semaphore.Semaphore(1);
|
|
@@ -75,10 +75,6 @@ ${uaError}` };
|
|
|
75
75
|
} catch (e) {
|
|
76
76
|
}
|
|
77
77
|
const isExtension = this._options.mode === "extension";
|
|
78
|
-
if (isExtension) {
|
|
79
|
-
if (!this._preLaunchedPlaywright)
|
|
80
|
-
this._preLaunchedPlaywright = (0, import_playwright.createPlaywright)({ sdkLanguage: "javascript", isServer: true });
|
|
81
|
-
}
|
|
82
78
|
let clientType = "launch-browser";
|
|
83
79
|
let semaphore = browserSemaphore;
|
|
84
80
|
if (isExtension && url.searchParams.has("debug-controller")) {
|
|
@@ -102,8 +98,8 @@ ${uaError}` };
|
|
|
102
98
|
allowFSPaths: this._options.mode === "extension",
|
|
103
99
|
sharedBrowser: this._options.mode === "launchServerShared"
|
|
104
100
|
},
|
|
101
|
+
this._playwright,
|
|
105
102
|
{
|
|
106
|
-
playwright: this._preLaunchedPlaywright,
|
|
107
103
|
browser: this._options.preLaunchedBrowser,
|
|
108
104
|
androidDevice: this._options.preLaunchedAndroidDevice,
|
|
109
105
|
socksProxy: this._options.preLaunchedSocksProxy
|
|
@@ -111,12 +107,6 @@ ${uaError}` };
|
|
|
111
107
|
id,
|
|
112
108
|
() => semaphore.release()
|
|
113
109
|
);
|
|
114
|
-
},
|
|
115
|
-
onClose: async () => {
|
|
116
|
-
import_debugLogger.debugLogger.log("server", "closing browsers");
|
|
117
|
-
if (this._preLaunchedPlaywright)
|
|
118
|
-
await Promise.all(this._preLaunchedPlaywright.allBrowsers().map((browser) => browser.close({ reason: "Playwright Server stopped" })));
|
|
119
|
-
import_debugLogger.debugLogger.log("server", "closed browsers");
|
|
120
110
|
}
|
|
121
111
|
});
|
|
122
112
|
}
|
|
@@ -29,9 +29,10 @@ var import_android = require("../android/android");
|
|
|
29
29
|
var import_eventsHelper = require("../utils/eventsHelper");
|
|
30
30
|
var import_instrumentation = require("../instrumentation");
|
|
31
31
|
class AndroidDispatcher extends import_dispatcher.Dispatcher {
|
|
32
|
-
constructor(scope, android) {
|
|
32
|
+
constructor(scope, android, denyLaunch) {
|
|
33
33
|
super(scope, android, "Android", {});
|
|
34
34
|
this._type_Android = true;
|
|
35
|
+
this._denyLaunch = denyLaunch;
|
|
35
36
|
}
|
|
36
37
|
async devices(params) {
|
|
37
38
|
const devices = await this._object.devices(params);
|
|
@@ -136,6 +137,8 @@ class AndroidDeviceDispatcher extends import_dispatcher.Dispatcher {
|
|
|
136
137
|
await this._object.push(params.file, params.path, params.mode);
|
|
137
138
|
}
|
|
138
139
|
async launchBrowser(params) {
|
|
140
|
+
if (this.parentScope()._denyLaunch)
|
|
141
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
139
142
|
const context = await this._object.launchBrowser(params.pkg, params);
|
|
140
143
|
return { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, context) };
|
|
141
144
|
}
|
|
@@ -143,6 +146,8 @@ class AndroidDeviceDispatcher extends import_dispatcher.Dispatcher {
|
|
|
143
146
|
await this._object.close();
|
|
144
147
|
}
|
|
145
148
|
async connectToWebView(params) {
|
|
149
|
+
if (this.parentScope()._denyLaunch)
|
|
150
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
146
151
|
return { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, await this._object.connectToWebView(params.socketName)) };
|
|
147
152
|
}
|
|
148
153
|
}
|
|
@@ -25,24 +25,31 @@ var import_browserContextDispatcher = require("./browserContextDispatcher");
|
|
|
25
25
|
var import_browserDispatcher = require("./browserDispatcher");
|
|
26
26
|
var import_dispatcher = require("./dispatcher");
|
|
27
27
|
class BrowserTypeDispatcher extends import_dispatcher.Dispatcher {
|
|
28
|
-
constructor(scope, browserType) {
|
|
28
|
+
constructor(scope, browserType, denyLaunch) {
|
|
29
29
|
super(scope, browserType, "BrowserType", {
|
|
30
30
|
executablePath: browserType.executablePath(),
|
|
31
31
|
name: browserType.name()
|
|
32
32
|
});
|
|
33
33
|
this._type_BrowserType = true;
|
|
34
|
+
this._denyLaunch = denyLaunch;
|
|
34
35
|
}
|
|
35
36
|
async launch(params, metadata) {
|
|
37
|
+
if (this._denyLaunch)
|
|
38
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
36
39
|
const browser = await this._object.launch(metadata, params);
|
|
37
40
|
return { browser: new import_browserDispatcher.BrowserDispatcher(this, browser) };
|
|
38
41
|
}
|
|
39
42
|
async launchPersistentContext(params, metadata) {
|
|
43
|
+
if (this._denyLaunch)
|
|
44
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
40
45
|
const browserContext = await this._object.launchPersistentContext(metadata, params.userDataDir, params);
|
|
41
46
|
const browserDispatcher = new import_browserDispatcher.BrowserDispatcher(this, browserContext._browser);
|
|
42
47
|
const contextDispatcher = import_browserContextDispatcher.BrowserContextDispatcher.from(browserDispatcher, browserContext);
|
|
43
48
|
return { browser: browserDispatcher, context: contextDispatcher };
|
|
44
49
|
}
|
|
45
50
|
async connectOverCDP(params, metadata) {
|
|
51
|
+
if (this._denyLaunch)
|
|
52
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
46
53
|
const browser = await this._object.connectOverCDP(metadata, params.endpointURL, params);
|
|
47
54
|
const browserDispatcher = new import_browserDispatcher.BrowserDispatcher(this, browser);
|
|
48
55
|
return {
|
|
@@ -27,11 +27,14 @@ var import_dispatcher = require("./dispatcher");
|
|
|
27
27
|
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
|
28
28
|
var import_electron = require("../electron/electron");
|
|
29
29
|
class ElectronDispatcher extends import_dispatcher.Dispatcher {
|
|
30
|
-
constructor(scope, electron) {
|
|
30
|
+
constructor(scope, electron, denyLaunch) {
|
|
31
31
|
super(scope, electron, "Electron", {});
|
|
32
32
|
this._type_Electron = true;
|
|
33
|
+
this._denyLaunch = denyLaunch;
|
|
33
34
|
}
|
|
34
35
|
async launch(params) {
|
|
36
|
+
if (this._denyLaunch)
|
|
37
|
+
throw new Error(`Launching more browsers is not allowed.`);
|
|
35
38
|
const electronApplication = await this._object.launch(params);
|
|
36
39
|
return { electronApplication: new ElectronApplicationDispatcher(this, electronApplication) };
|
|
37
40
|
}
|
|
@@ -35,12 +35,13 @@ var import_instrumentation = require("../instrumentation");
|
|
|
35
35
|
var import_eventsHelper = require("../utils/eventsHelper");
|
|
36
36
|
class PlaywrightDispatcher extends import_dispatcher.Dispatcher {
|
|
37
37
|
constructor(scope, playwright, options = {}) {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
38
|
+
const denyLaunch = options.denyLaunch ?? false;
|
|
39
|
+
const chromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium, denyLaunch);
|
|
40
|
+
const firefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox, denyLaunch);
|
|
41
|
+
const webkit = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit, denyLaunch);
|
|
42
|
+
const bidiChromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiChromium, denyLaunch);
|
|
43
|
+
const bidiFirefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiFirefox, denyLaunch);
|
|
44
|
+
const android = new import_androidDispatcher.AndroidDispatcher(scope, playwright.android, denyLaunch);
|
|
44
45
|
const initializer = {
|
|
45
46
|
chromium,
|
|
46
47
|
firefox,
|
|
@@ -48,7 +49,7 @@ class PlaywrightDispatcher extends import_dispatcher.Dispatcher {
|
|
|
48
49
|
bidiChromium,
|
|
49
50
|
bidiFirefox,
|
|
50
51
|
android,
|
|
51
|
-
electron: new import_electronDispatcher.ElectronDispatcher(scope, playwright.electron),
|
|
52
|
+
electron: new import_electronDispatcher.ElectronDispatcher(scope, playwright.electron, denyLaunch),
|
|
52
53
|
utils: playwright.options.isServer ? void 0 : new import_localUtilsDispatcher.LocalUtilsDispatcher(scope, playwright),
|
|
53
54
|
socksSupport: options.socksProxy ? new SocksSupportDispatcher(scope, playwright, options.socksProxy) : void 0
|
|
54
55
|
};
|
|
@@ -112,7 +112,6 @@ class WSServer {
|
|
|
112
112
|
this._wsServer = void 0;
|
|
113
113
|
this.server = void 0;
|
|
114
114
|
import_debugLogger.debugLogger.log("server", "closed server");
|
|
115
|
-
await this._delegate.onClose?.();
|
|
116
115
|
}
|
|
117
116
|
}
|
|
118
117
|
// Annotate the CommonJS export names for ESM import in node:
|