@web/test-runner-chrome
Version:
Chrome browser launcher for Web Test Runner
110 lines • 5.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChromeLauncherPage = void 0;
const test_runner_coverage_v8_1 = require("@web/test-runner-coverage-v8");
const async_mutex_1 = require("async-mutex");
const mutex = new async_mutex_1.Mutex();
class ChromeLauncherPage {
constructor(config, testFiles, product, puppeteerPage) {
this.nativeInstrumentationEnabledOnPage = false;
this.patchAdded = false;
this.resolvers = {};
this.config = config;
this.testFiles = testFiles;
this.browser = product;
this.puppeteerPage = puppeteerPage;
}
async runSession(url, coverage) {
var _a;
if (coverage &&
((_a = this.config.coverageConfig) === null || _a === void 0 ? void 0 : _a.nativeInstrumentation) !== false &&
this.browser === 'chromium') {
if (this.nativeInstrumentationEnabledOnPage) {
await this.puppeteerPage.coverage.stopJSCoverage();
}
this.nativeInstrumentationEnabledOnPage = true;
await this.puppeteerPage.coverage.startJSCoverage({
includeRawScriptCoverage: true,
});
}
// Patching the browser page to workaround an issue in the new headless mode of Chrome where some functions
// with callbacks (requestAnimationFrame and requestIdleCallback) are not executing their callbacks.
// https://github.com/puppeteer/puppeteer/issues/10350
if (!this.patchAdded) {
await this.puppeteerPage.exposeFunction('__bringTabToFront', (id) => {
const promise = new Promise(resolve => {
this.resolvers[id] = resolve;
});
return mutex.runExclusive(async () => {
await this.puppeteerPage.bringToFront();
await promise;
});
});
await this.puppeteerPage.exposeFunction('__releaseLock', (id) => {
var _a, _b;
(_b = (_a = this.resolvers)[id]) === null || _b === void 0 ? void 0 : _b.call(_a);
});
await this.puppeteerPage.evaluateOnNewDocument(() => {
// eslint-disable-next-line @typescript-eslint/ban-types
function patchFunction(name, fn) {
window[name] = (...args) => {
const result = fn.call(window, ...args);
const id = Math.random().toString().substring(2);
// Make sure that the tab running the test code is brought back to the front.
window.__bringTabToFront(id);
fn.call(window, () => {
window.__releaseLock(id);
});
return result;
};
}
patchFunction('requestAnimationFrame', window.requestAnimationFrame);
patchFunction('requestIdleCallback', window.requestIdleCallback);
});
this.patchAdded = true;
}
await this.puppeteerPage.setViewport({ height: 600, width: 800 });
await this.puppeteerPage.goto(url);
}
async stopSession() {
const testCoverage = await this.collectTestCoverage(this.config, this.testFiles);
// navigate to an empty page to kill any running code on the page, stopping timers and
// breaking a potential endless reload loop
await this.puppeteerPage.goto('about:blank');
return { testCoverage };
}
async collectTestCoverage(config, testFiles) {
var _a, _b;
const userAgentPromise = this.puppeteerPage
.browser()
.userAgent()
.catch(() => undefined);
try {
const coverageFromBrowser = await this.puppeteerPage.evaluate(() => window.__coverage__);
if (coverageFromBrowser) {
// coverage was generated by JS, return that
return coverageFromBrowser;
}
}
catch (error) {
// evaluate throws when the test navigates in the browser
}
if (((_a = config.coverageConfig) === null || _a === void 0 ? void 0 : _a.nativeInstrumentation) === false) {
throw new Error('Coverage is enabled with nativeInstrumentation disabled. ' +
'Expected coverage provided in the browser as a global __coverage__ variable.' +
'Use a plugin like babel-plugin-istanbul to generate the coverage, or enable native instrumentation.');
}
if (!this.nativeInstrumentationEnabledOnPage) {
return undefined;
}
const [userAgent, coverageResult] = await Promise.all([
userAgentPromise,
(_b = this.puppeteerPage.coverage) === null || _b === void 0 ? void 0 : _b.stopJSCoverage(),
]);
const v8Coverage = coverageResult === null || coverageResult === void 0 ? void 0 : coverageResult.map(entry => entry.rawScriptCoverage).filter((cov) => cov !== undefined);
this.nativeInstrumentationEnabledOnPage = false;
return (0, test_runner_coverage_v8_1.v8ToIstanbul)(config, testFiles, v8Coverage, userAgent);
}
}
exports.ChromeLauncherPage = ChromeLauncherPage;
//# sourceMappingURL=ChromeLauncherPage.js.map