Skip to content

Commit 890ec4c

Browse files
committed
refactor(@angular/build): remove source-map-support from Vitest runner
This change removes the injection of `source-map-support` in Vitest browser tests and enables sourcemap rebasing for coverage runs as well. This allows Vitest's native remapper to handle stack traces and coverage correctly without needing the external polyfill in the browser. The E2E tests have been verified to pass with these changes. The unused `createSourcemapSupportPlugin` function has also been removed.
1 parent 0a48239 commit 890ec4c

2 files changed

Lines changed: 25 additions & 47 deletions

File tree

packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -232,16 +232,12 @@ export async function createVitestConfigPlugin(
232232
delete config.plugins;
233233
}
234234

235-
// Add browser source map support if coverage is enabled
235+
// Validate browser coverage support if coverage is enabled
236236
if (
237237
(browser || testConfig?.browser?.enabled) &&
238238
(options.coverage.enabled || testConfig?.coverage?.enabled)
239239
) {
240-
// Validate that enabled browsers support the selected coverage provider
241240
validateBrowserCoverage(browser, testConfig?.browser, determinedProvider);
242-
243-
projectPlugins.unshift(createSourcemapSupportPlugin());
244-
setupFiles.unshift('virtual:source-map-support');
245241
}
246242

247243
const projectResolver = createRequire(projectSourceRoot + '/').resolve;
@@ -408,7 +404,7 @@ export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins
408404

409405
const map = sourceMapText ? JSON.parse(sourceMapText) : undefined;
410406
if (map) {
411-
adjustSourcemapSources(map, !vitestConfig?.coverage?.enabled, workspaceRoot, id);
407+
adjustSourcemapSources(map, true, workspaceRoot, id);
412408
}
413409

414410
return {
@@ -475,36 +471,6 @@ function adjustSourcemapSources(
475471
}
476472
}
477473

478-
function createSourcemapSupportPlugin(): VitestPlugins[0] {
479-
return {
480-
name: 'angular:source-map-support',
481-
enforce: 'pre',
482-
resolveId(source) {
483-
if (source.includes('virtual:source-map-support')) {
484-
return '\0source-map-support';
485-
}
486-
},
487-
async load(id) {
488-
if (id !== '\0source-map-support') {
489-
return;
490-
}
491-
492-
const packageResolve = createRequire(__filename).resolve;
493-
const supportPath = packageResolve('source-map-support/browser-source-map-support.js');
494-
495-
const content = await readFile(supportPath, 'utf-8');
496-
497-
// The `source-map-support` library currently relies on `this` being defined in the global scope.
498-
// However, when running in an ESM environment, `this` is undefined.
499-
// To workaround this, we patch the library to use `globalThis` instead of `this`.
500-
return (
501-
content.replaceAll(/this\.(define|sourceMapSupport|base64js)/g, 'globalThis.$1') +
502-
'\n;globalThis.sourceMapSupport.install();'
503-
);
504-
},
505-
};
506-
}
507-
508474
interface CustomBrowserConfigOptions {
509475
enabled?: boolean;
510476
instances?: { browser: string }[];

tests/e2e/tests/vitest/browser-coverage-sourcemaps.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,32 @@ export default async function (): Promise<void> {
1212

1313
// Run tests with coverage in browser mode.
1414
// We use the default passing tests generated for the project.
15-
const { stdout } = await ng('test', '--no-watch', '--browsers', 'chromiumHeadless', '--coverage');
15+
const { stdout } = await ng(
16+
'test',
17+
'--no-watch',
18+
'--browsers',
19+
'chromiumHeadless',
20+
'--coverage',
21+
'--coverage-reporters=json-summary',
22+
);
1623

1724
// Verify that tests passed
1825
assert.match(stdout, /pass/, 'Expected tests to run successfully.');
1926

2027
// Verify that coverage files are generated
21-
const coverageJsonPath = 'coverage/test-project/coverage-final.json';
22-
await expectFileToExist(coverageJsonPath);
23-
24-
const coverageContent = await readFile(coverageJsonPath);
25-
assert.match(coverageContent, /app\.ts/, 'Expected coverage report to contain app.ts.');
26-
assert.doesNotMatch(
27-
coverageContent,
28-
/\.spec\.ts/,
29-
'Expected coverage report to not contain .spec.ts files.',
30-
);
28+
const summaryPath = 'coverage/test-project/coverage-summary.json';
29+
await expectFileToExist(summaryPath);
30+
31+
const summary = JSON.parse(await readFile(summaryPath));
32+
33+
// Find the key for app.ts (it might be an absolute path)
34+
const appFileKey = Object.keys(summary).find((key) => key.endsWith('app.ts'));
35+
assert.ok(appFileKey, 'Expected coverage summary to contain app.ts.');
36+
37+
const appCoverage = summary[appFileKey];
38+
assert.ok(appCoverage.lines.pct > 0, 'Expected lines percentage to be greater than 0.');
39+
40+
// Also verify that spec files are NOT present in the summary
41+
const specFileKey = Object.keys(summary).find((key) => key.endsWith('.spec.ts'));
42+
assert.ok(!specFileKey, 'Expected coverage report to not contain .spec.ts files.');
3143
}

0 commit comments

Comments
 (0)