diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index 489084fb0e8f..b7243564374f 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -154,6 +154,22 @@ export async function createVitestConfigPlugin( (browser || testConfig?.browser?.enabled) && (options.coverage.enabled || testConfig?.coverage?.enabled) ) { + // Validate that enabled browsers support V8 coverage + if (browser?.instances) { + const unsupportedBrowsers = browser.instances.filter( + (instance) => !['chrome', 'chromium', 'edge'].includes(instance.browser), + ); + + if (unsupportedBrowsers.length > 0) { + throw new Error( + `Code coverage is enabled, but the following configured browsers do not support the V8 coverage provider: ` + + `${unsupportedBrowsers.map((i) => i.browser).join(', ')}. ` + + `V8 coverage is only supported on Chromium-based browsers (e.g., Chrome, Chromium, Edge). ` + + `Please disable coverage or remove the unsupported browsers.`, + ); + } + } + projectPlugins.unshift(createSourcemapSupportPlugin()); setupFiles.unshift('virtual:source-map-support'); } diff --git a/tests/e2e/tests/vitest/browser-coverage-validation.ts b/tests/e2e/tests/vitest/browser-coverage-validation.ts new file mode 100644 index 000000000000..48adfed5b76c --- /dev/null +++ b/tests/e2e/tests/vitest/browser-coverage-validation.ts @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import { applyVitestBuilder } from '../../utils/vitest'; +import { execAndCaptureError } from '../../utils/process'; +import { installPackage } from '../../utils/packages'; +import { stripVTControlCharacters } from 'node:util'; + +export default async function (): Promise { + await applyVitestBuilder(); + + // Install necessary packages to pass the provider check + await installPackage('playwright@1'); + await installPackage('@vitest/browser-playwright@4'); + await installPackage('@vitest/coverage-v8@4'); + + // Run test with coverage and an unsupported browser + const error = await execAndCaptureError('ng', [ + 'test', + '--no-watch', + '--coverage', + '--browsers', + 'firefox', + ]); + const output = stripVTControlCharacters(error.message); + + // Verify that the expected error message is present + assert.match( + output, + /Code coverage is enabled, but the following configured browsers do not support the V8 coverage provider: firefox/, + 'Expected validation error for unsupported browser with coverage.', + ); +}