Best JavaScript code snippet using playwright-internal
index.js
Source:index.js
...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':...
registry.js
Source:registry.js
...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':...
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const result = await page.evaluate(async () => {7 const { isBrowserDirectory } = require('@playwright/test/lib/utils/utils');8 return await isBrowserDirectory('/tmp');9 });10 console.log(result);11 await browser.close();12})();
Using AI Code Generation
1const { isBrowserDirectory } = require('playwright/lib/utils/utils');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 console.log(await isBrowserDirectory(browser._browserContext._browser._options.browserDirectory));6 await browser.close();7})();
Using AI Code Generation
1import { isBrowserDirectory } from 'playwright/internal/utils/utils';2import { isBrowserDirectory } from 'playwright/internal/utils/utils';3import { isBrowserDirectory } from 'playwright/internal/utils/utils';4import { isBrowserDirectory } from 'playwright/internal/utils/utils';5import { isBrowserDirectory } from 'playwright/internal/utils/utils';6import { isBrowserDirectory } from 'playwright/internal/utils/utils';7import { isBrowserDirectory } from 'playwright/internal/utils/utils';8import { isBrowserDirectory } from 'playwright/internal/utils/utils';9import { isBrowserDirectory } from 'playwright/internal/utils/utils';10import { isBrowserDirectory } from 'playwright/internal/utils/utils';11import { isBrowserDirectory } from 'playwright/internal/utils/utils';
Using AI Code Generation
1const { isBrowserDirectory } = require('playwright/lib/server/browserType');2const path = require('path');3(async () => {4 const browserDirectory = path.join(__dirname, 'browsers');5 const isBrowserDirectory = await isBrowserDirectory(browserDirectory);6 console.log(isBrowserDirectory);7})();
Using AI Code Generation
1const { isBrowserDirectory } = require('@playwright/test/lib/utils/utils');2const path = require('path');3const fs = require('fs');4const dir = path.join(__dirname, 'test');5console.log('isBrowserDirectory', isBrowserDirectory(dir));6console.log('fs.statSync', fs.statSync(dir).isDirectory());7console.log('fs.statSync', fs.statSync(dir).isFile());
Using AI Code Generation
1const { isBrowserDirectory } = require('playwright/lib/server/browserType');2const path = require('path');3const browserDirectory = path.resolve(__dirname, 'browser');4const exists = await isBrowserDirectory(browserDirectory);5console.log(exists);6BrowserType.launch()7const browser = await browserType.launch([options]);
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!!