playwright-core 1.56.0-alpha-2025-09-09 → 1.56.0-alpha-1757456950000

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.
@@ -0,0 +1,35 @@
1
+ $ErrorActionPreference = 'Stop'
2
+
3
+ # WebKit WSL Installation Script
4
+ # See webkit-wsl-transport-server.ts for the complete architecture diagram.
5
+ # This script sets up a WSL distribution that will be used to run WebKit.
6
+
7
+ $Distribution = "playwright"
8
+ $Username = "pwuser"
9
+
10
+ $distributions = (wsl --list --quiet) -split "\r?\n"
11
+ if ($distributions -contains $Distribution) {
12
+ Write-Host "WSL distribution '$Distribution' already exists. Skipping installation."
13
+ } else {
14
+ Write-Host "Installing new WSL distribution '$Distribution'..."
15
+ $VhdSize = "10GB"
16
+ wsl --install -d Ubuntu-24.04 --name $Distribution --no-launch --vhd-size $VhdSize
17
+ wsl -d $Distribution -u root adduser --gecos GECOS --disabled-password $Username
18
+ }
19
+
20
+ $pwshDirname = (Resolve-Path -Path $PSScriptRoot).Path;
21
+ $playwrightCoreRoot = Resolve-Path (Join-Path $pwshDirname "..")
22
+
23
+ $initScript = @"
24
+ if [ ! -f "/home/$Username/node/bin/node" ]; then
25
+ mkdir -p /home/$Username/node
26
+ curl -fsSL https://nodejs.org/dist/v22.17.0/node-v22.17.0-linux-x64.tar.xz -o /home/$Username/node/node-v22.17.0-linux-x64.tar.xz
27
+ tar -xJf /home/$Username/node/node-v22.17.0-linux-x64.tar.xz -C /home/$Username/node --strip-components=1
28
+ fi
29
+ /home/$Username/node/bin/node cli.js install-deps webkit
30
+ cp lib/server/webkit/wsl/webkit-wsl-transport-client.js /home/$Username/
31
+ sudo -u $Username PLAYWRIGHT_SKIP_BROWSER_GC=1 /home/$Username/node/bin/node cli.js install webkit
32
+ "@ -replace "\r\n", "`n"
33
+
34
+ wsl -d $Distribution --cd $playwrightCoreRoot -u root -- bash -c "$initScript"
35
+ Write-Host "Done!"
@@ -86,7 +86,7 @@ class BidiChromium extends import_browserType.BrowserType {
86
86
  supportsPipeTransport() {
87
87
  return false;
88
88
  }
89
- defaultArgs(options, isPersistent, userDataDir) {
89
+ async defaultArgs(options, isPersistent, userDataDir) {
90
90
  const chromeArguments = this._innerDefaultArgs(options);
91
91
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
92
92
  chromeArguments.push("--remote-debugging-port=0");
@@ -85,7 +85,7 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
85
85
  preferences: options.firefoxUserPrefs || {}
86
86
  });
87
87
  }
88
- defaultArgs(options, isPersistent, userDataDir) {
88
+ async defaultArgs(options, isPersistent, userDataDir) {
89
89
  const { args = [], headless } = options;
90
90
  const userDataDirArg = args.find((arg) => arg.startsWith("-profile") || arg.startsWith("--profile"));
91
91
  if (userDataDirArg)
@@ -148,7 +148,7 @@ class BidiNetworkManager {
148
148
  _onAuthRequired(params) {
149
149
  const isBasic = params.response.authChallenges?.some((challenge) => challenge.scheme.startsWith("Basic"));
150
150
  const credentials = this._page.browserContext._options.httpCredentials;
151
- if (isBasic && credentials) {
151
+ if (isBasic && credentials && (!credentials.origin || new URL(params.request.url).origin.toLowerCase() === credentials.origin.toLowerCase())) {
152
152
  if (this._attemptedAuthentications.has(params.request.request)) {
153
153
  this._session.sendMayFail("network.continueWithAuth", {
154
154
  request: params.request.request,
@@ -169,7 +169,7 @@ class BidiNetworkManager {
169
169
  } else {
170
170
  this._session.sendMayFail("network.continueWithAuth", {
171
171
  request: params.request.request,
172
- action: "default"
172
+ action: "cancel"
173
173
  });
174
174
  }
175
175
  }
@@ -169,9 +169,9 @@ class BrowserType extends import_instrumentation.SdkObject {
169
169
  if (ignoreAllDefaultArgs)
170
170
  browserArguments.push(...args);
171
171
  else if (ignoreDefaultArgs)
172
- browserArguments.push(...this.defaultArgs(options, isPersistent, userDataDir).filter((arg) => ignoreDefaultArgs.indexOf(arg) === -1));
172
+ browserArguments.push(...(await this.defaultArgs(options, isPersistent, userDataDir)).filter((arg) => ignoreDefaultArgs.indexOf(arg) === -1));
173
173
  else
174
- browserArguments.push(...this.defaultArgs(options, isPersistent, userDataDir));
174
+ browserArguments.push(...await this.defaultArgs(options, isPersistent, userDataDir));
175
175
  let executable;
176
176
  if (executablePath) {
177
177
  if (!await (0, import_fileUtils.existsAsync)(executablePath))
@@ -200,7 +200,7 @@ class BrowserType extends import_instrumentation.SdkObject {
200
200
  const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
201
201
  command: prepared.executable,
202
202
  args: prepared.browserArguments,
203
- env: this.amendEnvironment(env, prepared.userDataDir, isPersistent),
203
+ env: this.amendEnvironment(env, prepared.userDataDir, isPersistent, options),
204
204
  handleSIGINT,
205
205
  handleSIGTERM,
206
206
  handleSIGHUP,
@@ -250,7 +250,7 @@ class Chromium extends import_browserType.BrowserType {
250
250
  throw e;
251
251
  }
252
252
  }
253
- defaultArgs(options, isPersistent, userDataDir) {
253
+ async defaultArgs(options, isPersistent, userDataDir) {
254
254
  const chromeArguments = this._innerDefaultArgs(options);
255
255
  chromeArguments.push(`--user-data-dir=${userDataDir}`);
256
256
  if (options.cdpPort !== void 0)
@@ -67,7 +67,7 @@ Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ?
67
67
  const message = { method: "Browser.close", params: {}, id: import_ffConnection.kBrowserCloseMessageId };
68
68
  transport.send(message);
69
69
  }
70
- defaultArgs(options, isPersistent, userDataDir) {
70
+ async defaultArgs(options, isPersistent, userDataDir) {
71
71
  const { args = [], headless } = options;
72
72
  const userDataDirArg = args.find((arg) => arg.startsWith("-profile") || arg.startsWith("--profile"));
73
73
  if (userDataDirArg)
@@ -749,6 +749,33 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
749
749
  _dependencyGroup: "webkit",
750
750
  _isHermeticInstallation: true
751
751
  });
752
+ this._executables.push({
753
+ type: "channel",
754
+ name: "webkit-wsl",
755
+ browserName: "webkit",
756
+ directory: webkit.dir,
757
+ executablePath: () => process.execPath,
758
+ executablePathOrDie: () => process.execPath,
759
+ wslExecutablePath: `/home/pwuser/.cache/ms-playwright/webkit-${webkit.revision}/pw_run.sh`,
760
+ installType: "download-on-demand",
761
+ _validateHostRequirements: (sdkLanguage) => Promise.resolve(),
762
+ _isHermeticInstallation: true,
763
+ _install: async () => {
764
+ if (process.platform !== "win32")
765
+ throw new Error(`WebKit via WSL is only supported on Windows`);
766
+ const script = import_path.default.join(BIN_PATH, "install_webkit_wsl.ps1");
767
+ const { code } = await (0, import_spawnAsync.spawnAsync)("powershell.exe", [
768
+ "-ExecutionPolicy",
769
+ "Bypass",
770
+ "-File",
771
+ script
772
+ ], {
773
+ stdio: "inherit"
774
+ });
775
+ if (code !== 0)
776
+ throw new Error(`Failed to install WebKit via WSL`);
777
+ }
778
+ });
752
779
  const ffmpeg = descriptors.find((d) => d.name === "ffmpeg");
753
780
  const ffmpegExecutable = findExecutablePath(ffmpeg.dir, "ffmpeg");
754
781
  this._executables.push({
@@ -28,7 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var webkit_exports = {};
30
30
  __export(webkit_exports, {
31
- WebKit: () => WebKit
31
+ WebKit: () => WebKit,
32
+ translatePathToWSL: () => translatePathToWSL
32
33
  });
33
34
  module.exports = __toCommonJS(webkit_exports);
34
35
  var import_path = __toESM(require("path"));
@@ -36,6 +37,8 @@ var import_wkConnection = require("./wkConnection");
36
37
  var import_ascii = require("../utils/ascii");
37
38
  var import_browserType = require("../browserType");
38
39
  var import_wkBrowser = require("../webkit/wkBrowser");
40
+ var import_spawnAsync = require("../utils/spawnAsync");
41
+ var import_registry = require("../registry");
39
42
  class WebKit extends import_browserType.BrowserType {
40
43
  constructor(parent) {
41
44
  super(parent, "webkit");
@@ -43,10 +46,11 @@ class WebKit extends import_browserType.BrowserType {
43
46
  connectToTransport(transport, options) {
44
47
  return import_wkBrowser.WKBrowser.connect(this.attribution.playwright, transport, options);
45
48
  }
46
- amendEnvironment(env, userDataDir, isPersistent) {
49
+ amendEnvironment(env, userDataDir, isPersistent, options) {
47
50
  return {
48
51
  ...env,
49
- CURL_COOKIE_JAR_PATH: process.platform === "win32" && isPersistent ? import_path.default.join(userDataDir, "cookiejar.db") : void 0
52
+ CURL_COOKIE_JAR_PATH: process.platform === "win32" && isPersistent ? import_path.default.join(userDataDir, "cookiejar.db") : void 0,
53
+ WEBKIT_EXECUTABLE: options.channel === "webkit-wsl" ? import_registry.registry.findExecutable("webkit-wsl").wslExecutablePath : void 0
50
54
  };
51
55
  }
52
56
  doRewriteStartupLog(error) {
@@ -59,7 +63,7 @@ class WebKit extends import_browserType.BrowserType {
59
63
  attemptToGracefullyCloseBrowser(transport) {
60
64
  transport.send({ method: "Playwright.close", params: {}, id: import_wkConnection.kBrowserCloseMessageId });
61
65
  }
62
- defaultArgs(options, isPersistent, userDataDir) {
66
+ async defaultArgs(options, isPersistent, userDataDir) {
63
67
  const { args = [], headless } = options;
64
68
  const userDataDirArg = args.find((arg) => arg.startsWith("--user-data-dir"));
65
69
  if (userDataDirArg)
@@ -67,12 +71,19 @@ class WebKit extends import_browserType.BrowserType {
67
71
  if (args.find((arg) => !arg.startsWith("-")))
68
72
  throw new Error("Arguments can not specify page to be opened");
69
73
  const webkitArguments = ["--inspector-pipe"];
70
- if (process.platform === "win32")
74
+ if (options.channel === "webkit-wsl") {
75
+ if (options.executablePath)
76
+ throw new Error('Cannot specify executablePath when using the "webkit-wsl" channel.');
77
+ webkitArguments.unshift(
78
+ import_path.default.join(__dirname, "wsl/webkit-wsl-transport-server.js")
79
+ );
80
+ }
81
+ if (process.platform === "win32" && options.channel !== "webkit-wsl")
71
82
  webkitArguments.push("--disable-accelerated-compositing");
72
83
  if (headless)
73
84
  webkitArguments.push("--headless");
74
85
  if (isPersistent)
75
- webkitArguments.push(`--user-data-dir=${userDataDir}`);
86
+ webkitArguments.push(`--user-data-dir=${options.channel === "webkit-wsl" ? await translatePathToWSL(userDataDir) : userDataDir}`);
76
87
  else
77
88
  webkitArguments.push(`--no-startup-window`);
78
89
  const proxy = options.proxyOverride || options.proxy;
@@ -81,7 +92,7 @@ class WebKit extends import_browserType.BrowserType {
81
92
  webkitArguments.push(`--proxy=${proxy.server}`);
82
93
  if (proxy.bypass)
83
94
  webkitArguments.push(`--proxy-bypass-list=${proxy.bypass}`);
84
- } else if (process.platform === "linux") {
95
+ } else if (process.platform === "linux" || process.platform === "win32" && options.channel === "webkit-wsl") {
85
96
  webkitArguments.push(`--proxy=${proxy.server}`);
86
97
  if (proxy.bypass)
87
98
  webkitArguments.push(...proxy.bypass.split(",").map((t) => `--ignore-host=${t}`));
@@ -97,7 +108,12 @@ class WebKit extends import_browserType.BrowserType {
97
108
  return webkitArguments;
98
109
  }
99
110
  }
111
+ async function translatePathToWSL(path2) {
112
+ const { stdout } = await (0, import_spawnAsync.spawnAsync)("wsl.exe", ["-d", "playwright", "--cd", "/home/pwuser", "wslpath", path2.replace(/\\/g, "\\\\")]);
113
+ return stdout.toString().trim();
114
+ }
100
115
  // Annotate the CommonJS export names for ESM import in node:
101
116
  0 && (module.exports = {
102
- WebKit
117
+ WebKit,
118
+ translatePathToWSL
103
119
  });
@@ -39,6 +39,7 @@ var network = __toESM(require("../network"));
39
39
  var import_wkConnection = require("./wkConnection");
40
40
  var import_wkPage = require("./wkPage");
41
41
  var import_errors = require("../errors");
42
+ var import_webkit = require("./webkit");
42
43
  const BROWSER_VERSION = "26.0";
43
44
  const DEFAULT_USER_AGENT = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/${BROWSER_VERSION} Safari/605.1.15`;
