/* This file extends the base functionality of the playwright test framework to enable * code coverage instrumentation, console log error detection and working with a 3rd * party Chrome-as-a-service extension called Browserless. */ const base = require('@playwright/test'); const { expect } = require('@playwright/test'); const fs = require('fs'); const path = require('path'); const { v4: uuid } = require('uuid'); /** * Takes a `ConsoleMessage` and returns a formatted string * @param {import('@playwright/test').ConsoleMessage} msg * @returns {String} formatted string with message type, text, url, and line and column numbers */ function consoleMessageToString(msg) { const { url, lineNumber, columnNumber } = msg.location(); return `[${msg.type()}] ${msg.text()} at (${url} ${lineNumber}:${columnNumber})`; } //The following is based on https://github.com/mxschmitt/playwright-test-coverage // eslint-disable-next-line no-undef const istanbulCLIOutput = path.join(process.cwd(), '.nyc_output'); // eslint-disable-next-line no-undef exports.test = base.test.extend({ //The following is based on https://github.com/mxschmitt/playwright-test-coverage context: async ({ context }, use) => { await context.addInitScript(() => window.addEventListener('beforeunload', () => (window).collectIstanbulCoverage(JSON.stringify((window).__coverage__)) ) ); await fs.promises.mkdir(istanbulCLIOutput, { recursive: true }); await context.exposeFunction('collectIstanbulCoverage', (coverageJSON) => { if (coverageJSON) { fs.writeFileSync(path.join(istanbulCLIOutput, `playwright_coverage_${uuid()}.json`), coverageJSON); } }); await use(context); for (const page of context.pages()) { await page.evaluate(() => (window).collectIstanbulCoverage(JSON.stringify((window).__coverage__))); } }, page: async ({ baseURL, page }, use) => { const messages = []; page.on('console', (msg) => messages.push(msg)); await use(page); messages.forEach( msg => expect.soft(msg.type(), `Console error detected: ${consoleMessageToString(msg)}`).not.toEqual('error') ); }, browser: async ({ playwright, browser }, use, workerInfo) => { // Use browserless if configured if (workerInfo.project.name.match(/browserless/)) { const vBrowser = await playwright.chromium.connectOverCDP({ endpointURL: 'ws://localhost:3003' }); await use(vBrowser); } else { // Use Local Browser for testing. await use(browser); } } });