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.
@@ -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 playwright[browserName].launch((0, import_instrumentation.serverSideCallMetadata)(), this._options.launchOptions);
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(async () => {
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, playwright, { socksProxy: ownedSocksProxy, preLaunchedBrowser: browser });
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, playwright, {
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 playwright.allBrowsers()) {
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, playwright, { preLaunchedAndroidDevice: androidDevice });
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
- const playwright = this._preLaunched.playwright;
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 = playwright.allBrowsers().find((b) => {
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 playwright.allBrowsers()) {
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 playwright[this._options.browserName || "chromium"].launch((0, import_instrumentation.serverSideCallMetadata)(), {
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 playwright.allBrowsers()) {
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, playwright, { preLaunchedBrowser: browser });
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._preLaunchedPlaywright = options.preLaunchedBrowser.attribution.playwright;
35
+ this._playwright = options.preLaunchedBrowser.attribution.playwright;
37
36
  if (options.preLaunchedAndroidDevice)
38
- this._preLaunchedPlaywright = options.preLaunchedAndroidDevice._android.attribution.playwright;
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 chromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium);
39
- const firefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox);
40
- const webkit = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit);
41
- const bidiChromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiChromium);
42
- const bidiFirefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.bidiFirefox);
43
- const android = new import_androidDispatcher.AndroidDispatcher(scope, playwright.android);
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:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright-core",
3
- "version": "1.54.0-alpha-2025-06-19",
3
+ "version": "1.54.0-alpha-2025-06-20",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",