44
45
  class WKBrowser extends import_browser.Browser {
@@ -87,7 +88,7 @@ class WKBrowser extends import_browser.Browser {
87
88
  const createOptions = proxy ? {
88
89
  // Enable socks5 hostname resolution on Windows.
89
90
  // See https://github.com/microsoft/playwright/issues/20451
90
- proxyServer: process.platform === "win32" ? proxy.server.replace(/^socks5:\/\//, "socks5h://") : proxy.server,
91
+ proxyServer: process.platform === "win32" && this.attribution.browser?.options.channel !== "webkit-wsl" ? proxy.server.replace(/^socks5:\/\//, "socks5h://") : proxy.server,
91
92
  proxyBypassList: proxy.bypass
92
93
  } : void 0;
93
94
  const { browserContextId } = await this._browserSession.send("Playwright.createContext", createOptions);
@@ -192,7 +193,7 @@ class WKBrowserContext extends import_browserContext.BrowserContext {
192
193
  const promises = [super._initialize()];
193
194
  promises.push(this._browser._browserSession.send("Playwright.setDownloadBehavior", {
194
195
  behavior: this._options.acceptDownloads === "accept" ? "allow" : "deny",
195
- downloadPath: this._browser.options.downloadsPath,
196
+ downloadPath: this._browser.options.channel === "webkit-wsl" ? await (0, import_webkit.translatePathToWSL)(this._browser.options.downloadsPath) : this._browser.options.downloadsPath,
196
197
  browserContextId
197
198
  }));
198
199
  if (this._options.ignoreHTTPSErrors || this._options.internalIgnoreHTTPSErrors)
@@ -54,6 +54,7 @@ var import_wkInterceptableRequest = require("./wkInterceptableRequest");
54
54
  var import_wkProvisionalPage = require("./wkProvisionalPage");
55
55
  var import_wkWorkers = require("./wkWorkers");
56
56
  var import_debugLogger = require("../utils/debugLogger");
57
+ var import_webkit = require("./webkit");
57
58
  const UTILITY_WORLD_NAME = "__playwright_utility_world__";
58
59
  class WKPage {
59
60
  constructor(browserContext, pageProxySession, opener) {
@@ -769,7 +770,7 @@ class WKPage {
769
770
  async _startVideo(options) {
770
771
  (0, import_utils.assert)(!this._recordingVideoFile);
771
772
  const { screencastId } = await this._pageProxySession.send("Screencast.startVideo", {
772
- file: options.outputFile,
773
+ file: this._browserContext._browser.options.channel === "webkit-wsl" ? await (0, import_webkit.translatePathToWSL)(options.outputFile) : options.outputFile,
773
774
  width: options.width,
774
775
  height: options.height,
775
776
  toolbarHeight: this._toolbarHeight()
@@ -889,6 +890,8 @@ class WKPage {
889
890
  async setInputFilePaths(handle, paths) {
890
891
  const pageProxyId = this._pageProxySession.sessionId;
891
892
  const objectId = handle._objectId;
893
+ if (this._browserContext._browser?.options.channel === "webkit-wsl")
894
+ paths = await Promise.all(paths.map((path2) => (0, import_webkit.translatePathToWSL)(path2)));
892
895
  await Promise.all([
893
896
  this._pageProxySession.connection.browserSession.send("Playwright.grantFileReadAccess", { pageProxyId, paths }),
894
897
  this._session.send("DOM.setInputFiles", { objectId, paths })
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var import_net = __toESM(require("net"));
25
+ var import_fs = __toESM(require("fs"));
26
+ var import_child_process = require("child_process");
27
+ (async () => {
28
+ const { PW_WSL_BRIDGE_PORT: socketPort, ...childEnv } = process.env;
29
+ if (!socketPort)
30
+ throw new Error("PW_WSL_BRIDGE_PORT env var is not set");
31
+ const [executable, ...args] = process.argv.slice(2);
32
+ if (!(await import_fs.default.promises.stat(executable)).isFile())
33
+ throw new Error(`Executable does not exist. Did you update Playwright recently? Make sure to run npx playwright install webkit-wsl`);
34
+ const address = (() => {
35
+ const res = (0, import_child_process.spawnSync)("/usr/bin/wslinfo", ["--networking-mode"], { encoding: "utf8" });
36
+ if (res.error || res.status !== 0)
37
+ throw new Error(`Failed to run /usr/bin/wslinfo --networking-mode: ${res.error?.message || res.stderr || res.status}`);
38
+ if (res.stdout.trim() === "nat") {
39
+ const ipRes = (0, import_child_process.spawnSync)("/usr/sbin/ip", ["route", "show"], { encoding: "utf8" });
40
+ if (ipRes.error || ipRes.status !== 0)
41
+ throw new Error(`Failed to run ip route show: ${ipRes.error?.message || ipRes.stderr || ipRes.status}`);
42
+ const ip = ipRes.stdout.trim().split("\n").find((line) => line.includes("default"))?.split(" ")[2];
43
+ if (!ip)
44
+ throw new Error("Could not determine WSL IP address (NAT mode).");
45
+ return ip;
46
+ }
47
+ return "127.0.0.1";
48
+ })();
49
+ const socket = import_net.default.createConnection(parseInt(socketPort, 10), address);
50
+ socket.setNoDelay(true);
51
+ await new Promise((resolve, reject) => {
52
+ socket.on("connect", resolve);
53
+ socket.on("error", reject);
54
+ });
55
+ const child = (0, import_child_process.spawn)(executable, args, {
56
+ stdio: ["inherit", "inherit", "inherit", "pipe", "pipe"],
57
+ env: childEnv
58
+ });
59
+ const [childOutput, childInput] = [child.stdio[3], child.stdio[4]];
60
+ socket.pipe(childOutput);
61
+ childInput.pipe(socket);
62
+ socket.on("end", () => child.kill());
63
+ child.on("exit", (exitCode) => {
64
+ socket.end();
65
+ process.exit(exitCode || 0);
66
+ });
67
+ await new Promise((resolve, reject) => {
68
+ child.on("exit", resolve);
69
+ child.on("error", reject);
70
+ });
71
+ })().catch((error) => {
72
+ console.error("Error occurred:", error);
73
+ process.exit(1);
74
+ });
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var import_net = __toESM(require("net"));
25
+ var import_path = __toESM(require("path"));
26
+ var import_child_process = require("child_process");
27
+ (async () => {
28
+ const argv = process.argv.slice(2);
29
+ if (!argv.length) {
30
+ console.error(`Usage: node ${import_path.default.basename(__filename)} <executable> [args...]`);
31
+ process.exit(1);
32
+ }
33
+ const parentIn = new import_net.default.Socket({ fd: 3, readable: true, writable: false });
34
+ const parentOut = new import_net.default.Socket({ fd: 4, readable: false, writable: true });
35
+ const server = import_net.default.createServer();
36
+ let socket = null;
37
+ server.on("connection", (s) => {
38
+ if (socket) {
39
+ log("Extra connection received, destroying.");
40
+ socket.destroy();
41
+ return;
42
+ }
43
+ socket = s;
44
+ socket.setNoDelay(true);
45
+ log("Client connected, wiring pipes.");
46
+ socket.pipe(parentOut);
47
+ parentIn.pipe(socket);
48
+ socket.on("close", () => {
49
+ log("Socket closed");
50
+ socket = null;
51
+ });
52
+ });
53
+ await new Promise((resolve, reject) => {
54
+ server.once("error", reject);
55
+ server.listen(0, () => resolve(null));
56
+ });
57
+ const address = server.address();
58
+ if (!address || typeof address === "string") {
59
+ console.error("Failed to obtain listening address");
60
+ process.exit(1);
61
+ }
62
+ const port = address.port;
63
+ log("Server listening on", port);
64
+ const env = {
65
+ ...process.env,
66
+ // WSLENV is a colon-delimited list of environment variables that should be included when launching WSL processes from Win32 or Win32 processes from WSL
67
+ WSLENV: "PW_WSL_BRIDGE_PORT",
68
+ PW_WSL_BRIDGE_PORT: String(port)
69
+ };
70
+ let shuttingDown = false;
71
+ const child = (0, import_child_process.spawn)("wsl.exe", [
72
+ "-d",
73
+ "playwright",
74
+ "--cd",
75
+ "/home/pwuser",
76
+ "/home/pwuser/node/bin/node",
77
+ "/home/pwuser/webkit-wsl-transport-client.js",
78
+ process.env.WEBKIT_EXECUTABLE || "",
79
+ ...argv
80
+ ], {
81
+ env,
82
+ stdio: ["inherit", "inherit", "inherit"]
83
+ // no fd3/fd4 here; they stay only in this wrapper
84
+ });
85
+ log("Spawned child pid", child.pid);
86
+ child.on("close", (code, signal) => {
87
+ log("Child exit", { code, signal });
88
+ const exitCode = code ?? (signal ? 128 : 0);
89
+ shutdown(exitCode);
90
+ });
91
+ child.on("error", (err) => {
92
+ console.error("Child process failed to start:", err);
93
+ shutdown(1);
94
+ });
95
+ await new Promise((resolve) => child.once("close", resolve));
96
+ async function shutdown(code = 0) {
97
+ if (shuttingDown)
98
+ return;
99
+ shuttingDown = true;
100
+ server.close();
101
+ parentIn.destroy();
102
+ parentOut.destroy();
103
+ socket?.destroy();
104
+ await new Promise((resolve) => server.once("close", resolve));
105
+ process.exit(code);
106
+ }
107
+ function log(...args) {
108
+ console.error(/* @__PURE__ */ new Date(), `[${import_path.default.basename(__filename)}]`, ...args);
109
+ }
110
+ })().catch((error) => {
111
+ console.error("Error occurred:", error);
112
+ process.exit(1);
113
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright-core",
3
- "version": "1.56.0-alpha-2025-09-09",
3
+ "version": "1.56.0-alpha-1757456950000",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",