UNPKG

playwright-core

Version:

A high-level API to automate web browsers

141 lines • 7.26 kB
"use strict"; /** * Copyright Microsoft Corporation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.installBrowsersWithProgressBar = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const util_1 = __importDefault(require("util")); const rimraf_1 = __importDefault(require("rimraf")); const proper_lockfile_1 = __importDefault(require("proper-lockfile")); const registry_1 = require("../utils/registry"); const browserFetcher = __importStar(require("./browserFetcher")); const utils_1 = require("../utils/utils"); const fsMkdirAsync = util_1.default.promisify(fs_1.default.mkdir.bind(fs_1.default)); const fsReaddirAsync = util_1.default.promisify(fs_1.default.readdir.bind(fs_1.default)); const fsReadFileAsync = util_1.default.promisify(fs_1.default.readFile.bind(fs_1.default)); const fsExistsAsync = (filePath) => fsReadFileAsync(filePath).then(() => true).catch(e => false); const fsUnlinkAsync = util_1.default.promisify(fs_1.default.unlink.bind(fs_1.default)); const fsWriteFileAsync = util_1.default.promisify(fs_1.default.writeFile.bind(fs_1.default)); const removeFolderAsync = util_1.default.promisify(rimraf_1.default); const PACKAGE_PATH = path_1.default.join(__dirname, '..', '..'); async function installBrowsersWithProgressBar(browserNames = registry_1.allBrowserNames) { // PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1 if (utils_1.getAsBooleanFromENV('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) { browserFetcher.logPolitely('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set'); return false; } await fsMkdirAsync(registry_1.registryDirectory, { recursive: true }); const lockfilePath = path_1.default.join(registry_1.registryDirectory, '__dirlock'); const releaseLock = await proper_lockfile_1.default.lock(registry_1.registryDirectory, { retries: { retries: 10, // Retry 20 times during 10 minutes with // exponential back-off. // See documentation at: https://www.npmjs.com/package/retry#retrytimeoutsoptions factor: 1.27579, }, onCompromised: (err) => { throw new Error(`${err.message} Path: ${lockfilePath}`); }, lockfilePath, }); const linksDir = path_1.default.join(registry_1.registryDirectory, '.links'); try { await fsMkdirAsync(linksDir, { recursive: true }); await fsWriteFileAsync(path_1.default.join(linksDir, utils_1.calculateSha1(PACKAGE_PATH)), PACKAGE_PATH); await validateCache(linksDir, browserNames); } finally { await releaseLock(); } } exports.installBrowsersWithProgressBar = installBrowsersWithProgressBar; async function validateCache(linksDir, browserNames) { // 1. Collect used downloads and package descriptors. const usedBrowserPaths = new Set(); for (const fileName of await fsReaddirAsync(linksDir)) { const linkPath = path_1.default.join(linksDir, fileName); let linkTarget = ''; try { linkTarget = (await fsReadFileAsync(linkPath)).toString(); const linkRegistry = new registry_1.Registry(linkTarget); for (const browserName of registry_1.allBrowserNames) { if (!linkRegistry.shouldDownload(browserName)) continue; const usedBrowserPath = linkRegistry.browserDirectory(browserName); const browserRevision = linkRegistry.revision(browserName); // Old browser installations don't have marker file. const shouldHaveMarkerFile = (browserName === 'chromium' && browserRevision >= 786218) || (browserName === 'firefox' && browserRevision >= 1128) || (browserName === 'webkit' && browserRevision >= 1307) || // All new applications have a marker file right away. (browserName !== 'firefox' && browserName !== 'chromium' && browserName !== 'webkit'); if (!shouldHaveMarkerFile || (await fsExistsAsync(markerFilePath(usedBrowserPath)))) usedBrowserPaths.add(usedBrowserPath); } } catch (e) { await fsUnlinkAsync(linkPath).catch(e => { }); } } // 2. Delete all unused browsers. let downloadedBrowsers = (await fsReaddirAsync(registry_1.registryDirectory)).map(file => path_1.default.join(registry_1.registryDirectory, file)); downloadedBrowsers = downloadedBrowsers.filter(file => registry_1.isBrowserDirectory(file)); const directories = new Set(downloadedBrowsers); for (const browserDirectory of usedBrowserPaths) directories.delete(browserDirectory); for (const directory of directories) { browserFetcher.logPolitely('Removing unused browser at ' + directory); await removeFolderAsync(directory).catch(e => { }); } // 3. Install missing browsers for this package. const myRegistry = new registry_1.Registry(PACKAGE_PATH); for (const browserName of browserNames) { if (!myRegistry.shouldDownload(browserName)) continue; await browserFetcher.downloadBrowserWithProgressBar(myRegistry, browserName).catch(e => { throw new Error(`Failed to download ${browserName}, caused by\n${e.stack}`); }); await fsWriteFileAsync(markerFilePath(myRegistry.browserDirectory(browserName)), ''); } } function markerFilePath(browserDirectory) { return path_1.default.join(browserDirectory, 'INSTALLATION_COMPLETE'); } //# sourceMappingURL=installer.js.map