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 22c5993eabe2..666bfcc260af 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 @@ -114,15 +114,6 @@ export async function createVitestConfigPlugin( delete config.plugins; } - // Add browser source map support if coverage is enabled - if ( - (browser || testConfig?.browser?.enabled) && - (options.coverage.enabled || testConfig?.coverage?.enabled) - ) { - projectPlugins.unshift(createSourcemapSupportPlugin()); - setupFiles.unshift('virtual:source-map-support'); - } - const projectResolver = createRequire(projectSourceRoot + '/').resolve; const projectDefaults: UserWorkspaceConfig = { @@ -276,7 +267,7 @@ export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins const map = sourceMapText ? JSON.parse(sourceMapText) : undefined; if (map) { - adjustSourcemapSources(map, !vitestConfig?.coverage?.enabled, workspaceRoot, id); + adjustSourcemapSources(map, true, workspaceRoot, id); } return { @@ -343,36 +334,6 @@ function adjustSourcemapSources( } } -function createSourcemapSupportPlugin(): VitestPlugins[0] { - return { - name: 'angular:source-map-support', - enforce: 'pre', - resolveId(source) { - if (source.includes('virtual:source-map-support')) { - return '\0source-map-support'; - } - }, - async load(id) { - if (id !== '\0source-map-support') { - return; - } - - const packageResolve = createRequire(__filename).resolve; - const supportPath = packageResolve('source-map-support/browser-source-map-support.js'); - - const content = await readFile(supportPath, 'utf-8'); - - // The `source-map-support` library currently relies on `this` being defined in the global scope. - // However, when running in an ESM environment, `this` is undefined. - // To workaround this, we patch the library to use `globalThis` instead of `this`. - return ( - content.replaceAll(/this\.(define|sourceMapSupport|base64js)/g, 'globalThis.$1') + - '\n;globalThis.sourceMapSupport.install();' - ); - }, - }; -} - async function generateCoverageOption( optionsCoverage: NormalizedUnitTestBuilderOptions['coverage'], configCoverage: VitestCoverageOption | undefined, diff --git a/tests/e2e/tests/vitest/browser-sourcemaps.ts b/tests/e2e/tests/vitest/browser-sourcemaps.ts index 90c04457c7c8..f272d3dbd49d 100644 --- a/tests/e2e/tests/vitest/browser-sourcemaps.ts +++ b/tests/e2e/tests/vitest/browser-sourcemaps.ts @@ -7,6 +7,7 @@ import { stripVTControlCharacters } from 'node:util'; export default async function (): Promise { await applyVitestBuilder(); + await installPackage('@vitest/coverage-v8'); await installPackage('playwright@1'); await installPackage('@vitest/browser-playwright@4'); await ng('generate', 'component', 'my-comp'); @@ -37,4 +38,20 @@ export default async function (): Promise { 'Expected stack trace to point to the source file.', ); } + + // Again but with coverage + try { + await noSilentNg('test', '--no-watch', '--coverage', '--browsers', 'chromiumHeadless'); + throw new Error('Expected "ng test" to fail.'); + } catch (error: any) { + const stdout = stripVTControlCharacters(error.stdout || error.message); + // We expect the failure from failing.spec.ts + assert.match(stdout, /1 failed/, 'Expected 1 test to fail.'); + // Check that the stack trace points to the correct file + assert.match( + stdout, + /\bsrc[\/\\]app[\/\\]failing\.spec\.ts:4:\d+/, + 'Expected stack trace to point to the source file.', + ); + } }