diff --git a/end-to-end-tests/fixtures/extensionBase.ts b/end-to-end-tests/fixtures/extensionBase.ts index d06923a5f9..8ba4f20f8b 100644 --- a/end-to-end-tests/fixtures/extensionBase.ts +++ b/end-to-end-tests/fixtures/extensionBase.ts @@ -29,6 +29,8 @@ import { } from "./utils"; import { ModsPage } from "../pageObjects/extensionConsole/modsPage"; import { test as envSetup } from "./envSetup"; +import v8toIstanbul from "v8-to-istanbul"; +import { v4 } from "uuid"; // This environment variable is used to attach the browser sidepanel window that opens automatically to Playwright. // See https://github.com/microsoft/playwright/issues/26693 @@ -38,6 +40,16 @@ process.env.PW_CHROMIUM_ATTACH_TO_OTHER = "1"; // See https://playwright.dev/docs/service-workers-experimental process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS = "1"; +const coverageDirectory = path.join(__dirname, "../.output/coverage"); + +const collectCoverage = async (coverageJSON: string) => { + if (coverageJSON) + await fs.writeFile( + `${coverageDirectory}/playwright_coverage_${v4()}.json`, + coverageJSON, + ); +}; + export const test = mergeTests( envSetup, base.extend< @@ -83,6 +95,10 @@ export const test = mergeTests( recursive: true, }); + await fs.mkdir(coverageDirectory, { + recursive: true, + }); + const context = await launchPersistentContextWithExtension( chromiumChannel, temporaryProfileDirectory, @@ -94,12 +110,20 @@ export const test = mergeTests( async page({ context, extensionId }, use) { // Re-use the initial context page if it exists const page = context.pages()[0] || (await context.newPage()); + await page.coverage.startJSCoverage(); // Start off test from the extension console, and ensure it is done loading const modsPage = new ModsPage(page, extensionId); await modsPage.goto(); await use(page); + const coverage = await page.coverage.stopJSCoverage(); + for (const entry of coverage) { + const converter = v8toIstanbul("", 0, { source: entry.source }); + await converter.load(); + converter.applyCoverage(entry.functions); + await collectCoverage(JSON.stringify(converter.toIstanbul())); + } // The page is closed by the context fixture `.close` cleanup step }, async extensionId({ context }, use) { diff --git a/package-lock.json b/package-lock.json index 6ce0bbe78a..bff1647b3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -264,6 +264,7 @@ "type-fest": "^4.18.0", "typescript": "^5.4.5", "typescript-plugin-css-modules": "^5.1.0", + "v8-to-istanbul": "^9.2.0", "webpack": "^5.91.0", "webpack-build-notifier": "^2.3.0", "webpack-bundle-analyzer": "^4.10.2", @@ -28679,18 +28680,25 @@ } }, "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", diff --git a/package.json b/package.json index 0da551a9d5..79327cfa52 100644 --- a/package.json +++ b/package.json @@ -290,6 +290,7 @@ "type-fest": "^4.18.0", "typescript": "^5.4.5", "typescript-plugin-css-modules": "^5.1.0", + "v8-to-istanbul": "^9.2.0", "webpack": "^5.91.0", "webpack-build-notifier": "^2.3.0", "webpack-bundle-analyzer": "^4.10.2",