@web/test-runner-chrome
Version:
Chrome browser launcher for Web Test Runner
170 lines • 7.64 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChromeLauncher = void 0;
const puppeteer_core_1 = require("puppeteer-core");
const findExecutablePath_js_1 = require("./findExecutablePath.js");
const ChromeLauncherPage_js_1 = require("./ChromeLauncherPage.js");
function capitalize(str) {
return `${str[0].toUpperCase()}${str.substring(1)}`;
}
const errorHelp = 'This could be because of a mismatch between the version of puppeteer and Chrome or Chromium. ' +
'Try updating either of them, or adjust the executablePath option to point to another browser installation. ' +
'Use the --puppeteer flag to run tests with bundled compatible version of Chromium.';
class ChromeLauncher {
constructor(launchOptions, createBrowserContextFn, createPageFn, customPuppeteer, concurrency) {
var _a;
this.type = 'puppeteer';
this.activePages = new Map();
this.activeDebugPages = new Map();
this.inactivePages = [];
this.launchOptions = launchOptions;
this.customPuppeteer = customPuppeteer;
this.createBrowserContextFn = createBrowserContextFn;
this.createPageFn = createPageFn;
this.concurrency = concurrency;
if (!customPuppeteer) {
// without a custom puppeteer, we use the locally installed chrome
this.name = 'Chrome';
}
else if (!((_a = this.launchOptions) === null || _a === void 0 ? void 0 : _a.browser) || this.launchOptions.browser === 'chrome') {
// with puppeteer we use the a packaged chromium, puppeteer calls it chrome but we
// should call it chromium to avoid confusion
this.name = 'Chromium';
}
else {
// otherwise take the browser name directly
this.name = capitalize(this.launchOptions.browser);
}
}
async initialize(config, testFiles) {
this.config = config;
this.testFiles = testFiles;
}
launchBrowser(options = {}) {
const mergedOptions = Object.assign(Object.assign({ headless: true }, this.launchOptions), options);
if (this.customPuppeteer) {
// launch using a custom puppeteer instance
return this.customPuppeteer.launch(mergedOptions).catch(error => {
if (mergedOptions.browser === 'firefox') {
console.warn('\nUsing puppeteer with firefox is experimental.\n' +
'Check the docs at https://github.com/modernweb-dev/web/tree/master/packages/test-runner-puppeteer' +
' to learn how to set it up.\n');
}
throw error;
});
}
// launch using puppeteer-core, connecting to an installed browser
// add a default executable path if the user did not provide any
if (!mergedOptions.executablePath) {
if (!this.cachedExecutablePath) {
this.cachedExecutablePath = (0, findExecutablePath_js_1.findExecutablePath)();
}
mergedOptions.executablePath = this.cachedExecutablePath;
}
return (0, puppeteer_core_1.launch)(mergedOptions).catch(error => {
console.error('');
console.error(`Failed to launch local browser installed at ${mergedOptions.executablePath}. ${errorHelp}`);
console.error('');
throw error;
});
}
async startBrowser(options = {}) {
const browser = await this.launchBrowser(options);
const context = await this.createBrowserContextFn({ config: this.config, browser });
return { browser, context };
}
async stop() {
var _a, _b;
if ((_a = this.browser) === null || _a === void 0 ? void 0 : _a.isConnected()) {
await this.browser.close();
}
if ((_b = this.debugBrowser) === null || _b === void 0 ? void 0 : _b.isConnected()) {
await this.debugBrowser.close();
}
}
async startSession(sessionId, url) {
var _a;
const { browser, context } = await this.getOrStartBrowser();
let page;
if (this.inactivePages.length === 0) {
page = await this.createNewPage(browser, context);
}
else {
page = this.inactivePages.pop();
}
this.activePages.set(sessionId, page);
await page.runSession(url, !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.coverage));
}
isActive(sessionId) {
return this.activePages.has(sessionId);
}
getBrowserUrl(sessionId) {
return this.getPage(sessionId).url();
}
async startDebugSession(sessionId, url) {
if (!this.debugBrowser || !this.debugBrowserContext) {
this.debugBrowser = await this.launchBrowser({ devtools: true, headless: false });
this.debugBrowserContext = await this.createBrowserContextFn({
config: this.config,
browser: this.debugBrowser,
});
}
const page = await this.createNewPage(this.debugBrowser, this.debugBrowserContext);
this.activeDebugPages.set(sessionId, page);
page.puppeteerPage.on('close', () => {
this.activeDebugPages.delete(sessionId);
});
await page.runSession(url, true);
}
async createNewPage(browser, context) {
var _a, _b;
const puppeteerPagePromise = this.createPageFn({
config: this.config,
browser,
context,
}).catch(error => {
if (!this.customPuppeteer) {
console.error(`Failed to create page with puppeteer. ${errorHelp}`);
}
throw error;
});
return new ChromeLauncherPage_js_1.ChromeLauncherPage(this.config, this.testFiles, (_b = (_a = this.launchOptions) === null || _a === void 0 ? void 0 : _a.browser) !== null && _b !== void 0 ? _b : 'chromium', await puppeteerPagePromise);
}
async stopSession(sessionId) {
const page = this.activePages.get(sessionId);
if (!page) {
throw new Error(`No page for session ${sessionId}`);
}
if (page.puppeteerPage.isClosed()) {
throw new Error(`Session ${sessionId} is already stopped`);
}
const result = await page.stopSession();
this.activePages.delete(sessionId);
this.inactivePages.push(page);
return result;
}
async getOrStartBrowser() {
var _a;
if (this.__startBrowserPromise) {
return this.__startBrowserPromise;
}
if (!this.browser || !((_a = this.browser) === null || _a === void 0 ? void 0 : _a.isConnected()) || !this.browserContext) {
this.__startBrowserPromise = this.startBrowser();
const { browser, context } = await this.__startBrowserPromise;
this.browser = browser;
this.browserContext = context;
this.__startBrowserPromise = undefined;
}
return { browser: this.browser, context: this.browserContext };
}
getPage(sessionId) {
var _a, _b, _c;
const page = (_b = (_a = this.activePages.get(sessionId)) === null || _a === void 0 ? void 0 : _a.puppeteerPage) !== null && _b !== void 0 ? _b : (_c = this.activeDebugPages.get(sessionId)) === null || _c === void 0 ? void 0 : _c.puppeteerPage;
if (!page) {
throw new Error(`Could not find a page for session ${sessionId}`);
}
return page;
}
}
exports.ChromeLauncher = ChromeLauncher;
//# sourceMappingURL=ChromeLauncher.js.map