UNPKG

@eyeo/get-browser-binary

Version:

Install browser binaries and matching webdrivers

138 lines (127 loc) 5.46 kB
/* * Copyright (c) 2006-present eyeo GmbH * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import {exec, execFile} from "child_process"; import {promisify} from "util"; import {errMsg} from "./utils.js"; /** * Base class for browser and webdriver functionality. Please see subclasses for * browser specific details. All classes can be used statically. * @hideconstructor */ export class Browser { /** * @typedef {Object} BrowserBinary * @property {string} binary The path to the browser binary. * @property {string} versionNumber The version number of the browser binary. */ /** * Installs the browser. The installation process is detailed on the * subclasses. * @param {string} [version=latest] Either full version number or * channel/release. Please find examples on the subclasses. * @param {number} [downloadTimeout=0] Allowed time in ms for the download of * install files to complete. When set to 0 there is no time limit. * @return {BrowserBinary} * @throws {Error} Unsupported browser version, Unsupported platform, Browser * download failed. */ static async installBrowser(version, downloadTimeout = 0) { // to be implemented by the subclass } /** * Gets the installed version returned by the browser binary. Subclasses add * specific parsing to this function. * @param {string} binary The path to the browser binary. * @return {string} Installed browser version. * @throws {Error} Browser is not installed. */ static async getInstalledVersion(binary) { try { let stdout; let stderr; if (process.platform == "win32") { ({stdout, stderr} = await promisify(exec)( `(Get-ItemProperty ${binary}).VersionInfo.ProductVersion`, {shell: "powershell.exe"}) ); } else { ({stdout, stderr} = await promisify(execFile)(binary, ["--version"])); } if (stderr) throw new Error(stderr); return stdout.trim(); } catch (err) { throw new Error(`${errMsg.browserNotInstalled}.\nBinary path: ${binary}\n${err}`); } } /** * @typedef {Object} webdriver * @see https://www.selenium.dev/selenium/docs/api/javascript/index.html */ /** * @typedef {Object} driverOptions * @property {boolean} [headless=true] Run the browser in headless mode, * or not. In Chromium >= 111 and Edge >= 114 the * {@link https://developer.chrome.com/articles/new-headless/ new headless mode} * is used. * @property {Array.<string>} [extensionPaths=[]] Paths to folders containing * unpacked extensions which will be loaded to the browser. * @property {boolean} [incognito=false] Runs the browser in incognito mode, * or not. * @property {boolean} [insecure=false] Forces the browser to accept insecure * certificates, or not. * @property {Array.<string>} [extraArgs=[]] Additional arguments to start * the browser with. * @property {string} [proxy] Only for Firefox, path to network * proxy autoconfig url (PAC file). * @property {string} [customBrowserBinary] Path to the browser binary to be * used, instead of the browser installed by installBrowser(). This option * overrides the version parameter in getDriver(). */ /** * Installs the webdriver matching the browser version and runs the * browser. If needed, the browser binary is also installed. * @param {string} [version=latest] Either full version number or * channel/release. Please find examples on the subclasses. * @param {driverOptions} [options={}] Options to start the browser with. * @param {number} [downloadTimeout=0] Allowed time in ms for the download of * browser install files to complete. When set to 0 there is no time limit. * @return {webdriver} * @throws {Error} Unsupported browser version, Unsupported platform, Browser * download failed, Driver download failed, Unable to start driver, Manifest * file not found. */ static async getDriver(version, options = {}, downloadTimeout = 0) { // to be implemented by the subclass } /** * By default, extensions are disabled in incognito mode. This function * enables the extension when loaded in incognito. * @param {webdriver} driver The driver controlling the browser. * @param {string} extensionTitle Title of the extension to be enabled. * @throws {Error} Unsupported browser version, Extension not found, HTML * element not found. */ static async enableExtensionInIncognito(driver, extensionTitle) { // Allowing the extension in incognito mode can't happen programmatically: // https://stackoverflow.com/questions/57419654 // https://bugzilla.mozilla.org/show_bug.cgi?id=1729315 // That is done through the UI, to be implemented by the subclass } }