Best JavaScript code snippet using playwright-internal
index.js
Source:index.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.Registry = void 0;6exports.buildPlaywrightCLICommand = buildPlaywrightCLICommand;7exports.findChromiumChannel = findChromiumChannel;8exports.installBrowsersForNpmInstall = installBrowsersForNpmInstall;9exports.installDefaultBrowsersForNpmInstall = installDefaultBrowsersForNpmInstall;10exports.registryDirectory = exports.registry = void 0;11Object.defineProperty(exports, "writeDockerVersion", {12 enumerable: true,13 get: function () {14 return _dependencies.writeDockerVersion;15 }16});17var os = _interopRequireWildcard(require("os"));18var _path = _interopRequireDefault(require("path"));19var util = _interopRequireWildcard(require("util"));20var fs = _interopRequireWildcard(require("fs"));21var _properLockfile = _interopRequireDefault(require("proper-lockfile"));22var _ubuntuVersion = require("../../utils/ubuntuVersion");23var _netUtils = require("../../common/netUtils");24var _userAgent = require("../../common/userAgent");25var _utils = require("../../utils");26var _fileUtils = require("../../utils/fileUtils");27var _hostPlatform = require("../../utils/hostPlatform");28var _spawnAsync = require("../../utils/spawnAsync");29var _dependencies = require("./dependencies");30var _browserFetcher = require("./browserFetcher");31function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }32function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }33function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }34/**35 * Copyright 2017 Google Inc. All rights reserved.36 * Modifications copyright (c) Microsoft Corporation.37 *38 * Licensed under the Apache License, Version 2.0 (the "License");39 * you may not use this file except in compliance with the License.40 * You may obtain a copy of the License at41 *42 * http://www.apache.org/licenses/LICENSE-2.043 *44 * Unless required by applicable law or agreed to in writing, software45 * distributed under the License is distributed on an "AS IS" BASIS,46 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.47 * See the License for the specific language governing permissions and48 * limitations under the License.49 */50const PACKAGE_PATH = _path.default.join(__dirname, '..', '..', '..');51const BIN_PATH = _path.default.join(__dirname, '..', '..', '..', 'bin');52const EXECUTABLE_PATHS = {53 'chromium': {54 'linux': ['chrome-linux', 'chrome'],55 'mac': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'],56 'win': ['chrome-win', 'chrome.exe']57 },58 'firefox': {59 'linux': ['firefox', 'firefox'],60 'mac': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'],61 'win': ['firefox', 'firefox.exe']62 },63 'webkit': {64 'linux': ['pw_run.sh'],65 'mac': ['pw_run.sh'],66 'win': ['Playwright.exe']67 },68 'ffmpeg': {69 'linux': ['ffmpeg-linux'],70 'mac': ['ffmpeg-mac'],71 'win': ['ffmpeg-win64.exe']72 }73};74const DOWNLOAD_PATHS = {75 'chromium': {76 '<unknown>': undefined,77 'generic-linux': 'builds/chromium/%s/chromium-linux.zip',78 'generic-linux-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',79 'ubuntu18.04': 'builds/chromium/%s/chromium-linux.zip',80 'ubuntu20.04': 'builds/chromium/%s/chromium-linux.zip',81 'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',82 'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',83 'mac10.13': 'builds/chromium/%s/chromium-mac.zip',84 'mac10.14': 'builds/chromium/%s/chromium-mac.zip',85 'mac10.15': 'builds/chromium/%s/chromium-mac.zip',86 'mac11': 'builds/chromium/%s/chromium-mac.zip',87 'mac11-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',88 'mac12': 'builds/chromium/%s/chromium-mac.zip',89 'mac12-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',90 'win64': 'builds/chromium/%s/chromium-win64.zip'91 },92 'chromium-with-symbols': {93 '<unknown>': undefined,94 'generic-linux': 'builds/chromium/%s/chromium-with-symbols-linux.zip',95 'generic-linux-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',96 'ubuntu18.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',97 'ubuntu20.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',98 'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',99 'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',100 'mac10.13': 'builds/chromium/%s/chromium-with-symbols-mac.zip',101 'mac10.14': 'builds/chromium/%s/chromium-with-symbols-mac.zip',102 'mac10.15': 'builds/chromium/%s/chromium-with-symbols-mac.zip',103 'mac11': 'builds/chromium/%s/chromium-with-symbols-mac.zip',104 'mac11-arm64': 'builds/chromium/%s/chromium-with-symbols-mac-arm64.zip',105 'mac12': 'builds/chromium/%s/chromium-with-symbols-mac.zip',106 'mac12-arm64': 'builds/chromium/%s/chromium-with-symbols-mac-arm64.zip',107 'win64': 'builds/chromium/%s/chromium-with-symbols-win64.zip'108 },109 'firefox': {110 '<unknown>': undefined,111 'generic-linux': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',112 'generic-linux-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',113 'ubuntu18.04': 'builds/firefox/%s/firefox-ubuntu-18.04.zip',114 'ubuntu20.04': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',115 'ubuntu18.04-arm64': undefined,116 'ubuntu20.04-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',117 'mac10.13': 'builds/firefox/%s/firefox-mac-11.zip',118 'mac10.14': 'builds/firefox/%s/firefox-mac-11.zip',119 'mac10.15': 'builds/firefox/%s/firefox-mac-11.zip',120 'mac11': 'builds/firefox/%s/firefox-mac-11.zip',121 'mac11-arm64': 'builds/firefox/%s/firefox-mac-11-arm64.zip',122 'mac12': 'builds/firefox/%s/firefox-mac-11.zip',123 'mac12-arm64': 'builds/firefox/%s/firefox-mac-11-arm64.zip',124 'win64': 'builds/firefox/%s/firefox-win64.zip'125 },126 'firefox-beta': {127 '<unknown>': undefined,128 'generic-linux': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',129 'generic-linux-arm64': undefined,130 'ubuntu18.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-18.04.zip',131 'ubuntu20.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',132 'ubuntu18.04-arm64': undefined,133 'ubuntu20.04-arm64': undefined,134 'mac10.13': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',135 'mac10.14': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',136 'mac10.15': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',137 'mac11': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',138 'mac11-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-11-arm64.zip',139 'mac12': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',140 'mac12-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-11-arm64.zip',141 'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip'142 },143 'webkit': {144 '<unknown>': undefined,145 'generic-linux': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',146 'generic-linux-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',147 'ubuntu18.04': 'builds/webkit/%s/webkit-ubuntu-18.04.zip',148 'ubuntu20.04': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',149 'ubuntu18.04-arm64': undefined,150 'ubuntu20.04-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',151 'mac10.13': undefined,152 'mac10.14': 'builds/deprecated-webkit-mac-10.14/%s/deprecated-webkit-mac-10.14.zip',153 'mac10.15': 'builds/webkit/%s/webkit-mac-10.15.zip',154 'mac11': 'builds/webkit/%s/webkit-mac-11.zip',155 'mac11-arm64': 'builds/webkit/%s/webkit-mac-11-arm64.zip',156 'mac12': 'builds/webkit/%s/webkit-mac-12.zip',157 'mac12-arm64': 'builds/webkit/%s/webkit-mac-12-arm64.zip',158 'win64': 'builds/webkit/%s/webkit-win64.zip'159 },160 'ffmpeg': {161 '<unknown>': undefined,162 'generic-linux': 'builds/ffmpeg/%s/ffmpeg-linux.zip',163 'generic-linux-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',164 'ubuntu18.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',165 'ubuntu20.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',166 'ubuntu18.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',167 'ubuntu20.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',168 'mac10.13': 'builds/ffmpeg/%s/ffmpeg-mac.zip',169 'mac10.14': 'builds/ffmpeg/%s/ffmpeg-mac.zip',170 'mac10.15': 'builds/ffmpeg/%s/ffmpeg-mac.zip',171 'mac11': 'builds/ffmpeg/%s/ffmpeg-mac.zip',172 'mac11-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',173 'mac12': 'builds/ffmpeg/%s/ffmpeg-mac.zip',174 'mac12-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',175 'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip'176 }177};178const registryDirectory = (() => {179 let result;180 const envDefined = (0, _utils.getFromENV)('PLAYWRIGHT_BROWSERS_PATH');181 if (envDefined === '0') {182 result = _path.default.join(__dirname, '..', '..', '..', '.local-browsers');183 } else if (envDefined) {184 result = envDefined;185 } else {186 let cacheDirectory;187 if (process.platform === 'linux') cacheDirectory = process.env.XDG_CACHE_HOME || _path.default.join(os.homedir(), '.cache');else if (process.platform === 'darwin') cacheDirectory = _path.default.join(os.homedir(), 'Library', 'Caches');else if (process.platform === 'win32') cacheDirectory = process.env.LOCALAPPDATA || _path.default.join(os.homedir(), 'AppData', 'Local');else throw new Error('Unsupported platform: ' + process.platform);188 result = _path.default.join(cacheDirectory, 'ms-playwright');189 }190 if (!_path.default.isAbsolute(result)) {191 // It is important to resolve to the absolute path:192 // - for unzipping to work correctly;193 // - so that registry directory matches between installation and execution.194 // INIT_CWD points to the root of `npm/yarn install` and is probably what195 // the user meant when typing the relative path.196 result = _path.default.resolve((0, _utils.getFromENV)('INIT_CWD') || process.cwd(), result);197 }198 return result;199})();200exports.registryDirectory = registryDirectory;201function isBrowserDirectory(browserDirectory) {202 const baseName = _path.default.basename(browserDirectory);203 for (const browserName of allDownloadable) {204 if (baseName.startsWith(browserName + '-')) return true;205 }206 return false;207}208function readDescriptors(browsersJSON) {209 return browsersJSON['browsers'].map(obj => {210 const name = obj.name;211 const revisionOverride = (obj.revisionOverrides || {})[_hostPlatform.hostPlatform];212 const revision = revisionOverride || obj.revision;213 const browserDirectoryPrefix = revisionOverride ? `${name}_${_hostPlatform.hostPlatform}_special` : `${name}`;214 const descriptor = {215 name,216 revision,217 installByDefault: !!obj.installByDefault,218 // Method `isBrowserDirectory` determines directory to be browser iff219 // it starts with some browser name followed by '-'. Some browser names220 // are prefixes of others, e.g. 'webkit' is a prefix of `webkit-technology-preview`.221 // To avoid older registries erroneously removing 'webkit-technology-preview', we have to222 // ensure that browser folders to never include dashes inside.223 dir: _path.default.join(registryDirectory, browserDirectoryPrefix.replace(/-/g, '_') + '-' + revision)224 };225 return descriptor;226 });227}228const allDownloadable = ['chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-with-symbols'];229class Registry {230 constructor(browsersJSON) {231 this._executables = void 0;232 const descriptors = readDescriptors(browsersJSON);233 const findExecutablePath = (dir, name) => {234 let tokens = undefined;235 if (_hostPlatform.hostPlatform.startsWith('ubuntu') || _hostPlatform.hostPlatform.startsWith('generic-linux')) tokens = EXECUTABLE_PATHS[name]['linux'];else if (_hostPlatform.hostPlatform.startsWith('mac')) tokens = EXECUTABLE_PATHS[name]['mac'];else if (_hostPlatform.hostPlatform.startsWith('win')) tokens = EXECUTABLE_PATHS[name]['win'];236 return tokens ? _path.default.join(dir, ...tokens) : undefined;237 };238 const executablePathOrDie = (name, e, installByDefault, sdkLanguage) => {239 if (!e) throw new Error(`${name} is not supported on ${_hostPlatform.hostPlatform}`);240 const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install${installByDefault ? '' : ' ' + name}`);241 if (!(0, _fileUtils.canAccessFile)(e)) {242 const prettyMessage = [`Looks like Playwright Test or Playwright was just installed or updated.`, `Please run the following command to download new browser${installByDefault ? 's' : ''}:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n');243 throw new Error(`Executable doesn't exist at ${e}\n${(0, _utils.wrapInASCIIBox)(prettyMessage, 1)}`);244 }245 return e;246 };247 this._executables = [];248 const chromium = descriptors.find(d => d.name === 'chromium');249 const chromiumExecutable = findExecutablePath(chromium.dir, 'chromium');250 this._executables.push({251 type: 'browser',252 name: 'chromium',253 browserName: 'chromium',254 directory: chromium.dir,255 executablePath: () => chromiumExecutable,256 executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),257 installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand',258 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromium.dir, ['chrome-linux'], [], ['chrome-win']),259 _install: () => this._downloadExecutable(chromium, chromiumExecutable, DOWNLOAD_PATHS['chromium'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'),260 _dependencyGroup: 'chromium',261 _isHermeticInstallation: true262 });263 const chromiumWithSymbols = descriptors.find(d => d.name === 'chromium-with-symbols');264 const chromiumWithSymbolsExecutable = findExecutablePath(chromiumWithSymbols.dir, 'chromium');265 this._executables.push({266 type: 'tool',267 name: 'chromium-with-symbols',268 browserName: 'chromium',269 directory: chromiumWithSymbols.dir,270 executablePath: () => chromiumWithSymbolsExecutable,271 executablePathOrDie: sdkLanguage => executablePathOrDie('chromium-with-symbols', chromiumWithSymbolsExecutable, chromiumWithSymbols.installByDefault, sdkLanguage),272 installType: chromiumWithSymbols.installByDefault ? 'download-by-default' : 'download-on-demand',273 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromiumWithSymbols.dir, ['chrome-linux'], [], ['chrome-win']),274 _install: () => this._downloadExecutable(chromiumWithSymbols, chromiumWithSymbolsExecutable, DOWNLOAD_PATHS['chromium-with-symbols'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'),275 _dependencyGroup: 'chromium',276 _isHermeticInstallation: true277 });278 this._executables.push(this._createChromiumChannel('chrome', {279 'linux': '/opt/google/chrome/chrome',280 'darwin': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',281 'win32': `\\Google\\Chrome\\Application\\chrome.exe`282 }, () => this._installChromiumChannel('chrome', {283 'linux': 'reinstall_chrome_stable_linux.sh',284 'darwin': 'reinstall_chrome_stable_mac.sh',285 'win32': 'reinstall_chrome_stable_win.ps1'286 })));287 this._executables.push(this._createChromiumChannel('chrome-beta', {288 'linux': '/opt/google/chrome-beta/chrome',289 'darwin': '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',290 'win32': `\\Google\\Chrome Beta\\Application\\chrome.exe`291 }, () => this._installChromiumChannel('chrome-beta', {292 'linux': 'reinstall_chrome_beta_linux.sh',293 'darwin': 'reinstall_chrome_beta_mac.sh',294 'win32': 'reinstall_chrome_beta_win.ps1'295 })));296 this._executables.push(this._createChromiumChannel('chrome-dev', {297 'linux': '/opt/google/chrome-unstable/chrome',298 'darwin': '/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev',299 'win32': `\\Google\\Chrome Dev\\Application\\chrome.exe`300 }));301 this._executables.push(this._createChromiumChannel('chrome-canary', {302 'linux': '',303 'darwin': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',304 'win32': `\\Google\\Chrome SxS\\Application\\chrome.exe`305 }));306 this._executables.push(this._createChromiumChannel('msedge', {307 'linux': '/opt/microsoft/msedge/msedge',308 'darwin': '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',309 'win32': `\\Microsoft\\Edge\\Application\\msedge.exe`310 }, () => this._installMSEdgeChannel('msedge', {311 'linux': 'reinstall_msedge_stable_linux.sh',312 'darwin': 'reinstall_msedge_stable_mac.sh',313 'win32': 'reinstall_msedge_stable_win.ps1'314 })));315 this._executables.push(this._createChromiumChannel('msedge-beta', {316 'linux': '/opt/microsoft/msedge-beta/msedge',317 'darwin': '/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta',318 'win32': `\\Microsoft\\Edge Beta\\Application\\msedge.exe`319 }, () => this._installMSEdgeChannel('msedge-beta', {320 'darwin': 'reinstall_msedge_beta_mac.sh',321 'linux': 'reinstall_msedge_beta_linux.sh',322 'win32': 'reinstall_msedge_beta_win.ps1'323 })));324 this._executables.push(this._createChromiumChannel('msedge-dev', {325 'linux': '/opt/microsoft/msedge-dev/msedge',326 'darwin': '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev',327 'win32': `\\Microsoft\\Edge Dev\\Application\\msedge.exe`328 }, () => this._installMSEdgeChannel('msedge-dev', {329 'darwin': 'reinstall_msedge_dev_mac.sh',330 'linux': 'reinstall_msedge_dev_linux.sh',331 'win32': 'reinstall_msedge_dev_win.ps1'332 })));333 this._executables.push(this._createChromiumChannel('msedge-canary', {334 'linux': '',335 'darwin': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary',336 'win32': `\\Microsoft\\Edge SxS\\Application\\msedge.exe`337 }));338 const firefox = descriptors.find(d => d.name === 'firefox');339 const firefoxExecutable = findExecutablePath(firefox.dir, 'firefox');340 this._executables.push({341 type: 'browser',342 name: 'firefox',343 browserName: 'firefox',344 directory: firefox.dir,345 executablePath: () => firefoxExecutable,346 executablePathOrDie: sdkLanguage => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage),347 installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand',348 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefox.dir, ['firefox'], [], ['firefox']),349 _install: () => this._downloadExecutable(firefox, firefoxExecutable, DOWNLOAD_PATHS['firefox'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'),350 _dependencyGroup: 'firefox',351 _isHermeticInstallation: true352 });353 const firefoxBeta = descriptors.find(d => d.name === 'firefox-beta');354 const firefoxBetaExecutable = findExecutablePath(firefoxBeta.dir, 'firefox');355 this._executables.push({356 type: 'tool',357 name: 'firefox-beta',358 browserName: 'firefox',359 directory: firefoxBeta.dir,360 executablePath: () => firefoxBetaExecutable,361 executablePathOrDie: sdkLanguage => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),362 installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand',363 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefoxBeta.dir, ['firefox'], [], ['firefox']),364 _install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable, DOWNLOAD_PATHS['firefox-beta'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'),365 _dependencyGroup: 'firefox',366 _isHermeticInstallation: true367 });368 const webkit = descriptors.find(d => d.name === 'webkit');369 const webkitExecutable = findExecutablePath(webkit.dir, 'webkit');370 const webkitLinuxLddDirectories = [_path.default.join('minibrowser-gtk'), _path.default.join('minibrowser-gtk', 'bin'), _path.default.join('minibrowser-gtk', 'lib'), _path.default.join('minibrowser-gtk', 'sys', 'lib'), _path.default.join('minibrowser-wpe'), _path.default.join('minibrowser-wpe', 'bin'), _path.default.join('minibrowser-wpe', 'lib'), _path.default.join('minibrowser-wpe', 'sys', 'lib')];371 this._executables.push({372 type: 'browser',373 name: 'webkit',374 browserName: 'webkit',375 directory: webkit.dir,376 executablePath: () => webkitExecutable,377 executablePathOrDie: sdkLanguage => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage),378 installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand',379 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'webkit', webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),380 _install: () => this._downloadExecutable(webkit, webkitExecutable, DOWNLOAD_PATHS['webkit'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST'),381 _dependencyGroup: 'webkit',382 _isHermeticInstallation: true383 });384 const ffmpeg = descriptors.find(d => d.name === 'ffmpeg');385 const ffmpegExecutable = findExecutablePath(ffmpeg.dir, 'ffmpeg');386 this._executables.push({387 type: 'tool',388 name: 'ffmpeg',389 browserName: undefined,390 directory: ffmpeg.dir,391 executablePath: () => ffmpegExecutable,392 executablePathOrDie: sdkLanguage => executablePathOrDie('ffmpeg', ffmpegExecutable, ffmpeg.installByDefault, sdkLanguage),393 installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand',394 validateHostRequirements: () => Promise.resolve(),395 _install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable, DOWNLOAD_PATHS['ffmpeg'][_hostPlatform.hostPlatform], 'PLAYWRIGHT_FFMPEG_DOWNLOAD_HOST'),396 _dependencyGroup: 'tools',397 _isHermeticInstallation: true398 });399 }400 _createChromiumChannel(name, lookAt, install) {401 const executablePath = (sdkLanguage, shouldThrow) => {402 const suffix = lookAt[process.platform];403 if (!suffix) {404 if (shouldThrow) throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`);405 return undefined;406 }407 const prefixes = process.platform === 'win32' ? [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']].filter(Boolean) : [''];408 for (const prefix of prefixes) {409 const executablePath = _path.default.join(prefix, suffix);410 if ((0, _fileUtils.canAccessFile)(executablePath)) return executablePath;411 }412 if (!shouldThrow) return undefined;413 const location = prefixes.length ? ` at ${_path.default.join(prefixes[0], suffix)}` : ``; // TODO: language-specific error message414 const installation = install ? `\nRun "${buildPlaywrightCLICommand(sdkLanguage, 'install ' + name)}"` : '';415 throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`);416 };417 return {418 type: 'channel',419 name,420 browserName: 'chromium',421 directory: undefined,422 executablePath: sdkLanguage => executablePath(sdkLanguage, false),423 executablePathOrDie: sdkLanguage => executablePath(sdkLanguage, true),424 installType: install ? 'install-script' : 'none',425 validateHostRequirements: () => Promise.resolve(),426 _isHermeticInstallation: false,427 _install: install428 };429 }430 executables() {431 return this._executables;432 }433 findExecutable(name) {434 return this._executables.find(b => b.name === name);435 }436 defaultExecutables() {437 return this._executables.filter(e => e.installType === 'download-by-default');438 }439 _addRequirementsAndDedupe(executables) {440 const set = new Set();441 for (const executable of executables) {442 set.add(executable);443 if (executable.browserName === 'chromium') set.add(this.findExecutable('ffmpeg'));444 }445 return Array.from(set);446 }447 async _validateHostRequirements(sdkLanguage, browserName, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) {448 if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {449 process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');450 return;451 }452 const ubuntuVersion = await (0, _ubuntuVersion.getUbuntuVersion)();453 if (browserName === 'firefox' && ubuntuVersion === '16.04') throw new Error(`Cannot launch Firefox on Ubuntu 16.04! Minimum required Ubuntu version for Firefox browser is 18.04`);454 if (os.platform() === 'linux') return await (0, _dependencies.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map(d => _path.default.join(browserDirectory, d)), dlOpenLibraries);455 if (os.platform() === 'win32' && os.arch() === 'x64') return await (0, _dependencies.validateDependenciesWindows)(windowsExeAndDllDirectories.map(d => _path.default.join(browserDirectory, d)));456 }457 async installDeps(executablesToInstallDeps, dryRun) {458 const executables = this._addRequirementsAndDedupe(executablesToInstallDeps);459 const targets = new Set();460 for (const executable of executables) {461 if (executable._dependencyGroup) targets.add(executable._dependencyGroup);462 }463 targets.add('tools');464 if (os.platform() === 'win32') return await (0, _dependencies.installDependenciesWindows)(targets, dryRun);465 if (os.platform() === 'linux') return await (0, _dependencies.installDependenciesLinux)(targets, dryRun);466 }467 async install(executablesToInstall, forceReinstall) {468 const executables = this._addRequirementsAndDedupe(executablesToInstall);469 await fs.promises.mkdir(registryDirectory, {470 recursive: true471 });472 const lockfilePath = _path.default.join(registryDirectory, '__dirlock');473 const linksDir = _path.default.join(registryDirectory, '.links');474 let releaseLock;475 try {476 releaseLock = await _properLockfile.default.lock(registryDirectory, {477 retries: {478 // Retry 20 times during 10 minutes with479 // exponential back-off.480 // See documentation at: https://www.npmjs.com/package/retry#retrytimeoutsoptions481 retries: 20,482 factor: 1.27579483 },484 onCompromised: err => {485 throw new Error(`${err.message} Path: ${lockfilePath}`);486 },487 lockfilePath488 }); // Create a link first, so that cache validation does not remove our own browsers.489 await fs.promises.mkdir(linksDir, {490 recursive: true491 });492 await fs.promises.writeFile(_path.default.join(linksDir, (0, _utils.calculateSha1)(PACKAGE_PATH)), PACKAGE_PATH); // Remove stale browsers.493 await this._validateInstallationCache(linksDir); // Install browsers for this package.494 for (const executable of executables) {495 if (!executable._install) throw new Error(`ERROR: Playwright does not support installing ${executable.name}`);496 const {497 langName498 } = (0, _userAgent.getClientLanguage)();499 if (!(0, _utils.getAsBooleanFromENV)('CI') && !executable._isHermeticInstallation && !forceReinstall && executable.executablePath(langName)) {500 const command = buildPlaywrightCLICommand(langName, 'install --force ' + executable.name);501 throw new Error('\n' + (0, _utils.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));502 }503 await executable._install();504 }505 } catch (e) {506 if (e.code === 'ELOCKED') {507 const rmCommand = process.platform === 'win32' ? 'rm -R' : 'rm -rf';508 throw new Error('\n' + (0, _utils.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));509 } else {510 throw e;511 }512 } finally {513 if (releaseLock) await releaseLock();514 }515 }516 async _downloadExecutable(descriptor, executablePath, downloadPathTemplate, downloadHostEnv) {517 if (!downloadPathTemplate || !executablePath) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${_hostPlatform.hostPlatform}`);518 if (_hostPlatform.hostPlatform === 'generic-linux' || _hostPlatform.hostPlatform === 'generic-linux-arm64') (0, _browserFetcher.logPolitely)('BEWARE: your OS is not officially supported by Playwright; downloading Ubuntu build as a fallback.');519 const downloadHost = downloadHostEnv && (0, _utils.getFromENV)(downloadHostEnv) || (0, _utils.getFromENV)('PLAYWRIGHT_DOWNLOAD_HOST') || 'https://playwright.azureedge.net';520 const downloadPath = util.format(downloadPathTemplate, descriptor.revision);521 const downloadURL = `${downloadHost}/${downloadPath}`;522 const title = `${descriptor.name} v${descriptor.revision}`;523 const downloadFileName = `playwright-download-${descriptor.name}-${_hostPlatform.hostPlatform}-${descriptor.revision}.zip`;524 await (0, _browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURL, downloadFileName).catch(e => {525 throw new Error(`Failed to download ${title}, caused by\n${e.stack}`);526 });527 await fs.promises.writeFile(markerFilePath(descriptor.dir), '');528 }529 async _installMSEdgeChannel(channel, scripts) {530 const scriptArgs = [];531 if (process.platform !== 'linux') {532 const products = JSON.parse(await (0, _netUtils.fetchData)({533 url: 'https://edgeupdates.microsoft.com/api/products'534 }));535 const productName = {536 'msedge': 'Stable',537 'msedge-beta': 'Beta',538 'msedge-dev': 'Dev'539 }[channel];540 const product = products.find(product => product.Product === productName);541 const searchConfig = {542 darwin: {543 platform: 'MacOS',544 arch: 'universal',545 artifact: 'pkg'546 },547 win32: {548 platform: 'Windows',549 arch: 'x64',550 artifact: 'msi'551 }552 }[process.platform];553 const release = searchConfig ? product.Releases.find(release => release.Platform === searchConfig.platform && release.Architecture === searchConfig.arch) : null;554 const artifact = release ? release.Artifacts.find(artifact => artifact.ArtifactName === searchConfig.artifact) : null;555 if (artifact) scriptArgs.push(artifact.Location556 /* url */557 );else throw new Error(`Cannot install ${channel} on ${process.platform}`);558 }559 await this._installChromiumChannel(channel, scripts, scriptArgs);560 }561 async _installChromiumChannel(channel, scripts, scriptArgs = []) {562 const scriptName = scripts[process.platform];563 if (!scriptName) throw new Error(`Cannot install ${channel} on ${process.platform}`);564 const cwd = BIN_PATH;565 const isPowerShell = scriptName.endsWith('.ps1');566 if (isPowerShell) {567 const args = ['-ExecutionPolicy', 'Bypass', '-File', _path.default.join(BIN_PATH, scriptName), ...scriptArgs];568 const {569 code570 } = await (0, _spawnAsync.spawnAsync)('powershell.exe', args, {571 cwd,572 stdio: 'inherit'573 });574 if (code !== 0) throw new Error(`Failed to install ${channel}`);575 } else {576 const {577 command,578 args,579 elevatedPermissions580 } = await (0, _dependencies.transformCommandsForRoot)([`bash "${_path.default.join(BIN_PATH, scriptName)}" ${scriptArgs.join('')}`]);581 if (elevatedPermissions) console.log('Switching to root user to install dependencies...'); // eslint-disable-line no-console582 const {583 code584 } = await (0, _spawnAsync.spawnAsync)(command, args, {585 cwd,586 stdio: 'inherit'587 });588 if (code !== 0) throw new Error(`Failed to install ${channel}`);589 }590 }591 async _validateInstallationCache(linksDir) {592 // 1. Collect used downloads and package descriptors.593 const usedBrowserPaths = new Set();594 for (const fileName of await fs.promises.readdir(linksDir)) {595 const linkPath = _path.default.join(linksDir, fileName);596 let linkTarget = '';597 try {598 linkTarget = (await fs.promises.readFile(linkPath)).toString();599 const browsersJSON = require(_path.default.join(linkTarget, 'browsers.json'));600 const descriptors = readDescriptors(browsersJSON);601 for (const browserName of allDownloadable) {602 // We retain browsers if they are found in the descriptor.603 // Note, however, that there are older versions out in the wild that rely on604 // the "download" field in the browser descriptor and use its value605 // to retain and download browsers.606 // As of v1.10, we decided to abandon "download" field.607 const descriptor = descriptors.find(d => d.name === browserName);608 if (!descriptor) continue;609 const usedBrowserPath = descriptor.dir;610 const browserRevision = parseInt(descriptor.revision, 10); // Old browser installations don't have marker file.611 const shouldHaveMarkerFile = browserName === 'chromium' && browserRevision >= 786218 || browserName === 'firefox' && browserRevision >= 1128 || browserName === 'webkit' && browserRevision >= 1307 || // All new applications have a marker file right away.612 browserName !== 'firefox' && browserName !== 'chromium' && browserName !== 'webkit';613 if (!shouldHaveMarkerFile || (await (0, _fileUtils.existsAsync)(markerFilePath(usedBrowserPath)))) usedBrowserPaths.add(usedBrowserPath);614 }615 } catch (e) {616 await fs.promises.unlink(linkPath).catch(e => {});617 }618 } // 2. Delete all unused browsers.619 if (!(0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_GC')) {620 let downloadedBrowsers = (await fs.promises.readdir(registryDirectory)).map(file => _path.default.join(registryDirectory, file));621 downloadedBrowsers = downloadedBrowsers.filter(file => isBrowserDirectory(file));622 const directories = new Set(downloadedBrowsers);623 for (const browserDirectory of usedBrowserPaths) directories.delete(browserDirectory);624 for (const directory of directories) (0, _browserFetcher.logPolitely)('Removing unused browser at ' + directory);625 await (0, _fileUtils.removeFolders)([...directories]);626 }627 }628}629exports.Registry = Registry;630function markerFilePath(browserDirectory) {631 return _path.default.join(browserDirectory, 'INSTALLATION_COMPLETE');632}633function buildPlaywrightCLICommand(sdkLanguage, parameters) {634 switch (sdkLanguage) {635 case 'python':636 return `playwright ${parameters}`;637 case 'java':638 return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="${parameters}"`;639 case 'csharp':640 return `pwsh bin\\Debug\\netX\\playwright.ps1 ${parameters}`;641 default:642 return `npx playwright ${parameters}`;643 }644}645async function installDefaultBrowsersForNpmInstall() {646 const defaultBrowserNames = registry.defaultExecutables().map(e => e.name);647 return installBrowsersForNpmInstall(defaultBrowserNames);648}649async function installBrowsersForNpmInstall(browsers) {650 // PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1651 if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {652 (0, _browserFetcher.logPolitely)('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set');653 return false;654 }655 const executables = [];656 for (const browserName of browsers) {657 const executable = registry.findExecutable(browserName);658 if (!executable || executable.installType === 'none') throw new Error(`Cannot install ${browserName}`);659 executables.push(executable);660 }661 await registry.install(executables, false662 /* forceReinstall */663 );664}665function findChromiumChannel(sdkLanguage) {666 // Fall back to the stable channels of popular vendors to work out of the box.667 // Null means no installation and no channels found.668 let channel = null;669 for (const name of ['chromium', 'chrome', 'msedge']) {670 try {671 registry.findExecutable(name).executablePathOrDie(sdkLanguage);672 channel = name === 'chromium' ? undefined : name;673 break;674 } catch (e) {}675 }676 if (channel === null) {677 const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install chromium`);678 const prettyMessage = [`No chromium-based browser found on the system.`, `Please run the following command to download one:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n');679 throw new Error('\n' + (0, _utils.wrapInASCIIBox)(prettyMessage, 1));680 }681 return channel;682}683const registry = new Registry(require('../../../browsers.json'));...
registry.js
Source:registry.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.Registry = void 0;6exports.buildPlaywrightCLICommand = buildPlaywrightCLICommand;7exports.findChromiumChannel = findChromiumChannel;8exports.installBrowsersForNpmInstall = installBrowsersForNpmInstall;9exports.installDefaultBrowsersForNpmInstall = installDefaultBrowsersForNpmInstall;10exports.registryDirectory = exports.registry = void 0;11var os = _interopRequireWildcard(require("os"));12var _path = _interopRequireDefault(require("path"));13var util = _interopRequireWildcard(require("util"));14var fs = _interopRequireWildcard(require("fs"));15var _properLockfile = _interopRequireDefault(require("proper-lockfile"));16var _ubuntuVersion = require("./ubuntuVersion");17var _utils = require("./utils");18var _dependencies = require("./dependencies");19var _browserFetcher = require("./browserFetcher");20function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }21function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }22function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }23/**24 * Copyright 2017 Google Inc. All rights reserved.25 * Modifications copyright (c) Microsoft Corporation.26 *27 * Licensed under the Apache License, Version 2.0 (the "License");28 * you may not use this file except in compliance with the License.29 * You may obtain a copy of the License at30 *31 * http://www.apache.org/licenses/LICENSE-2.032 *33 * Unless required by applicable law or agreed to in writing, software34 * distributed under the License is distributed on an "AS IS" BASIS,35 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.36 * See the License for the specific language governing permissions and37 * limitations under the License.38 */39const PACKAGE_PATH = _path.default.join(__dirname, '..', '..');40const BIN_PATH = _path.default.join(__dirname, '..', '..', 'bin');41const EXECUTABLE_PATHS = {42 'chromium': {43 'linux': ['chrome-linux', 'chrome'],44 'mac': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'],45 'win': ['chrome-win', 'chrome.exe']46 },47 'firefox': {48 'linux': ['firefox', 'firefox'],49 'mac': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'],50 'win': ['firefox', 'firefox.exe']51 },52 'webkit': {53 'linux': ['pw_run.sh'],54 'mac': ['pw_run.sh'],55 'win': ['Playwright.exe']56 },57 'ffmpeg': {58 'linux': ['ffmpeg-linux'],59 'mac': ['ffmpeg-mac'],60 'win': ['ffmpeg-win64.exe']61 }62};63const DOWNLOAD_PATHS = {64 'chromium': {65 'ubuntu18.04': 'builds/chromium/%s/chromium-linux.zip',66 'ubuntu20.04': 'builds/chromium/%s/chromium-linux.zip',67 'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',68 'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',69 'mac10.13': 'builds/chromium/%s/chromium-mac.zip',70 'mac10.14': 'builds/chromium/%s/chromium-mac.zip',71 'mac10.15': 'builds/chromium/%s/chromium-mac.zip',72 'mac11': 'builds/chromium/%s/chromium-mac.zip',73 'mac11-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',74 'mac12': 'builds/chromium/%s/chromium-mac.zip',75 'mac12-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',76 'win64': 'builds/chromium/%s/chromium-win64.zip'77 },78 'chromium-with-symbols': {79 'ubuntu18.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',80 'ubuntu20.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',81 'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',82 'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',83 'mac10.13': 'builds/chromium/%s/chromium-with-symbols-mac.zip',84 'mac10.14': 'builds/chromium/%s/chromium-with-symbols-mac.zip',85 'mac10.15': 'builds/chromium/%s/chromium-with-symbols-mac.zip',86 'mac11': 'builds/chromium/%s/chromium-with-symbols-mac.zip',87 'mac11-arm64': 'builds/chromium/%s/chromium-with-symbols-mac-arm64.zip',88 'mac12': 'builds/chromium/%s/chromium-with-symbols-mac.zip',89 'mac12-arm64': 'builds/chromium/%s/chromium-with-symbols-mac-arm64.zip',90 'win64': 'builds/chromium/%s/chromium-with-symbols-win64.zip'91 },92 'firefox': {93 'ubuntu18.04': 'builds/firefox/%s/firefox-ubuntu-18.04.zip',94 'ubuntu20.04': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',95 'ubuntu18.04-arm64': undefined,96 'ubuntu20.04-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',97 'mac10.13': 'builds/firefox/%s/firefox-mac-11.zip',98 'mac10.14': 'builds/firefox/%s/firefox-mac-11.zip',99 'mac10.15': 'builds/firefox/%s/firefox-mac-11.zip',100 'mac11': 'builds/firefox/%s/firefox-mac-11.zip',101 'mac11-arm64': 'builds/firefox/%s/firefox-mac-11-arm64.zip',102 'mac12': 'builds/firefox/%s/firefox-mac-11.zip',103 'mac12-arm64': 'builds/firefox/%s/firefox-mac-11-arm64.zip',104 'win64': 'builds/firefox/%s/firefox-win64.zip'105 },106 'firefox-beta': {107 'ubuntu18.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-18.04.zip',108 'ubuntu20.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',109 'ubuntu18.04-arm64': undefined,110 'ubuntu20.04-arm64': undefined,111 'mac10.13': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',112 'mac10.14': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',113 'mac10.15': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',114 'mac11': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',115 'mac11-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-11-arm64.zip',116 'mac12': 'builds/firefox-beta/%s/firefox-beta-mac-11.zip',117 'mac12-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-11-arm64.zip',118 'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip'119 },120 'webkit': {121 'ubuntu18.04': 'builds/webkit/%s/webkit-ubuntu-18.04.zip',122 'ubuntu20.04': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',123 'ubuntu18.04-arm64': undefined,124 'ubuntu20.04-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',125 'mac10.13': undefined,126 'mac10.14': 'builds/deprecated-webkit-mac-10.14/%s/deprecated-webkit-mac-10.14.zip',127 'mac10.15': 'builds/webkit/%s/webkit-mac-10.15.zip',128 'mac11': 'builds/webkit/%s/webkit-mac-10.15.zip',129 'mac11-arm64': 'builds/webkit/%s/webkit-mac-11-arm64.zip',130 'mac12': 'builds/webkit/%s/webkit-mac-12.zip',131 'mac12-arm64': 'builds/webkit/%s/webkit-mac-12-arm64.zip',132 'win64': 'builds/webkit/%s/webkit-win64.zip'133 },134 'ffmpeg': {135 'ubuntu18.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',136 'ubuntu20.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',137 'ubuntu18.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',138 'ubuntu20.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',139 'mac10.13': 'builds/ffmpeg/%s/ffmpeg-mac.zip',140 'mac10.14': 'builds/ffmpeg/%s/ffmpeg-mac.zip',141 'mac10.15': 'builds/ffmpeg/%s/ffmpeg-mac.zip',142 'mac11': 'builds/ffmpeg/%s/ffmpeg-mac.zip',143 'mac11-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',144 'mac12': 'builds/ffmpeg/%s/ffmpeg-mac.zip',145 'mac12-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',146 'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip'147 }148};149const registryDirectory = (() => {150 let result;151 const envDefined = (0, _utils.getFromENV)('PLAYWRIGHT_BROWSERS_PATH');152 if (envDefined === '0') {153 result = _path.default.join(__dirname, '..', '..', '.local-browsers');154 } else if (envDefined) {155 result = envDefined;156 } else {157 let cacheDirectory;158 if (process.platform === 'linux') cacheDirectory = process.env.XDG_CACHE_HOME || _path.default.join(os.homedir(), '.cache');else if (process.platform === 'darwin') cacheDirectory = _path.default.join(os.homedir(), 'Library', 'Caches');else if (process.platform === 'win32') cacheDirectory = process.env.LOCALAPPDATA || _path.default.join(os.homedir(), 'AppData', 'Local');else throw new Error('Unsupported platform: ' + process.platform);159 result = _path.default.join(cacheDirectory, 'ms-playwright');160 }161 if (!_path.default.isAbsolute(result)) {162 // It is important to resolve to the absolute path:163 // - for unzipping to work correctly;164 // - so that registry directory matches between installation and execution.165 // INIT_CWD points to the root of `npm/yarn install` and is probably what166 // the user meant when typing the relative path.167 result = _path.default.resolve((0, _utils.getFromENV)('INIT_CWD') || process.cwd(), result);168 }169 return result;170})();171exports.registryDirectory = registryDirectory;172function isBrowserDirectory(browserDirectory) {173 const baseName = _path.default.basename(browserDirectory);174 for (const browserName of allDownloadable) {175 if (baseName.startsWith(browserName + '-')) return true;176 }177 return false;178}179function readDescriptors(browsersJSON) {180 return browsersJSON['browsers'].map(obj => {181 const name = obj.name;182 const revisionOverride = (obj.revisionOverrides || {})[_utils.hostPlatform];183 const revision = revisionOverride || obj.revision;184 const browserDirectoryPrefix = revisionOverride ? `${name}_${_utils.hostPlatform}_special` : `${name}`;185 const descriptor = {186 name,187 revision,188 installByDefault: !!obj.installByDefault,189 // Method `isBrowserDirectory` determines directory to be browser iff190 // it starts with some browser name followed by '-'. Some browser names191 // are prefixes of others, e.g. 'webkit' is a prefix of `webkit-technology-preview`.192 // To avoid older registries erroneously removing 'webkit-technology-preview', we have to193 // ensure that browser folders to never include dashes inside.194 dir: _path.default.join(registryDirectory, browserDirectoryPrefix.replace(/-/g, '_') + '-' + revision)195 };196 return descriptor;197 });198}199const allDownloadable = ['chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-with-symbols'];200class Registry {201 constructor(browsersJSON) {202 this._executables = void 0;203 const descriptors = readDescriptors(browsersJSON);204 const findExecutablePath = (dir, name) => {205 let tokens = undefined;206 if (_utils.hostPlatform.startsWith('ubuntu')) tokens = EXECUTABLE_PATHS[name]['linux'];else if (_utils.hostPlatform.startsWith('mac')) tokens = EXECUTABLE_PATHS[name]['mac'];else if (_utils.hostPlatform.startsWith('win')) tokens = EXECUTABLE_PATHS[name]['win'];207 return tokens ? _path.default.join(dir, ...tokens) : undefined;208 };209 const executablePathOrDie = (name, e, installByDefault, sdkLanguage) => {210 if (!e) throw new Error(`${name} is not supported on ${_utils.hostPlatform}`);211 const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install${installByDefault ? '' : ' ' + name}`);212 if (!(0, _utils.canAccessFile)(e)) {213 const prettyMessage = [`Looks like Playwright Test or Playwright was just installed or updated.`, `Please run the following command to download new browser${installByDefault ? 's' : ''}:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n');214 throw new Error(`Executable doesn't exist at ${e}\n${(0, _utils.wrapInASCIIBox)(prettyMessage, 1)}`);215 }216 return e;217 };218 this._executables = [];219 const chromium = descriptors.find(d => d.name === 'chromium');220 const chromiumExecutable = findExecutablePath(chromium.dir, 'chromium');221 this._executables.push({222 type: 'browser',223 name: 'chromium',224 browserName: 'chromium',225 directory: chromium.dir,226 executablePath: () => chromiumExecutable,227 executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),228 installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand',229 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromium.dir, ['chrome-linux'], [], ['chrome-win']),230 _install: () => this._downloadExecutable(chromium, chromiumExecutable, DOWNLOAD_PATHS['chromium'][_utils.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'),231 _dependencyGroup: 'chromium'232 });233 const chromiumWithSymbols = descriptors.find(d => d.name === 'chromium-with-symbols');234 const chromiumWithSymbolsExecutable = findExecutablePath(chromiumWithSymbols.dir, 'chromium');235 this._executables.push({236 type: 'tool',237 name: 'chromium-with-symbols',238 browserName: 'chromium',239 directory: chromiumWithSymbols.dir,240 executablePath: () => chromiumWithSymbolsExecutable,241 executablePathOrDie: sdkLanguage => executablePathOrDie('chromium-with-symbols', chromiumWithSymbolsExecutable, chromiumWithSymbols.installByDefault, sdkLanguage),242 installType: chromiumWithSymbols.installByDefault ? 'download-by-default' : 'download-on-demand',243 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromiumWithSymbols.dir, ['chrome-linux'], [], ['chrome-win']),244 _install: () => this._downloadExecutable(chromiumWithSymbols, chromiumWithSymbolsExecutable, DOWNLOAD_PATHS['chromium-with-symbols'][_utils.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'),245 _dependencyGroup: 'chromium'246 });247 this._executables.push(this._createChromiumChannel('chrome', {248 'linux': '/opt/google/chrome/chrome',249 'darwin': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',250 'win32': `\\Google\\Chrome\\Application\\chrome.exe`251 }, () => this._installChromiumChannel('chrome', {252 'linux': 'reinstall_chrome_stable_linux.sh',253 'darwin': 'reinstall_chrome_stable_mac.sh',254 'win32': 'reinstall_chrome_stable_win.ps1'255 })));256 this._executables.push(this._createChromiumChannel('chrome-beta', {257 'linux': '/opt/google/chrome-beta/chrome',258 'darwin': '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',259 'win32': `\\Google\\Chrome Beta\\Application\\chrome.exe`260 }, () => this._installChromiumChannel('chrome-beta', {261 'linux': 'reinstall_chrome_beta_linux.sh',262 'darwin': 'reinstall_chrome_beta_mac.sh',263 'win32': 'reinstall_chrome_beta_win.ps1'264 })));265 this._executables.push(this._createChromiumChannel('chrome-dev', {266 'linux': '/opt/google/chrome-unstable/chrome',267 'darwin': '/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev',268 'win32': `\\Google\\Chrome Dev\\Application\\chrome.exe`269 }));270 this._executables.push(this._createChromiumChannel('chrome-canary', {271 'linux': '',272 'darwin': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',273 'win32': `\\Google\\Chrome SxS\\Application\\chrome.exe`274 }));275 this._executables.push(this._createChromiumChannel('msedge', {276 'linux': '/opt/microsoft/msedge/msedge',277 'darwin': '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',278 'win32': `\\Microsoft\\Edge\\Application\\msedge.exe`279 }, () => this._installMSEdgeChannel('msedge', {280 'linux': 'reinstall_msedge_stable_linux.sh',281 'darwin': 'reinstall_msedge_stable_mac.sh',282 'win32': 'reinstall_msedge_stable_win.ps1'283 })));284 this._executables.push(this._createChromiumChannel('msedge-beta', {285 'linux': '/opt/microsoft/msedge-beta/msedge',286 'darwin': '/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta',287 'win32': `\\Microsoft\\Edge Beta\\Application\\msedge.exe`288 }, () => this._installMSEdgeChannel('msedge-beta', {289 'darwin': 'reinstall_msedge_beta_mac.sh',290 'linux': 'reinstall_msedge_beta_linux.sh',291 'win32': 'reinstall_msedge_beta_win.ps1'292 })));293 this._executables.push(this._createChromiumChannel('msedge-dev', {294 'linux': '/opt/microsoft/msedge-dev/msedge',295 'darwin': '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev',296 'win32': `\\Microsoft\\Edge Dev\\Application\\msedge.exe`297 }, () => this._installMSEdgeChannel('msedge-dev', {298 'darwin': 'reinstall_msedge_dev_mac.sh',299 'linux': 'reinstall_msedge_dev_linux.sh',300 'win32': 'reinstall_msedge_dev_win.ps1'301 })));302 this._executables.push(this._createChromiumChannel('msedge-canary', {303 'linux': '',304 'darwin': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary',305 'win32': `\\Microsoft\\Edge SxS\\Application\\msedge.exe`306 }));307 const firefox = descriptors.find(d => d.name === 'firefox');308 const firefoxExecutable = findExecutablePath(firefox.dir, 'firefox');309 this._executables.push({310 type: 'browser',311 name: 'firefox',312 browserName: 'firefox',313 directory: firefox.dir,314 executablePath: () => firefoxExecutable,315 executablePathOrDie: sdkLanguage => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage),316 installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand',317 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefox.dir, ['firefox'], [], ['firefox']),318 _install: () => this._downloadExecutable(firefox, firefoxExecutable, DOWNLOAD_PATHS['firefox'][_utils.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'),319 _dependencyGroup: 'firefox'320 });321 const firefoxBeta = descriptors.find(d => d.name === 'firefox-beta');322 const firefoxBetaExecutable = findExecutablePath(firefoxBeta.dir, 'firefox');323 this._executables.push({324 type: 'tool',325 name: 'firefox-beta',326 browserName: 'firefox',327 directory: firefoxBeta.dir,328 executablePath: () => firefoxBetaExecutable,329 executablePathOrDie: sdkLanguage => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),330 installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand',331 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefoxBeta.dir, ['firefox'], [], ['firefox']),332 _install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable, DOWNLOAD_PATHS['firefox-beta'][_utils.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'),333 _dependencyGroup: 'firefox'334 });335 const webkit = descriptors.find(d => d.name === 'webkit');336 const webkitExecutable = findExecutablePath(webkit.dir, 'webkit');337 const webkitLinuxLddDirectories = [_path.default.join('minibrowser-gtk'), _path.default.join('minibrowser-gtk', 'bin'), _path.default.join('minibrowser-gtk', 'lib'), _path.default.join('minibrowser-wpe'), _path.default.join('minibrowser-wpe', 'bin'), _path.default.join('minibrowser-wpe', 'lib')];338 this._executables.push({339 type: 'browser',340 name: 'webkit',341 browserName: 'webkit',342 directory: webkit.dir,343 executablePath: () => webkitExecutable,344 executablePathOrDie: sdkLanguage => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage),345 installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand',346 validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'webkit', webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),347 _install: () => this._downloadExecutable(webkit, webkitExecutable, DOWNLOAD_PATHS['webkit'][_utils.hostPlatform], 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST'),348 _dependencyGroup: 'webkit'349 });350 const ffmpeg = descriptors.find(d => d.name === 'ffmpeg');351 const ffmpegExecutable = findExecutablePath(ffmpeg.dir, 'ffmpeg');352 this._executables.push({353 type: 'tool',354 name: 'ffmpeg',355 browserName: undefined,356 directory: ffmpeg.dir,357 executablePath: () => ffmpegExecutable,358 executablePathOrDie: sdkLanguage => executablePathOrDie('ffmpeg', ffmpegExecutable, ffmpeg.installByDefault, sdkLanguage),359 installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand',360 validateHostRequirements: () => Promise.resolve(),361 _install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable, DOWNLOAD_PATHS['ffmpeg'][_utils.hostPlatform], 'PLAYWRIGHT_FFMPEG_DOWNLOAD_HOST'),362 _dependencyGroup: 'tools'363 });364 }365 _createChromiumChannel(name, lookAt, install) {366 const executablePath = (sdkLanguage, shouldThrow) => {367 const suffix = lookAt[process.platform];368 if (!suffix) {369 if (shouldThrow) throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`);370 return undefined;371 }372 const prefixes = process.platform === 'win32' ? [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']].filter(Boolean) : [''];373 for (const prefix of prefixes) {374 const executablePath = _path.default.join(prefix, suffix);375 if ((0, _utils.canAccessFile)(executablePath)) return executablePath;376 }377 if (!shouldThrow) return undefined;378 const location = prefixes.length ? ` at ${_path.default.join(prefixes[0], suffix)}` : ``; // TODO: language-specific error message379 const installation = install ? `\nRun "${buildPlaywrightCLICommand(sdkLanguage, 'install ' + name)}"` : '';380 throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`);381 };382 return {383 type: 'channel',384 name,385 browserName: 'chromium',386 directory: undefined,387 executablePath: sdkLanguage => executablePath(sdkLanguage, false),388 executablePathOrDie: sdkLanguage => executablePath(sdkLanguage, true),389 installType: install ? 'install-script' : 'none',390 validateHostRequirements: () => Promise.resolve(),391 _install: install392 };393 }394 executables() {395 return this._executables;396 }397 findExecutable(name) {398 return this._executables.find(b => b.name === name);399 }400 defaultExecutables() {401 return this._executables.filter(e => e.installType === 'download-by-default');402 }403 _addRequirementsAndDedupe(executables) {404 const set = new Set();405 for (const executable of executables) {406 set.add(executable);407 if (executable.browserName === 'chromium') set.add(this.findExecutable('ffmpeg'));408 }409 return Array.from(set);410 }411 async _validateHostRequirements(sdkLanguage, browserName, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) {412 if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {413 process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');414 return;415 }416 const ubuntuVersion = await (0, _ubuntuVersion.getUbuntuVersion)();417 if (browserName === 'firefox' && ubuntuVersion === '16.04') throw new Error(`Cannot launch Firefox on Ubuntu 16.04! Minimum required Ubuntu version for Firefox browser is 18.04`);418 if (os.platform() === 'linux') return await (0, _dependencies.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map(d => _path.default.join(browserDirectory, d)), dlOpenLibraries);419 if (os.platform() === 'win32' && os.arch() === 'x64') return await (0, _dependencies.validateDependenciesWindows)(windowsExeAndDllDirectories.map(d => _path.default.join(browserDirectory, d)));420 }421 async installDeps(executablesToInstallDeps, dryRun) {422 const executables = this._addRequirementsAndDedupe(executablesToInstallDeps);423 const targets = new Set();424 for (const executable of executables) {425 if (executable._dependencyGroup) targets.add(executable._dependencyGroup);426 }427 targets.add('tools');428 if (os.platform() === 'win32') return await (0, _dependencies.installDependenciesWindows)(targets, dryRun);429 if (os.platform() === 'linux') return await (0, _dependencies.installDependenciesLinux)(targets, dryRun);430 }431 async install(executablesToInstall) {432 const executables = this._addRequirementsAndDedupe(executablesToInstall);433 await fs.promises.mkdir(registryDirectory, {434 recursive: true435 });436 const lockfilePath = _path.default.join(registryDirectory, '__dirlock');437 const linksDir = _path.default.join(registryDirectory, '.links');438 let releaseLock;439 try {440 releaseLock = await _properLockfile.default.lock(registryDirectory, {441 retries: {442 // Retry 20 times during 10 minutes with443 // exponential back-off.444 // See documentation at: https://www.npmjs.com/package/retry#retrytimeoutsoptions445 retries: 20,446 factor: 1.27579447 },448 onCompromised: err => {449 throw new Error(`${err.message} Path: ${lockfilePath}`);450 },451 lockfilePath452 }); // Create a link first, so that cache validation does not remove our own browsers.453 await fs.promises.mkdir(linksDir, {454 recursive: true455 });456 await fs.promises.writeFile(_path.default.join(linksDir, (0, _utils.calculateSha1)(PACKAGE_PATH)), PACKAGE_PATH); // Remove stale browsers.457 await this._validateInstallationCache(linksDir); // Install browsers for this package.458 for (const executable of executables) {459 if (executable._install) await executable._install();else throw new Error(`ERROR: Playwright does not support installing ${executable.name}`);460 }461 } catch (e) {462 if (e.code === 'ELOCKED') {463 const rmCommand = process.platform === 'win32' ? 'rm -R' : 'rm -rf';464 throw new Error('\n' + (0, _utils.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));465 } else {466 throw e;467 }468 } finally {469 if (releaseLock) await releaseLock();470 }471 }472 async _downloadExecutable(descriptor, executablePath, downloadPathTemplate, downloadHostEnv) {473 if (!downloadPathTemplate || !executablePath) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${_utils.hostPlatform}`);474 const downloadHost = downloadHostEnv && (0, _utils.getFromENV)(downloadHostEnv) || (0, _utils.getFromENV)('PLAYWRIGHT_DOWNLOAD_HOST') || 'https://playwright.azureedge.net';475 const downloadPath = util.format(downloadPathTemplate, descriptor.revision);476 const downloadURL = `${downloadHost}/${downloadPath}`;477 const title = `${descriptor.name} v${descriptor.revision}`;478 const downloadFileName = `playwright-download-${descriptor.name}-${_utils.hostPlatform}-${descriptor.revision}.zip`;479 await (0, _browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURL, downloadFileName).catch(e => {480 throw new Error(`Failed to download ${title}, caused by\n${e.stack}`);481 });482 await fs.promises.writeFile(markerFilePath(descriptor.dir), '');483 }484 async _installMSEdgeChannel(channel, scripts) {485 const scriptArgs = [];486 if (process.platform !== 'linux') {487 const products = JSON.parse(await (0, _utils.fetchData)({488 url: 'https://edgeupdates.microsoft.com/api/products'489 }));490 const productName = {491 'msedge': 'Stable',492 'msedge-beta': 'Beta',493 'msedge-dev': 'Dev'494 }[channel];495 const product = products.find(product => product.Product === productName);496 const searchConfig = {497 darwin: {498 platform: 'MacOS',499 arch: 'universal',500 artifact: 'pkg'501 },502 win32: {503 platform: 'Windows',504 arch: 'x64',505 artifact: 'msi'506 }507 }[process.platform];508 const release = searchConfig ? product.Releases.find(release => release.Platform === searchConfig.platform && release.Architecture === searchConfig.arch) : null;509 const artifact = release ? release.Artifacts.find(artifact => artifact.ArtifactName === searchConfig.artifact) : null;510 if (artifact) scriptArgs.push(artifact.Location511 /* url */512 );else throw new Error(`Cannot install ${channel} on ${process.platform}`);513 }514 await this._installChromiumChannel(channel, scripts, scriptArgs);515 }516 async _installChromiumChannel(channel, scripts, scriptArgs = []) {517 const scriptName = scripts[process.platform];518 if (!scriptName) throw new Error(`Cannot install ${channel} on ${process.platform}`);519 const cwd = BIN_PATH;520 const isPowerShell = scriptName.endsWith('.ps1');521 if (isPowerShell) {522 const args = ['-ExecutionPolicy', 'Bypass', '-File', _path.default.join(BIN_PATH, scriptName), ...scriptArgs];523 const {524 code525 } = await (0, _utils.spawnAsync)('powershell.exe', args, {526 cwd,527 stdio: 'inherit'528 });529 if (code !== 0) throw new Error(`Failed to install ${channel}`);530 } else {531 const {532 command,533 args,534 elevatedPermissions535 } = await (0, _utils.transformCommandsForRoot)([`bash ${_path.default.join(BIN_PATH, scriptName)} ${scriptArgs.join('')}`]);536 if (elevatedPermissions) console.log('Switching to root user to install dependencies...'); // eslint-disable-line no-console537 const {538 code539 } = await (0, _utils.spawnAsync)(command, args, {540 cwd,541 stdio: 'inherit'542 });543 if (code !== 0) throw new Error(`Failed to install ${channel}`);544 }545 }546 async _validateInstallationCache(linksDir) {547 // 1. Collect used downloads and package descriptors.548 const usedBrowserPaths = new Set();549 for (const fileName of await fs.promises.readdir(linksDir)) {550 const linkPath = _path.default.join(linksDir, fileName);551 let linkTarget = '';552 try {553 linkTarget = (await fs.promises.readFile(linkPath)).toString();554 const browsersJSON = require(_path.default.join(linkTarget, 'browsers.json'));555 const descriptors = readDescriptors(browsersJSON);556 for (const browserName of allDownloadable) {557 // We retain browsers if they are found in the descriptor.558 // Note, however, that there are older versions out in the wild that rely on559 // the "download" field in the browser descriptor and use its value560 // to retain and download browsers.561 // As of v1.10, we decided to abandon "download" field.562 const descriptor = descriptors.find(d => d.name === browserName);563 if (!descriptor) continue;564 const usedBrowserPath = descriptor.dir;565 const browserRevision = parseInt(descriptor.revision, 10); // Old browser installations don't have marker file.566 const shouldHaveMarkerFile = browserName === 'chromium' && browserRevision >= 786218 || browserName === 'firefox' && browserRevision >= 1128 || browserName === 'webkit' && browserRevision >= 1307 || // All new applications have a marker file right away.567 browserName !== 'firefox' && browserName !== 'chromium' && browserName !== 'webkit';568 if (!shouldHaveMarkerFile || (await (0, _utils.existsAsync)(markerFilePath(usedBrowserPath)))) usedBrowserPaths.add(usedBrowserPath);569 }570 } catch (e) {571 await fs.promises.unlink(linkPath).catch(e => {});572 }573 } // 2. Delete all unused browsers.574 if (!(0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_GC')) {575 let downloadedBrowsers = (await fs.promises.readdir(registryDirectory)).map(file => _path.default.join(registryDirectory, file));576 downloadedBrowsers = downloadedBrowsers.filter(file => isBrowserDirectory(file));577 const directories = new Set(downloadedBrowsers);578 for (const browserDirectory of usedBrowserPaths) directories.delete(browserDirectory);579 for (const directory of directories) (0, _browserFetcher.logPolitely)('Removing unused browser at ' + directory);580 await (0, _utils.removeFolders)([...directories]);581 }582 }583}584exports.Registry = Registry;585function markerFilePath(browserDirectory) {586 return _path.default.join(browserDirectory, 'INSTALLATION_COMPLETE');587}588function buildPlaywrightCLICommand(sdkLanguage, parameters) {589 switch (sdkLanguage) {590 case 'python':591 return `playwright ${parameters}`;592 case 'java':593 return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="${parameters}"`;594 case 'csharp':595 return `playwright ${parameters}`;596 default:597 return `npx playwright ${parameters}`;598 }599}600async function installDefaultBrowsersForNpmInstall() {601 const defaultBrowserNames = registry.defaultExecutables().map(e => e.name);602 return installBrowsersForNpmInstall(defaultBrowserNames);603}604async function installBrowsersForNpmInstall(browsers) {605 // PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1606 if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {607 (0, _browserFetcher.logPolitely)('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set');608 return false;609 }610 const executables = [];611 for (const browserName of browsers) {612 const executable = registry.findExecutable(browserName);613 if (!executable || executable.installType === 'none') throw new Error(`Cannot install ${browserName}`);614 executables.push(executable);615 }616 await registry.install(executables);617}618function findChromiumChannel(sdkLanguage) {619 // Fall back to the stable channels of popular vendors to work out of the box.620 // Null means no installation and no channels found.621 let channel = null;622 for (const name of ['chromium', 'chrome', 'msedge']) {623 try {624 registry.findExecutable(name).executablePathOrDie(sdkLanguage);625 channel = name === 'chromium' ? undefined : name;626 break;627 } catch (e) {}628 }629 if (channel === null) {630 const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install chromium`);631 const prettyMessage = [`No chromium-based browser found on the system.`, `Please run the following command to download one:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n');632 throw new Error('\n' + (0, _utils.wrapInASCIIBox)(prettyMessage, 1));633 }634 return channel;635}636const registry = new Registry(require('../../browsers.json'));...
download-chromium.js
Source:download-chromium.js
...42 const downloadFileName = `playwright-download-chromium-${platform}-${revision}.zip`;43 try {44 // eslint-disable-next-line no-console45 console.info('Downloading browser ', title);46 await downloadBrowserWithProgressBar(47 title,48 directory,49 executablePath,50 downloadURL,51 downloadFileName52 );53 } catch (e) {54 throw new Error(`Failed to download ${title}, caused by\n${e.stack}`);55 }56}57function findExecutablePath(dir, platform) {58 const tokens = EXECUTABLE_PATHS[platform];59 return tokens ? path.join(dir, ...tokens) : undefined;60}...
browserFetcher.js
Source:browserFetcher.js
...26 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.27 * See the License for the specific language governing permissions and28 * limitations under the License.29 */30async function downloadBrowserWithProgressBar(title, browserDirectory, executablePath, downloadURL, downloadFileName) {31 const progressBarName = `Playwright build of ${title}`;32 if (await (0, _utils.existsAsync)(browserDirectory)) {33 // Already downloaded.34 _debugLogger.debugLogger.log('install', `browser ${title} is already downloaded.`);35 return false;36 }37 const url = downloadURL;38 const zipPath = _path.default.join(_os.default.tmpdir(), downloadFileName);39 try {40 await (0, _utils.download)(url, zipPath, {41 progressBarName,42 log: _debugLogger.debugLogger.log.bind(_debugLogger.debugLogger, 'install'),43 userAgent: (0, _utils.getUserAgent)()44 });...
Using AI Code Generation
1const playwright = require('playwright');2const fs = require('fs');3(async () => {4 const browser = await playwright.chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const downloadPath = 'C:\\Users\\Downloads\\';8 console.log(download);9 await browser.close();10})();11 at CDPSession.send (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:129:13)12 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)13 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)14 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)15 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)16 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)17 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)18 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)19 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)20 at async CDPSession.sendMayFail (C:\Users\Downloads\playwright\playwright\lib\cdp\cdpSession.js:149:24)
Using AI Code Generation
1const downloadBrowserWithProgressBar = require('playwright/lib/server/downloadBrowserWithProgressBar');2const browserFetcher = require('playwright/lib/server/browserFetcher');3const { spawn } = require('child_process');4const path = require('path');5const os = require('os');6const fs = require('fs');7const { chromium } = require('playwright');8const { downloadBrowserWithProgressBar } = require('playwright/lib/server/downloadBrowserWithProgressBar');9const { browserFetcher } = require('playwright/lib/server/browserFetcher');10const browserFetcher = browserFetcher();11const browserName = 'chromium';12const browserPath = browserFetcher.revisionInfo(browserName, '809590').downloadPath;13const browser = await chromium.launch({executablePath: browserPath});14const downloadBrowserWithProgressBar = require('playwright/lib/server/downloadBrowserWithProgressBar');15const browserFetcher = require('playwright/lib/server/browserFetcher');16const { spawn } = require('child_process');17const path = require('path');18const os = require('os');19const fs = require('fs');20const { chromium } = require('playwright');21const { downloadBrowserWithProgressBar } = require('playwright/lib/server/downloadBrowserWithProgressBar');22const { browserFetcher } = require('playwright/lib/server/browserFetcher');23const browserFetcher = browserFetcher();24const browserName = 'chromium';25const browserPath = browserFetcher.revisionInfo(browserName, '809590').downloadPath;26const browser = await chromium.launch({executablePath: browserPath});27const downloadBrowserWithProgressBar = require('playwright/lib/server/downloadBrowserWithProgressBar');28const browserFetcher = require('playwright/lib/server/browserFetcher');29const { spawn } = require('child_process');30const path = require('path');31const os = require('os');32const fs = require('fs');33const { chromium } = require('playwright');34const { downloadBrowserWithProgressBar } = require('playwright/lib/server/downloadBrowserWithProgressBar');35const { browserFetcher } = require('playwright/lib/server/browserFetcher');36const browserFetcher = browserFetcher();37const browserName = 'chromium';38const browserPath = browserFetcher.revisionInfo(browserName, '809590').downloadPath;39const browser = await chromium.launch({executablePath: browserPath});
Using AI Code Generation
1const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');2const browserName = 'chromium';3const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');4console.log(browserPath);5const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');6const browserName = 'chromium';7const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');8console.log(browserPath);9const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');10const browserName = 'chromium';11const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');12console.log(browserPath);13const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');14const browserName = 'chromium';15const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');16console.log(browserPath);17const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');18const browserName = 'chromium';19const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');20console.log(browserPath);21const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');22const browserName = 'chromium';23const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');24console.log(browserPath);25const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserPaths');26const browserName = 'chromium';27const browserPath = await downloadBrowserWithProgressBar(browserName, '0.12.1');28console.log(browserPath);29const { downloadBrowserWithProgressBar }
Using AI Code Generation
1const { downloadBrowserWithProgressBar } = require('playwright/lib/server/download');2const path = require('path');3const fs = require('fs');4const ProgressBar = require('progress');5const util = require('util');6const { chromium } = require('playwright');7const { spawn } = require('child_process');8const { promisify } = require('util');9const exec = promisify(require('child_process').exec);10const { downloadBrowserWithProgressBar } = require('playwright/lib/server/download');11const downloadBrowser = async (browserName, browserRevision, progressBar) => {12 const browserPath = await downloadBrowserWithProgressBar(browserName, browserRevision, progressBar);13 const browserDirectory = path.dirname(browserPath);14 const browserExecutable = path.basename(browserPath);15 await exec(`chmod +x ${path.join(browserDirectory, browserExecutable)}`);16 return browserPath;17};18(async () => {19 const progressBar = new ProgressBar('Downloading Chromium [:bar] :percent :etas', {20 });21 const browserPath = await downloadBrowser('chromium', '869685', progressBar);22 const browser = await chromium.launch({23 });24 const page = await browser.newPage();25 await page.screenshot({ path: 'google.png' });26 await browser.close();27})();28{29 "scripts": {30 },31 "dependencies": {32 }33}
Using AI Code Generation
1const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserFetcher');2const browserFetcher = new BrowserFetcher();3const progressBar = new ProgressBar();4await downloadBrowserWithProgressBar(browserFetcher, progressBar, 'chromium', '1.2.3');5const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserFetcher');6const browserFetcher = new BrowserFetcher();7const progressBar = new ProgressBar();8await downloadBrowserWithProgressBar(browserFetcher, progressBar, 'firefox', '1.2.3');9const { downloadBrowserWithProgressBar } = require('playwright/lib/utils/browserFetcher');10const browserFetcher = new BrowserFetcher();11const progressBar = new ProgressBar();12await downloadBrowserWithProgressBar(browserFetcher, progressBar, 'webkit', '1.2.3');
Using AI Code Generation
1const { downloadBrowserWithProgressBar } = require('@playwright/test');2const { chromium } = require('playwright-chromium');3await downloadBrowserWithProgressBar(chromium, {4 onProgress: (downloadedBytes, totalBytes) => {5 console.log(`${(downloadedBytes / totalBytes * 100).toFixed(2)}%`);6 },7});8const { chromium } = require('playwright-chromium');9const browser = await chromium.launch();10const { test } = require('@playwright/test');11test('My test', async ({ page }) => {12});
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!