UNPKG

@web/test-runner-chrome

Version:
110 lines 5.39 kB
"use strict"; 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