TenantAtlas/apps/platform/.pnpm-store/v10/files/f2/c8786e91dd00284635aa9c507403d2a5364abd59298177944b35eb95150250a704ae8d9cd1c0f02eec023d085ad7846c603d19a8ee09519d9560e8e7f0a7d9
Ahmed Darrazi 9f74f7a658
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 51s
feat: compress governance operator outcomes
2026-04-19 14:15:11 +02:00

1396 lines
67 KiB
Plaintext

"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var registry_exports = {};
__export(registry_exports, {
Registry: () => Registry,
browserDirectoryToMarkerFilePath: () => browserDirectoryToMarkerFilePath,
buildPlaywrightCLICommand: () => buildPlaywrightCLICommand,
defaultCacheDirectory: () => defaultCacheDirectory,
defaultRegistryDirectory: () => defaultRegistryDirectory,
findChromiumChannelBestEffort: () => findChromiumChannelBestEffort,
installBrowsersForNpmInstall: () => installBrowsersForNpmInstall,
registry: () => registry,
registryDirectory: () => registryDirectory,
writeDockerVersion: () => import_dependencies3.writeDockerVersion
});
module.exports = __toCommonJS(registry_exports);
var import_fs = __toESM(require("fs"));
var import_os = __toESM(require("os"));
var import_path = __toESM(require("path"));
var util = __toESM(require("util"));
var import_browserFetcher = require("./browserFetcher");
var import_dependencies = require("./dependencies");
var import_dependencies2 = require("./dependencies");
var import_utils = require("../../utils");
var import_ascii = require("../utils/ascii");
var import_debugLogger = require("../utils/debugLogger");
var import_hostPlatform = require("../utils/hostPlatform");
var import_network = require("../utils/network");
var import_spawnAsync = require("../utils/spawnAsync");
var import_userAgent = require("../utils/userAgent");
var import_utilsBundle = require("../../utilsBundle");
var import_fileUtils = require("../utils/fileUtils");
var import_dependencies3 = require("./dependencies");
const PACKAGE_PATH = import_path.default.join(__dirname, "..", "..", "..");
const BIN_PATH = import_path.default.join(__dirname, "..", "..", "..", "bin");
const PLAYWRIGHT_CDN_MIRRORS = [
"https://cdn.playwright.dev/dbazure/download/playwright",
// ESRP CDN
"https://playwright.download.prss.microsoft.com/dbazure/download/playwright",
// Directly hit ESRP CDN
"https://cdn.playwright.dev"
// Hit the Storage Bucket directly
];
if (process.env.PW_TEST_CDN_THAT_SHOULD_WORK) {
for (let i = 0; i < PLAYWRIGHT_CDN_MIRRORS.length; i++) {
const cdn = PLAYWRIGHT_CDN_MIRRORS[i];
if (cdn !== process.env.PW_TEST_CDN_THAT_SHOULD_WORK) {
const parsedCDN = new URL(cdn);
parsedCDN.hostname = parsedCDN.hostname + ".does-not-resolve.playwright.dev";
PLAYWRIGHT_CDN_MIRRORS[i] = parsedCDN.toString();
}
}
}
const EXECUTABLE_PATHS = {
"chromium": {
"<unknown>": void 0,
"linux-x64": ["chrome-linux64", "chrome"],
"linux-arm64": ["chrome-linux", "chrome"],
// non-cft build
"mac-x64": ["chrome-mac-x64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"],
"mac-arm64": ["chrome-mac-arm64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"],
"win-x64": ["chrome-win64", "chrome.exe"]
},
"chromium-headless-shell": {
"<unknown>": void 0,
"linux-x64": ["chrome-headless-shell-linux64", "chrome-headless-shell"],
"linux-arm64": ["chrome-linux", "headless_shell"],
// non-cft build
"mac-x64": ["chrome-headless-shell-mac-x64", "chrome-headless-shell"],
"mac-arm64": ["chrome-headless-shell-mac-arm64", "chrome-headless-shell"],
"win-x64": ["chrome-headless-shell-win64", "chrome-headless-shell.exe"]
},
"chromium-tip-of-tree": {
"<unknown>": void 0,
"linux-x64": ["chrome-linux64", "chrome"],
"linux-arm64": ["chrome-linux", "chrome"],
// non-cft build
"mac-x64": ["chrome-mac-x64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"],
"mac-arm64": ["chrome-mac-arm64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"],
"win-x64": ["chrome-win64", "chrome.exe"]
},
"chromium-tip-of-tree-headless-shell": {
"<unknown>": void 0,
"linux-x64": ["chrome-headless-shell-linux64", "chrome-headless-shell"],
"linux-arm64": ["chrome-linux", "headless_shell"],
// non-cft build
"mac-x64": ["chrome-headless-shell-mac-x64", "chrome-headless-shell"],
"mac-arm64": ["chrome-headless-shell-mac-arm64", "chrome-headless-shell"],
"win-x64": ["chrome-headless-shell-win64", "chrome-headless-shell.exe"]
},
"firefox": {
"<unknown>": void 0,
"linux-x64": ["firefox", "firefox"],
"linux-arm64": ["firefox", "firefox"],
"mac-x64": ["firefox", "Nightly.app", "Contents", "MacOS", "firefox"],
"mac-arm64": ["firefox", "Nightly.app", "Contents", "MacOS", "firefox"],
"win-x64": ["firefox", "firefox.exe"]
},
"webkit": {
"<unknown>": void 0,
"linux-x64": ["pw_run.sh"],
"linux-arm64": ["pw_run.sh"],
"mac-x64": ["pw_run.sh"],
"mac-arm64": ["pw_run.sh"],
"win-x64": ["Playwright.exe"]
},
"ffmpeg": {
"<unknown>": void 0,
"linux-x64": ["ffmpeg-linux"],
"linux-arm64": ["ffmpeg-linux"],
"mac-x64": ["ffmpeg-mac"],
"mac-arm64": ["ffmpeg-mac"],
"win-x64": ["ffmpeg-win64.exe"]
},
"winldd": {
"<unknown>": void 0,
"linux-x64": void 0,
"linux-arm64": void 0,
"mac-x64": void 0,
"mac-arm64": void 0,
"win-x64": ["PrintDeps.exe"]
}
};
function cftUrl(suffix) {
return ({ browserVersion }) => {
return {
path: `builds/cft/${browserVersion}/${suffix}`,
mirrors: [
"https://cdn.playwright.dev"
]
};
};
}
const DOWNLOAD_PATHS = {
"chromium": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu22.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu24.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"ubuntu22.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"ubuntu24.04-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"debian11-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian11-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"debian12-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian12-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"debian13-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian13-arm64": "builds/chromium/%s/chromium-linux-arm64.zip",
"mac10.13": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac10.14": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac10.15": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac11": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac11-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac12": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac12-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac13": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac13-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac14": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac14-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac15": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac15-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"win64": cftUrl("win64/chrome-win64.zip")
},
"chromium-headless-shell": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu22.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu24.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"ubuntu22.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"ubuntu24.04-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"debian11-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian11-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"debian12-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian12-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"debian13-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian13-arm64": "builds/chromium/%s/chromium-headless-shell-linux-arm64.zip",
"mac10.13": void 0,
"mac10.14": void 0,
"mac10.15": void 0,
"mac11": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac11-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac12": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac12-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac13": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac13-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac14": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac14-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac15": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac15-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"win64": cftUrl("win64/chrome-headless-shell-win64.zip")
},
"chromium-tip-of-tree": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu22.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu24.04-x64": cftUrl("linux64/chrome-linux64.zip"),
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"ubuntu22.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"ubuntu24.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"debian11-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"debian12-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"debian13-x64": cftUrl("linux64/chrome-linux64.zip"),
"debian13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip",
"mac10.13": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac10.14": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac10.15": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac11": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac11-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac12": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac12-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac13": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac13-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac14": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac14-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"mac15": cftUrl("mac-x64/chrome-mac-x64.zip"),
"mac15-arm64": cftUrl("mac-arm64/chrome-mac-arm64.zip"),
"win64": cftUrl("win64/chrome-win64.zip")
},
"chromium-tip-of-tree-headless-shell": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu22.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu24.04-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"ubuntu22.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"ubuntu24.04-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"debian11-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian11-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"debian12-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian12-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"debian13-x64": cftUrl("linux64/chrome-headless-shell-linux64.zip"),
"debian13-arm64": "builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-headless-shell-linux-arm64.zip",
"mac10.13": void 0,
"mac10.14": void 0,
"mac10.15": void 0,
"mac11": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac11-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac12": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac12-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac13": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac13-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac14": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac14-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"mac15": cftUrl("mac-x64/chrome-headless-shell-mac-x64.zip"),
"mac15-arm64": cftUrl("mac-arm64/chrome-headless-shell-mac-arm64.zip"),
"win64": cftUrl("win64/chrome-headless-shell-win64.zip")
},
"firefox": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": "builds/firefox/%s/firefox-ubuntu-20.04.zip",
"ubuntu22.04-x64": "builds/firefox/%s/firefox-ubuntu-22.04.zip",
"ubuntu24.04-x64": "builds/firefox/%s/firefox-ubuntu-24.04.zip",
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip",
"ubuntu22.04-arm64": "builds/firefox/%s/firefox-ubuntu-22.04-arm64.zip",
"ubuntu24.04-arm64": "builds/firefox/%s/firefox-ubuntu-24.04-arm64.zip",
"debian11-x64": "builds/firefox/%s/firefox-debian-11.zip",
"debian11-arm64": "builds/firefox/%s/firefox-debian-11-arm64.zip",
"debian12-x64": "builds/firefox/%s/firefox-debian-12.zip",
"debian12-arm64": "builds/firefox/%s/firefox-debian-12-arm64.zip",
"debian13-x64": "builds/firefox/%s/firefox-debian-13.zip",
"debian13-arm64": "builds/firefox/%s/firefox-debian-13-arm64.zip",
"mac10.13": "builds/firefox/%s/firefox-mac.zip",
"mac10.14": "builds/firefox/%s/firefox-mac.zip",
"mac10.15": "builds/firefox/%s/firefox-mac.zip",
"mac11": "builds/firefox/%s/firefox-mac.zip",
"mac11-arm64": "builds/firefox/%s/firefox-mac-arm64.zip",
"mac12": "builds/firefox/%s/firefox-mac.zip",
"mac12-arm64": "builds/firefox/%s/firefox-mac-arm64.zip",
"mac13": "builds/firefox/%s/firefox-mac.zip",
"mac13-arm64": "builds/firefox/%s/firefox-mac-arm64.zip",
"mac14": "builds/firefox/%s/firefox-mac.zip",
"mac14-arm64": "builds/firefox/%s/firefox-mac-arm64.zip",
"mac15": "builds/firefox/%s/firefox-mac.zip",
"mac15-arm64": "builds/firefox/%s/firefox-mac-arm64.zip",
"win64": "builds/firefox/%s/firefox-win64.zip"
},
"firefox-beta": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": "builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip",
"ubuntu22.04-x64": "builds/firefox-beta/%s/firefox-beta-ubuntu-22.04.zip",
"ubuntu24.04-x64": "builds/firefox-beta/%s/firefox-beta-ubuntu-24.04.zip",
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": void 0,
"ubuntu22.04-arm64": "builds/firefox-beta/%s/firefox-beta-ubuntu-22.04-arm64.zip",
"ubuntu24.04-arm64": "builds/firefox-beta/%s/firefox-beta-ubuntu-24.04-arm64.zip",
"debian11-x64": "builds/firefox-beta/%s/firefox-beta-debian-11.zip",
"debian11-arm64": "builds/firefox-beta/%s/firefox-beta-debian-11-arm64.zip",
"debian12-x64": "builds/firefox-beta/%s/firefox-beta-debian-12.zip",
"debian12-arm64": "builds/firefox-beta/%s/firefox-beta-debian-12-arm64.zip",
"debian13-x64": "builds/firefox-beta/%s/firefox-beta-debian-12.zip",
"debian13-arm64": "builds/firefox-beta/%s/firefox-beta-debian-12-arm64.zip",
"mac10.13": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac10.14": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac10.15": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac11": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac11-arm64": "builds/firefox-beta/%s/firefox-beta-mac-arm64.zip",
"mac12": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac12-arm64": "builds/firefox-beta/%s/firefox-beta-mac-arm64.zip",
"mac13": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac13-arm64": "builds/firefox-beta/%s/firefox-beta-mac-arm64.zip",
"mac14": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac14-arm64": "builds/firefox-beta/%s/firefox-beta-mac-arm64.zip",
"mac15": "builds/firefox-beta/%s/firefox-beta-mac.zip",
"mac15-arm64": "builds/firefox-beta/%s/firefox-beta-mac-arm64.zip",
"win64": "builds/firefox-beta/%s/firefox-beta-win64.zip"
},
"webkit": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": "builds/webkit/%s/webkit-ubuntu-20.04.zip",
"ubuntu22.04-x64": "builds/webkit/%s/webkit-ubuntu-22.04.zip",
"ubuntu24.04-x64": "builds/webkit/%s/webkit-ubuntu-24.04.zip",
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip",
"ubuntu22.04-arm64": "builds/webkit/%s/webkit-ubuntu-22.04-arm64.zip",
"ubuntu24.04-arm64": "builds/webkit/%s/webkit-ubuntu-24.04-arm64.zip",
"debian11-x64": "builds/webkit/%s/webkit-debian-11.zip",
"debian11-arm64": "builds/webkit/%s/webkit-debian-11-arm64.zip",
"debian12-x64": "builds/webkit/%s/webkit-debian-12.zip",
"debian12-arm64": "builds/webkit/%s/webkit-debian-12-arm64.zip",
"debian13-x64": "builds/webkit/%s/webkit-debian-13.zip",
"debian13-arm64": "builds/webkit/%s/webkit-debian-13-arm64.zip",
"mac10.13": void 0,
"mac10.14": void 0,
"mac10.15": void 0,
"mac11": void 0,
"mac11-arm64": void 0,
"mac12": void 0,
"mac12-arm64": void 0,
"mac13": void 0,
"mac13-arm64": void 0,
"mac14": "builds/webkit/%s/webkit-mac-14.zip",
"mac14-arm64": "builds/webkit/%s/webkit-mac-14-arm64.zip",
"mac15": "builds/webkit/%s/webkit-mac-15.zip",
"mac15-arm64": "builds/webkit/%s/webkit-mac-15-arm64.zip",
"win64": "builds/webkit/%s/webkit-win64.zip"
},
"ffmpeg": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"ubuntu22.04-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"ubuntu24.04-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"ubuntu22.04-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"ubuntu24.04-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"debian11-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"debian11-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"debian12-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"debian12-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"debian13-x64": "builds/ffmpeg/%s/ffmpeg-linux.zip",
"debian13-arm64": "builds/ffmpeg/%s/ffmpeg-linux-arm64.zip",
"mac10.13": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac10.14": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac10.15": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac11": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac11-arm64": "builds/ffmpeg/%s/ffmpeg-mac-arm64.zip",
"mac12": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac12-arm64": "builds/ffmpeg/%s/ffmpeg-mac-arm64.zip",
"mac13": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac13-arm64": "builds/ffmpeg/%s/ffmpeg-mac-arm64.zip",
"mac14": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac14-arm64": "builds/ffmpeg/%s/ffmpeg-mac-arm64.zip",
"mac15": "builds/ffmpeg/%s/ffmpeg-mac.zip",
"mac15-arm64": "builds/ffmpeg/%s/ffmpeg-mac-arm64.zip",
"win64": "builds/ffmpeg/%s/ffmpeg-win64.zip"
},
"winldd": {
"<unknown>": void 0,
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": void 0,
"ubuntu22.04-x64": void 0,
"ubuntu24.04-x64": void 0,
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": void 0,
"ubuntu22.04-arm64": void 0,
"ubuntu24.04-arm64": void 0,
"debian11-x64": void 0,
"debian11-arm64": void 0,
"debian12-x64": void 0,
"debian12-arm64": void 0,
"debian13-x64": void 0,
"debian13-arm64": void 0,
"mac10.13": void 0,
"mac10.14": void 0,
"mac10.15": void 0,
"mac11": void 0,
"mac11-arm64": void 0,
"mac12": void 0,
"mac12-arm64": void 0,
"mac13": void 0,
"mac13-arm64": void 0,
"mac14": void 0,
"mac14-arm64": void 0,
"mac15": void 0,
"mac15-arm64": void 0,
"win64": "builds/winldd/%s/winldd-win64.zip"
},
"android": {
"<unknown>": "builds/android/%s/android.zip",
"ubuntu18.04-x64": void 0,
"ubuntu20.04-x64": "builds/android/%s/android.zip",
"ubuntu22.04-x64": "builds/android/%s/android.zip",
"ubuntu24.04-x64": "builds/android/%s/android.zip",
"ubuntu18.04-arm64": void 0,
"ubuntu20.04-arm64": "builds/android/%s/android.zip",
"ubuntu22.04-arm64": "builds/android/%s/android.zip",
"ubuntu24.04-arm64": "builds/android/%s/android.zip",
"debian11-x64": "builds/android/%s/android.zip",
"debian11-arm64": "builds/android/%s/android.zip",
"debian12-x64": "builds/android/%s/android.zip",
"debian12-arm64": "builds/android/%s/android.zip",
"debian13-x64": "builds/android/%s/android.zip",
"debian13-arm64": "builds/android/%s/android.zip",
"mac10.13": "builds/android/%s/android.zip",
"mac10.14": "builds/android/%s/android.zip",
"mac10.15": "builds/android/%s/android.zip",
"mac11": "builds/android/%s/android.zip",
"mac11-arm64": "builds/android/%s/android.zip",
"mac12": "builds/android/%s/android.zip",
"mac12-arm64": "builds/android/%s/android.zip",
"mac13": "builds/android/%s/android.zip",
"mac13-arm64": "builds/android/%s/android.zip",
"mac14": "builds/android/%s/android.zip",
"mac14-arm64": "builds/android/%s/android.zip",
"mac15": "builds/android/%s/android.zip",
"mac15-arm64": "builds/android/%s/android.zip",
"win64": "builds/android/%s/android.zip"
}
};
const defaultCacheDirectory = (() => {
if (process.platform === "linux")
return process.env.XDG_CACHE_HOME || import_path.default.join(import_os.default.homedir(), ".cache");
if (process.platform === "darwin")
return import_path.default.join(import_os.default.homedir(), "Library", "Caches");
if (process.platform === "win32")
return process.env.LOCALAPPDATA || import_path.default.join(import_os.default.homedir(), "AppData", "Local");
throw new Error("Unsupported platform: " + process.platform);
})();
const defaultRegistryDirectory = import_path.default.join(defaultCacheDirectory, "ms-playwright");
const registryDirectory = (() => {
let result;
const envDefined = (0, import_utils.getFromENV)("PLAYWRIGHT_BROWSERS_PATH");
if (envDefined === "0")
result = import_path.default.join(__dirname, "..", "..", "..", ".local-browsers");
else if (envDefined)
result = envDefined;
else
result = defaultRegistryDirectory;
if (!import_path.default.isAbsolute(result)) {
result = import_path.default.resolve((0, import_utils.getFromENV)("INIT_CWD") || process.cwd(), result);
}
return result;
})();
function isBrowserDirectory(browserDirectory) {
const baseName = import_path.default.basename(browserDirectory);
for (const browserName of allDownloadableDirectoriesThatEverExisted) {
if (baseName.startsWith(browserName.replace(/-/g, "_") + "-"))
return true;
}
return false;
}
function readDescriptors(browsersJSON) {
return browsersJSON["browsers"].map((obj) => {
const name = obj.name;
const revisionOverride = (obj.revisionOverrides || {})[import_hostPlatform.hostPlatform];
const revision = revisionOverride || obj.revision;
const browserDirectoryPrefix = revisionOverride ? `${name}_${import_hostPlatform.hostPlatform}_special` : `${name}`;
const descriptor = {
name,
revision,
hasRevisionOverride: !!revisionOverride,
// We only put browser version for the supported operating systems.
browserVersion: revisionOverride ? void 0 : obj.browserVersion,
title: obj["title"],
installByDefault: !!obj.installByDefault,
// Method `isBrowserDirectory` determines directory to be browser iff
// it starts with some browser name followed by '-'. Some browser names
// are prefixes of others, e.g. 'webkit' is a prefix of `webkit-technology-preview`.
// To avoid older registries erroneously removing 'webkit-technology-preview', we have to
// ensure that browser folders to never include dashes inside.
dir: import_path.default.join(registryDirectory, browserDirectoryPrefix.replace(/-/g, "_") + "-" + revision)
};
return descriptor;
});
}
const allDownloadableDirectoriesThatEverExisted = ["android", "chromium", "firefox", "webkit", "ffmpeg", "firefox-beta", "chromium-tip-of-tree", "chromium-headless-shell", "chromium-tip-of-tree-headless-shell", "winldd"];
const chromiumAliases = ["chrome-for-testing"];
class Registry {
constructor(browsersJSON) {
const descriptors = readDescriptors(browsersJSON);
const findExecutablePath = (dir, name) => {
const tokens = EXECUTABLE_PATHS[name][import_hostPlatform.shortPlatform];
return tokens ? import_path.default.join(dir, ...tokens) : void 0;
};
const executablePathOrDie = (name, e, installByDefault, sdkLanguage) => {
if (!e)
throw new Error(`${name} is not supported on ${import_hostPlatform.hostPlatform}`);
const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install${installByDefault ? "" : " " + name}`);
if (!(0, import_fileUtils.canAccessFile)(e)) {
const currentDockerVersion = (0, import_dependencies.readDockerVersionSync)();
const preferredDockerVersion = currentDockerVersion ? (0, import_dependencies.dockerVersion)(currentDockerVersion.dockerImageNameTemplate) : null;
const isOutdatedDockerImage = currentDockerVersion && preferredDockerVersion && currentDockerVersion.dockerImageName !== preferredDockerVersion.dockerImageName;
const isFfmpeg = name === "ffmpeg";
let prettyMessage;
if (isOutdatedDockerImage) {
prettyMessage = [
`Looks like Playwright was just updated to ${preferredDockerVersion.driverVersion}.`,
`Please update docker image as well.`,
`- current: ${currentDockerVersion.dockerImageName}`,
`- required: ${preferredDockerVersion.dockerImageName}`,
``,
`<3 Playwright Team`
].join("\n");
} else if (isFfmpeg) {
prettyMessage = [
`Video rendering requires ffmpeg binary.`,
`Downloading it will not affect any of the system-wide settings.`,
`Please run the following command:`,
``,
` ${buildPlaywrightCLICommand(sdkLanguage, "install ffmpeg")}`,
``,
`<3 Playwright Team`
].join("\n");
} else {
prettyMessage = [
`Looks like Playwright was just installed or updated.`,
`Please run the following command to download new browser${installByDefault ? "s" : ""}:`,
``,
` ${installCommand}`,
``,
`<3 Playwright Team`
].join("\n");
}
throw new Error(`Executable doesn't exist at ${e}
${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
}
return e;
};
this._executables = [];
const chromium = descriptors.find((d) => d.name === "chromium");
const chromiumExecutable = findExecutablePath(chromium.dir, "chromium");
this._executables.push({
name: "chromium",
browserName: "chromium",
directory: chromium.dir,
executablePath: () => chromiumExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium", chromiumExecutable, chromium.installByDefault, sdkLanguage),
installType: chromium.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromium.dir, ["chrome-linux"], [], ["chrome-win"]),
downloadURLs: this._downloadURLs(chromium),
title: chromium.title,
revision: chromium.revision,
browserVersion: chromium.browserVersion,
_install: (force) => this._downloadExecutable(chromium, force, chromiumExecutable),
_dependencyGroup: "chromium",
_isHermeticInstallation: true
});
const chromiumHeadlessShell = descriptors.find((d) => d.name === "chromium-headless-shell");
const chromiumHeadlessShellExecutable = findExecutablePath(chromiumHeadlessShell.dir, "chromium-headless-shell");
this._executables.push({
name: "chromium-headless-shell",
browserName: "chromium",
directory: chromiumHeadlessShell.dir,
executablePath: () => chromiumHeadlessShellExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium", chromiumHeadlessShellExecutable, chromiumHeadlessShell.installByDefault, sdkLanguage),
installType: chromiumHeadlessShell.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ["chrome-linux"], [], ["chrome-win"]),
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
title: chromiumHeadlessShell.title,
revision: chromiumHeadlessShell.revision,
browserVersion: chromiumHeadlessShell.browserVersion,
_install: (force) => this._downloadExecutable(chromiumHeadlessShell, force, chromiumHeadlessShellExecutable),
_dependencyGroup: "chromium",
_isHermeticInstallation: true
});
const chromiumTipOfTreeHeadlessShell = descriptors.find((d) => d.name === "chromium-tip-of-tree-headless-shell");
const chromiumTipOfTreeHeadlessShellExecutable = findExecutablePath(chromiumTipOfTreeHeadlessShell.dir, "chromium-tip-of-tree-headless-shell");
this._executables.push({
name: "chromium-tip-of-tree-headless-shell",
browserName: "chromium",
directory: chromiumTipOfTreeHeadlessShell.dir,
executablePath: () => chromiumTipOfTreeHeadlessShellExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium", chromiumTipOfTreeHeadlessShellExecutable, chromiumTipOfTreeHeadlessShell.installByDefault, sdkLanguage),
installType: chromiumTipOfTreeHeadlessShell.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTreeHeadlessShell.dir, ["chrome-linux"], [], ["chrome-win"]),
downloadURLs: this._downloadURLs(chromiumTipOfTreeHeadlessShell),
title: chromiumTipOfTreeHeadlessShell.title,
revision: chromiumTipOfTreeHeadlessShell.revision,
browserVersion: chromiumTipOfTreeHeadlessShell.browserVersion,
_install: (force) => this._downloadExecutable(chromiumTipOfTreeHeadlessShell, force, chromiumTipOfTreeHeadlessShellExecutable),
_dependencyGroup: "chromium",
_isHermeticInstallation: true
});
const chromiumTipOfTree = descriptors.find((d) => d.name === "chromium-tip-of-tree");
const chromiumTipOfTreeExecutable = findExecutablePath(chromiumTipOfTree.dir, "chromium-tip-of-tree");
this._executables.push({
name: "chromium-tip-of-tree",
browserName: "chromium",
directory: chromiumTipOfTree.dir,
executablePath: () => chromiumTipOfTreeExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium-tip-of-tree", chromiumTipOfTreeExecutable, chromiumTipOfTree.installByDefault, sdkLanguage),
installType: chromiumTipOfTree.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ["chrome-linux"], [], ["chrome-win"]),
downloadURLs: this._downloadURLs(chromiumTipOfTree),
title: chromiumTipOfTree.title,
revision: chromiumTipOfTree.revision,
browserVersion: chromiumTipOfTree.browserVersion,
_install: (force) => this._downloadExecutable(chromiumTipOfTree, force, chromiumTipOfTreeExecutable),
_dependencyGroup: "chromium",
_isHermeticInstallation: true
});
this._executables.push(this._createChromiumChannel("chrome", {
"linux": "/opt/google/chrome/chrome",
"darwin": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"win32": `\\Google\\Chrome\\Application\\chrome.exe`
}, () => this._installChromiumChannel("chrome", {
"linux": "reinstall_chrome_stable_linux.sh",
"darwin": "reinstall_chrome_stable_mac.sh",
"win32": "reinstall_chrome_stable_win.ps1"
})));
this._executables.push(this._createChromiumChannel("chrome-beta", {
"linux": "/opt/google/chrome-beta/chrome",
"darwin": "/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta",
"win32": `\\Google\\Chrome Beta\\Application\\chrome.exe`
}, () => this._installChromiumChannel("chrome-beta", {
"linux": "reinstall_chrome_beta_linux.sh",
"darwin": "reinstall_chrome_beta_mac.sh",
"win32": "reinstall_chrome_beta_win.ps1"
})));
this._executables.push(this._createChromiumChannel("chrome-dev", {
"linux": "/opt/google/chrome-unstable/chrome",
"darwin": "/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev",
"win32": `\\Google\\Chrome Dev\\Application\\chrome.exe`
}));
this._executables.push(this._createChromiumChannel("chrome-canary", {
"linux": "/opt/google/chrome-canary/chrome",
"darwin": "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
"win32": `\\Google\\Chrome SxS\\Application\\chrome.exe`
}));
this._executables.push(this._createChromiumChannel("msedge", {
"linux": "/opt/microsoft/msedge/msedge",
"darwin": "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
"win32": `\\Microsoft\\Edge\\Application\\msedge.exe`
}, () => this._installMSEdgeChannel("msedge", {
"linux": "reinstall_msedge_stable_linux.sh",
"darwin": "reinstall_msedge_stable_mac.sh",
"win32": "reinstall_msedge_stable_win.ps1"
})));
this._executables.push(this._createChromiumChannel("msedge-beta", {
"linux": "/opt/microsoft/msedge-beta/msedge",
"darwin": "/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta",
"win32": `\\Microsoft\\Edge Beta\\Application\\msedge.exe`
}, () => this._installMSEdgeChannel("msedge-beta", {
"darwin": "reinstall_msedge_beta_mac.sh",
"linux": "reinstall_msedge_beta_linux.sh",
"win32": "reinstall_msedge_beta_win.ps1"
})));
this._executables.push(this._createChromiumChannel("msedge-dev", {
"linux": "/opt/microsoft/msedge-dev/msedge",
"darwin": "/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev",
"win32": `\\Microsoft\\Edge Dev\\Application\\msedge.exe`
}, () => this._installMSEdgeChannel("msedge-dev", {
"darwin": "reinstall_msedge_dev_mac.sh",
"linux": "reinstall_msedge_dev_linux.sh",
"win32": "reinstall_msedge_dev_win.ps1"
})));
this._executables.push(this._createChromiumChannel("msedge-canary", {
"linux": "",
"darwin": "/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary",
"win32": `\\Microsoft\\Edge SxS\\Application\\msedge.exe`
}));
this._executables.push(this._createBidiFirefoxChannel("moz-firefox", {
"linux": "/snap/bin/firefox",
"darwin": "/Applications/Firefox.app/Contents/MacOS/firefox",
"win32": "\\Mozilla Firefox\\firefox.exe"
}));
this._executables.push(this._createBidiFirefoxChannel("moz-firefox-beta", {
"linux": "/opt/firefox-beta/firefox",
"darwin": "/Applications/Firefox.app/Contents/MacOS/firefox",
"win32": "\\Mozilla Firefox\\firefox.exe"
}));
this._executables.push(this._createBidiFirefoxChannel("moz-firefox-nightly", {
"linux": "/opt/firefox-nightly/firefox",
"darwin": "/Applications/Firefox Nightly.app/Contents/MacOS/firefox",
"win32": "\\Mozilla Firefox\\firefox.exe"
}));
const firefox = descriptors.find((d) => d.name === "firefox");
const firefoxExecutable = findExecutablePath(firefox.dir, "firefox");
this._executables.push({
name: "firefox",
browserName: "firefox",
directory: firefox.dir,
executablePath: () => firefoxExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("firefox", firefoxExecutable, firefox.installByDefault, sdkLanguage),
installType: firefox.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, firefox.dir, ["firefox"], [], ["firefox"]),
downloadURLs: this._downloadURLs(firefox),
title: firefox.title,
revision: firefox.revision,
browserVersion: firefox.browserVersion,
_install: (force) => this._downloadExecutable(firefox, force, firefoxExecutable),
_dependencyGroup: "firefox",
_isHermeticInstallation: true
});
const firefoxBeta = descriptors.find((d) => d.name === "firefox-beta");
const firefoxBetaExecutable = findExecutablePath(firefoxBeta.dir, "firefox");
this._executables.push({
name: "firefox-beta",
browserName: "firefox",
directory: firefoxBeta.dir,
executablePath: () => firefoxBetaExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("firefox-beta", firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),
installType: firefoxBeta.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ["firefox"], [], ["firefox"]),
downloadURLs: this._downloadURLs(firefoxBeta),
title: firefoxBeta.title,
revision: firefoxBeta.revision,
browserVersion: firefoxBeta.browserVersion,
_install: (force) => this._downloadExecutable(firefoxBeta, force, firefoxBetaExecutable),
_dependencyGroup: "firefox",
_isHermeticInstallation: true
});
const webkit = descriptors.find((d) => d.name === "webkit");
const webkitExecutable = findExecutablePath(webkit.dir, "webkit");
const webkitLinuxLddDirectories = [
import_path.default.join("minibrowser-gtk"),
import_path.default.join("minibrowser-gtk", "bin"),
import_path.default.join("minibrowser-gtk", "lib"),
import_path.default.join("minibrowser-gtk", "sys", "lib"),
import_path.default.join("minibrowser-wpe"),
import_path.default.join("minibrowser-wpe", "bin"),
import_path.default.join("minibrowser-wpe", "lib"),
import_path.default.join("minibrowser-wpe", "sys", "lib")
];
this._executables.push({
name: "webkit",
browserName: "webkit",
directory: webkit.dir,
executablePath: () => webkitExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("webkit", webkitExecutable, webkit.installByDefault, sdkLanguage),
installType: webkit.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: (sdkLanguage) => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ["libGLESv2.so.2", "libx264.so"], [""]),
downloadURLs: this._downloadURLs(webkit),
title: webkit.title,
revision: webkit.revision,
browserVersion: webkit.browserVersion,
_install: (force) => this._downloadExecutable(webkit, force, webkitExecutable),
_dependencyGroup: "webkit",
_isHermeticInstallation: true
});
this._executables.push({
name: "webkit-wsl",
browserName: "webkit",
directory: webkit.dir,
executablePath: () => webkitExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("webkit", webkitExecutable, webkit.installByDefault, sdkLanguage),
installType: "download-on-demand",
title: "Webkit in WSL",
_validateHostRequirements: (sdkLanguage) => Promise.resolve(),
_isHermeticInstallation: true,
_install: async () => {
if (process.platform !== "win32")
throw new Error(`WebKit via WSL is only supported on Windows`);
const script = import_path.default.join(BIN_PATH, "install_webkit_wsl.ps1");
const { code } = await (0, import_spawnAsync.spawnAsync)("powershell.exe", [
"-ExecutionPolicy",
"Bypass",
"-File",
script
], {
stdio: "inherit"
});
if (code !== 0)
throw new Error(`Failed to install WebKit via WSL`);
}
});
const ffmpeg = descriptors.find((d) => d.name === "ffmpeg");
const ffmpegExecutable = findExecutablePath(ffmpeg.dir, "ffmpeg");
this._executables.push({
name: "ffmpeg",
browserName: void 0,
directory: ffmpeg.dir,
executablePath: () => ffmpegExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("ffmpeg", ffmpegExecutable, ffmpeg.installByDefault, sdkLanguage),
installType: ffmpeg.installByDefault ? "download-by-default" : "download-on-demand",
_validateHostRequirements: () => Promise.resolve(),
downloadURLs: this._downloadURLs(ffmpeg),
title: ffmpeg.title,
revision: ffmpeg.revision,
_install: (force) => this._downloadExecutable(ffmpeg, force, ffmpegExecutable),
_dependencyGroup: "tools",
_isHermeticInstallation: true
});
const winldd = descriptors.find((d) => d.name === "winldd");
const winlddExecutable = findExecutablePath(winldd.dir, "winldd");
this._executables.push({
name: "winldd",
browserName: void 0,
directory: winldd.dir,
executablePath: () => winlddExecutable,
executablePathOrDie: (sdkLanguage) => executablePathOrDie("winldd", winlddExecutable, winldd.installByDefault, sdkLanguage),
installType: process.platform === "win32" ? "download-by-default" : "none",
_validateHostRequirements: () => Promise.resolve(),
downloadURLs: this._downloadURLs(winldd),
title: winldd.title,
revision: winldd.revision,
_install: (force) => this._downloadExecutable(winldd, force, winlddExecutable),
_dependencyGroup: "tools",
_isHermeticInstallation: true
});
const android = descriptors.find((d) => d.name === "android");
this._executables.push({
name: "android",
browserName: void 0,
directory: android.dir,
executablePath: () => void 0,
executablePathOrDie: () => "",
installType: "download-on-demand",
_validateHostRequirements: () => Promise.resolve(),
downloadURLs: this._downloadURLs(android),
title: android.title,
revision: android.revision,
_install: (force) => this._downloadExecutable(android, force),
_dependencyGroup: "tools",
_isHermeticInstallation: true
});
}
_createChromiumChannel(name, lookAt, install) {
const executablePath = (sdkLanguage, shouldThrow) => {
const suffix = lookAt[process.platform];
if (!suffix) {
if (shouldThrow)
throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`);
return void 0;
}
const prefixes = process.platform === "win32" ? [
process.env.LOCALAPPDATA,
process.env.PROGRAMFILES,
process.env["PROGRAMFILES(X86)"],
// In some cases there is no PROGRAMFILES/(86) env var set but HOMEDRIVE is set.
process.env.HOMEDRIVE + "\\Program Files",
process.env.HOMEDRIVE + "\\Program Files (x86)"
].filter(Boolean) : [""];
for (const prefix of prefixes) {
const executablePath2 = import_path.default.join(prefix, suffix);
if ((0, import_fileUtils.canAccessFile)(executablePath2))
return executablePath2;
}
if (!shouldThrow)
return void 0;
const location = prefixes.length ? ` at ${import_path.default.join(prefixes[0], suffix)}` : ``;
const installation = install ? `
Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`);
};
return {
name,
browserName: "chromium",
directory: void 0,
executablePath: () => executablePath("", false),
executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
installType: install ? "install-script" : "none",
_validateHostRequirements: () => Promise.resolve(),
_isHermeticInstallation: false,
_install: install
};
}
_createBidiFirefoxChannel(name, lookAt, install) {
const executablePath = (sdkLanguage, shouldThrow) => {
const suffix = lookAt[process.platform];
if (!suffix) {
if (shouldThrow)
throw new Error(`Firefox distribution '${name}' is not supported on ${process.platform}`);
return void 0;
}
const prefixes = process.platform === "win32" ? [
process.env.LOCALAPPDATA,
process.env.PROGRAMFILES,
process.env["PROGRAMFILES(X86)"],
// In some cases there is no PROGRAMFILES/(86) env var set but HOMEDRIVE is set.
process.env.HOMEDRIVE + "\\Program Files",
process.env.HOMEDRIVE + "\\Program Files (x86)"
].filter(Boolean) : [""];
for (const prefix of prefixes) {
const executablePath2 = import_path.default.join(prefix, suffix);
if ((0, import_fileUtils.canAccessFile)(executablePath2))
return executablePath2;
}
if (shouldThrow)
throw new Error(`Cannot find Firefox installation for channel '${name}' at the standard system paths. ${`Tried paths:
${prefixes.map((p) => import_path.default.join(p, suffix)).join("\n ")}`}`);
return void 0;
};
return {
name,
browserName: "firefox",
directory: void 0,
executablePath: () => executablePath("", false),
executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
installType: "none",
_validateHostRequirements: () => Promise.resolve(),
_isHermeticInstallation: true,
_install: install
};
}
executables() {
return this._executables;
}
findExecutable(name) {
return this._executables.find((b) => b.name === name);
}
defaultExecutables() {
return this._executables.filter((e) => e.installType === "download-by-default");
}
_dedupe(executables) {
return Array.from(new Set(executables));
}
async _validateHostRequirements(sdkLanguage, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) {
if (import_os.default.platform() === "linux")
return await (0, import_dependencies2.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map((d) => import_path.default.join(browserDirectory, d)), dlOpenLibraries);
if (import_os.default.platform() === "win32" && import_os.default.arch() === "x64")
return await (0, import_dependencies2.validateDependenciesWindows)(sdkLanguage, windowsExeAndDllDirectories.map((d) => import_path.default.join(browserDirectory, d)));
}
async installDeps(executablesToInstallDeps, dryRun) {
const executables = this._dedupe(executablesToInstallDeps);
const targets = /* @__PURE__ */ new Set();
for (const executable of executables) {
if (executable._dependencyGroup)
targets.add(executable._dependencyGroup);
}
targets.add("tools");
if (import_os.default.platform() === "win32")
return await (0, import_dependencies2.installDependenciesWindows)(targets, dryRun);
if (import_os.default.platform() === "linux")
return await (0, import_dependencies2.installDependenciesLinux)(targets, dryRun);
}
async install(executablesToInstall, options) {
const executables = this._dedupe(executablesToInstall);
await import_fs.default.promises.mkdir(registryDirectory, { recursive: true });
const lockfilePath = import_path.default.join(registryDirectory, "__dirlock");
const linksDir = import_path.default.join(registryDirectory, ".links");
let releaseLock;
try {
releaseLock = await import_utilsBundle.lockfile.lock(registryDirectory, {
retries: {
// Retry 20 times during 10 minutes with
// exponential back-off.
// See documentation at: https://www.npmjs.com/package/retry#retrytimeoutsoptions
retries: 20,
factor: 1.27579
},
onCompromised: (err) => {
throw new Error(`${err.message} Path: ${lockfilePath}`);
},
lockfilePath
});
await import_fs.default.promises.mkdir(linksDir, { recursive: true });
await import_fs.default.promises.writeFile(import_path.default.join(linksDir, (0, import_utils.calculateSha1)(PACKAGE_PATH)), PACKAGE_PATH);
if (!(0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_SKIP_BROWSER_GC"))
await this._validateInstallationCache(linksDir);
for (const executable of executables) {
if (!executable._install)
throw new Error(`ERROR: Playwright does not support installing ${executable.name}`);
if (!(0, import_utils.getAsBooleanFromENV)("CI") && !executable._isHermeticInstallation && !options?.force && executable.executablePath()) {
const { embedderName } = (0, import_userAgent.getEmbedderName)();
const command = buildPlaywrightCLICommand(embedderName, "install --force " + executable.name);
process.stderr.write("\n" + (0, import_ascii.wrapInASCIIBox)([
`ATTENTION: "${executable.name}" is already installed on the system!`,
``,
`"${executable.name}" installation is not hermetic; installing newer version`,
`requires *removal* of a current installation first.`,
``,
`To *uninstall* current version and re-install latest "${executable.name}":`,
``,
`- Close all running instances of "${executable.name}", if any`,
`- Use "--force" to install browser:`,
``,
` ${command}`,
``,
`<3 Playwright Team`
].join("\n"), 1) + "\n\n");
return;
}
await executable._install(!!options?.force);
}
} catch (e) {
if (e.code === "ELOCKED") {
const rmCommand = process.platform === "win32" ? "rm -R" : "rm -rf";
throw new Error("\n" + (0, import_ascii.wrapInASCIIBox)([
`An active lockfile is found at:`,
``,
` ${lockfilePath}`,
``,
`Either:`,
`- wait a few minutes if other Playwright is installing browsers in parallel`,
`- remove lock manually with:`,
``,
` ${rmCommand} ${lockfilePath}`,
``,
`<3 Playwright Team`
].join("\n"), 1));
} else {
throw e;
}
} finally {
if (releaseLock)
await releaseLock();
}
}
async uninstall(all) {
const linksDir = import_path.default.join(registryDirectory, ".links");
if (all) {
const links = await import_fs.default.promises.readdir(linksDir).catch(() => []);
for (const link of links)
await import_fs.default.promises.unlink(import_path.default.join(linksDir, link));
} else {
await import_fs.default.promises.unlink(import_path.default.join(linksDir, (0, import_utils.calculateSha1)(PACKAGE_PATH))).catch(() => {
});
}
await this._validateInstallationCache(linksDir);
return {
numberOfBrowsersLeft: (await import_fs.default.promises.readdir(registryDirectory).catch(() => [])).filter((browserDirectory) => isBrowserDirectory(browserDirectory)).length
};
}
async validateHostRequirementsForExecutablesIfNeeded(executables, sdkLanguage) {
if ((0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS")) {
process.stderr.write("Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n");
return;
}
for (const executable of executables)
await this._validateHostRequirementsForExecutableIfNeeded(executable, sdkLanguage);
}
async _validateHostRequirementsForExecutableIfNeeded(executable, sdkLanguage) {
const kMaximumReValidationPeriod = 30 * 24 * 60 * 60 * 1e3;
if (!executable.directory)
return;
const markerFile = import_path.default.join(executable.directory, "DEPENDENCIES_VALIDATED");
if (await import_fs.default.promises.stat(markerFile).then((stat) => Date.now() - stat.mtime.getTime() < kMaximumReValidationPeriod).catch(() => false))
return;
import_debugLogger.debugLogger.log("install", `validating host requirements for "${executable.name}"`);
try {
await executable._validateHostRequirements(sdkLanguage);
import_debugLogger.debugLogger.log("install", `validation passed for ${executable.name}`);
} catch (error) {
import_debugLogger.debugLogger.log("install", `validation failed for ${executable.name}`);
throw error;
}
await import_fs.default.promises.writeFile(markerFile, "").catch(() => {
});
}
_downloadURLs(descriptor) {
const paths = DOWNLOAD_PATHS[descriptor.name];
const downloadPathTemplate = paths[import_hostPlatform.hostPlatform] || paths["<unknown>"];
if (!downloadPathTemplate)
return [];
let downloadPath;
let mirrors;
if (typeof downloadPathTemplate === "function") {
const result = downloadPathTemplate(descriptor);
downloadPath = result.path;
mirrors = result.mirrors;
} else {
downloadPath = util.format(downloadPathTemplate, descriptor.revision);
mirrors = PLAYWRIGHT_CDN_MIRRORS;
}
let downloadHostEnv;
if (descriptor.name.startsWith("chromium"))
downloadHostEnv = "PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST";
else if (descriptor.name.startsWith("firefox"))
downloadHostEnv = "PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST";
else if (descriptor.name.startsWith("webkit"))
downloadHostEnv = "PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST";
const customHostOverride = downloadHostEnv && (0, import_utils.getFromENV)(downloadHostEnv) || (0, import_utils.getFromENV)("PLAYWRIGHT_DOWNLOAD_HOST");
if (customHostOverride)
mirrors = [customHostOverride];
return mirrors.map((mirror) => `${mirror}/${downloadPath}`);
}
async _downloadExecutable(descriptor, force, executablePath) {
const downloadURLs = this._downloadURLs(descriptor);
if (!downloadURLs.length)
throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${import_hostPlatform.hostPlatform}`);
if (!import_hostPlatform.isOfficiallySupportedPlatform)
(0, import_browserFetcher.logPolitely)(`BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ${import_hostPlatform.hostPlatform}.`);
if (descriptor.hasRevisionOverride) {
const message = `You are using a frozen ${descriptor.name} browser which does not receive updates anymore on ${import_hostPlatform.hostPlatform}. Please update to the latest version of your operating system to test up-to-date browsers.`;
if (process.env.GITHUB_ACTIONS)
console.log(`::warning title=Playwright::${message}`);
else
(0, import_browserFetcher.logPolitely)(message);
}
const title = this.calculateDownloadTitle(descriptor);
const downloadFileName = `playwright-download-${descriptor.name}-${import_hostPlatform.hostPlatform}-${descriptor.revision}.zip`;
const downloadSocketTimeoutEnv = (0, import_utils.getFromENV)("PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT");
const downloadSocketTimeout = +(downloadSocketTimeoutEnv || "0") || import_network.NET_DEFAULT_TIMEOUT;
await (0, import_browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadSocketTimeout, force).catch((e) => {
throw new Error(`Failed to download ${title}, caused by
${e.stack}`);
});
}
calculateDownloadTitle(descriptor) {
const title = descriptor.title ?? descriptor.name.split("-").map((word) => {
return word === "ffmpeg" ? "FFmpeg" : word.charAt(0).toUpperCase() + word.slice(1);
}).join(" ");
const version = descriptor.browserVersion ? " " + descriptor.browserVersion : "";
return `${title}${version} (playwright ${descriptor.name} v${descriptor.revision})`;
}
async _installMSEdgeChannel(channel, scripts) {
const scriptArgs = [];
if (process.platform !== "linux") {
const products = lowercaseAllKeys(JSON.parse(await (0, import_network.fetchData)(void 0, { url: "https://edgeupdates.microsoft.com/api/products" })));
const productName = {
"msedge": "Stable",
"msedge-beta": "Beta",
"msedge-dev": "Dev"
}[channel];
const product = products.find((product2) => product2.product === productName);
const searchConfig = {
darwin: { platform: "MacOS", arch: "universal", artifact: "pkg" },
win32: { platform: "Windows", arch: "x64", artifact: "msi" }
}[process.platform];
const release = searchConfig ? product.releases.find((release2) => release2.platform === searchConfig.platform && release2.architecture === searchConfig.arch && release2.artifacts.length > 0) : null;
const artifact = release ? release.artifacts.find((artifact2) => artifact2.artifactname === searchConfig.artifact) : null;
if (artifact)
scriptArgs.push(
artifact.location
/* url */
);
else
throw new Error(`Cannot install ${channel} on ${process.platform}`);
}
await this._installChromiumChannel(channel, scripts, scriptArgs);
}
async _installChromiumChannel(channel, scripts, scriptArgs = []) {
const scriptName = scripts[process.platform];
if (!scriptName)
throw new Error(`Cannot install ${channel} on ${process.platform}`);
const cwd = BIN_PATH;
const isPowerShell = scriptName.endsWith(".ps1");
if (isPowerShell) {
const args = [
"-ExecutionPolicy",
"Bypass",
"-File",
import_path.default.join(BIN_PATH, scriptName),
...scriptArgs
];
const { code } = await (0, import_spawnAsync.spawnAsync)("powershell.exe", args, { cwd, stdio: "inherit" });
if (code !== 0)
throw new Error(`Failed to install ${channel}`);
} else {
const { command, args, elevatedPermissions } = await (0, import_dependencies.transformCommandsForRoot)([`bash "${import_path.default.join(BIN_PATH, scriptName)}" ${scriptArgs.join("")}`]);
if (elevatedPermissions)
console.log("Switching to root user to install dependencies...");
const { code } = await (0, import_spawnAsync.spawnAsync)(command, args, { cwd, stdio: "inherit" });
if (code !== 0)
throw new Error(`Failed to install ${channel}`);
}
}
async listInstalledBrowsers() {
const linksDir = import_path.default.join(registryDirectory, ".links");
const { browsers } = await this._traverseBrowserInstallations(linksDir);
return browsers.filter((browser) => import_fs.default.existsSync(browser.browserPath));
}
async _validateInstallationCache(linksDir) {
const { browsers, brokenLinks } = await this._traverseBrowserInstallations(linksDir);
await this._deleteStaleBrowsers(browsers);
await this._deleteBrokenInstallations(brokenLinks);
}
async _traverseBrowserInstallations(linksDir) {
const browserList = [];
const brokenLinks = [];
for (const fileName of await import_fs.default.promises.readdir(linksDir)) {
const linkPath = import_path.default.join(linksDir, fileName);
let linkTarget = "";
try {
linkTarget = (await import_fs.default.promises.readFile(linkPath)).toString();
const browsersJSON = require(import_path.default.join(linkTarget, "browsers.json"));
const descriptors = readDescriptors(browsersJSON);
for (const browserName of allDownloadableDirectoriesThatEverExisted) {
const descriptor = descriptors.find((d) => d.name === browserName);
if (!descriptor)
continue;
const browserPath = descriptor.dir;
const browserVersion = parseInt(descriptor.revision, 10);
browserList.push({
browserName,
browserVersion,
browserPath,
referenceDir: linkTarget
});
}
} catch (e) {
brokenLinks.push(linkPath);
}
}
return { browsers: browserList, brokenLinks };
}
async _deleteStaleBrowsers(browserList) {
const usedBrowserPaths = /* @__PURE__ */ new Set();
for (const browser of browserList) {
const { browserName, browserVersion, browserPath } = browser;
const shouldHaveMarkerFile = browserName === "chromium" && (browserVersion >= 786218 || browserVersion < 3e5) || browserName === "firefox" && browserVersion >= 1128 || browserName === "webkit" && browserVersion >= 1307 || // All new applications have a marker file right away.
browserName !== "firefox" && browserName !== "chromium" && browserName !== "webkit";
if (!shouldHaveMarkerFile || await (0, import_fileUtils.existsAsync)(browserDirectoryToMarkerFilePath(browserPath)))
usedBrowserPaths.add(browserPath);
}
let downloadedBrowsers = (await import_fs.default.promises.readdir(registryDirectory)).map((file) => import_path.default.join(registryDirectory, file));
downloadedBrowsers = downloadedBrowsers.filter((file) => isBrowserDirectory(file));
const directories = new Set(downloadedBrowsers);
for (const browserDirectory of usedBrowserPaths)
directories.delete(browserDirectory);
for (const directory of directories)
(0, import_browserFetcher.logPolitely)("Removing unused browser at " + directory);
await (0, import_fileUtils.removeFolders)([...directories]);
}
async _deleteBrokenInstallations(brokenLinks) {
for (const linkPath of brokenLinks)
await import_fs.default.promises.unlink(linkPath).catch((e) => {
});
}
_defaultBrowsersToInstall(options) {
let executables = this.defaultExecutables();
if (options.shell === "no")
executables = executables.filter((e) => e.name !== "chromium-headless-shell" && e.name !== "chromium-tip-of-tree-headless-shell");
if (options.shell === "only")
executables = executables.filter((e) => e.name !== "chromium" && e.name !== "chromium-tip-of-tree");
return executables;
}
suggestedBrowsersToInstall() {
const names = this.executables().filter((e) => e.installType !== "none").map((e) => e.name);
names.push(...chromiumAliases);
return names.sort().join(", ");
}
isChromiumAlias(name) {
return chromiumAliases.includes(name);
}
resolveBrowsers(aliases, options) {
if (aliases.length === 0)
return this._defaultBrowsersToInstall(options);
const faultyArguments = [];
const executables = [];
const handleArgument = (arg) => {
const executable = this.findExecutable(arg);
if (!executable || executable.installType === "none")
faultyArguments.push(arg);
else
executables.push(executable);
if (executable?.browserName)
executables.push(this.findExecutable("ffmpeg"));
};
for (const alias of aliases) {
if (alias === "chromium" || chromiumAliases.includes(alias)) {
if (options.shell !== "only")
handleArgument("chromium");
if (options.shell !== "no")
handleArgument("chromium-headless-shell");
} else if (alias === "chromium-tip-of-tree") {
if (options.shell !== "only")
handleArgument("chromium-tip-of-tree");
if (options.shell !== "no")
handleArgument("chromium-tip-of-tree-headless-shell");
} else {
handleArgument(alias);
}
}
if (process.platform === "win32")
executables.push(this.findExecutable("winldd"));
if (faultyArguments.length)
throw new Error(`Invalid installation targets: ${faultyArguments.map((name) => `'${name}'`).join(", ")}. Expecting one of: ${this.suggestedBrowsersToInstall()}`);
return executables;
}
}
function browserDirectoryToMarkerFilePath(browserDirectory) {
return import_path.default.join(browserDirectory, "INSTALLATION_COMPLETE");
}
function buildPlaywrightCLICommand(sdkLanguage, parameters) {
switch (sdkLanguage) {
case "python":
return `playwright ${parameters}`;
case "java":
return `mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="${parameters}"`;
case "csharp":
return `pwsh bin/Debug/netX/playwright.ps1 ${parameters}`;
default: {
const packageManagerCommand = (0, import_utils.getPackageManagerExecCommand)();
return `${packageManagerCommand} playwright ${parameters}`;
}
}
}
async function installBrowsersForNpmInstall(browsers) {
if ((0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD")) {
(0, import_browserFetcher.logPolitely)("Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set");
return false;
}
const executables = [];
if (process.platform === "win32")
executables.push(registry.findExecutable("winldd"));
for (const browserName of browsers) {
const executable = registry.findExecutable(browserName);
if (!executable || executable.installType === "none")
throw new Error(`Cannot install ${browserName}`);
executables.push(executable);
}
await registry.install(executables);
}
function findChromiumChannelBestEffort(sdkLanguage) {
let channel = null;
for (const name of ["chromium", "chrome", "msedge"]) {
try {
registry.findExecutable(name).executablePathOrDie(sdkLanguage);
channel = name === "chromium" ? void 0 : name;
break;
} catch (e) {
}
}
if (channel === null) {
const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install chromium`);
const prettyMessage = [
`No chromium-based browser found on the system.`,
`Please run the following command to download one:`,
``,
` ${installCommand}`,
``,
`<3 Playwright Team`
].join("\n");
throw new Error("\n" + (0, import_ascii.wrapInASCIIBox)(prettyMessage, 1));
}
return channel;
}
function lowercaseAllKeys(json) {
if (typeof json !== "object" || !json)
return json;
if (Array.isArray(json))
return json.map(lowercaseAllKeys);
const result = {};
for (const [key, value] of Object.entries(json))
result[key.toLowerCase()] = lowercaseAllKeys(value);
return result;
}
const registry = new Registry(require("../../../browsers.json"));
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Registry,
browserDirectoryToMarkerFilePath,
buildPlaywrightCLICommand,
defaultCacheDirectory,
defaultRegistryDirectory,
findChromiumChannelBestEffort,
installBrowsersForNpmInstall,
registry,
registryDirectory,
writeDockerVersion
});