Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ea4bb86

Browse files
committed
fix(@angular/build): inject source-map-support for Vitest browser tests
This change ensures that `source-map-support` is injected into the setup files when running Vitest tests in a browser environment. This allows stack traces from failing tests to correctly map back to the original source files, significantly improving debugging capabilities. A regression test has been added to `tests/vitest/browser-sourcemaps.ts` to verify that a failing test correctly identifies the source file in its stack trace.
1 parent edeb41c commit ea4bb86

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function createTestBedInitVirtualFile(
1818
providersFile: string | undefined,
1919
projectSourceRoot: string,
2020
polyfills: string[] = [],
21+
sourcemapSupport: boolean = false,
2122
): string {
2223
const usesZoneJS = polyfills.includes('zone.js');
2324
let providersImport = 'const providers = [];';
@@ -28,13 +29,23 @@ function createTestBedInitVirtualFile(
2829
providersImport = `import providers from './${importPath}';`;
2930
}
3031

32+
// Resolve and add sourcemap support (mainly for browsers)
33+
let sourceMapSetup;
34+
if (sourcemapSupport) {
35+
sourceMapSetup = `
36+
import sourceMapSupport from 'source-map-support';
37+
sourceMapSupport.install();
38+
`;
39+
}
40+
3141
return `
3242
// Initialize the Angular testing environment
3343
import { NgModule${usesZoneJS ? ', provideZoneChangeDetection' : ''} } from '@angular/core';
3444
import { getTestBed, ɵgetCleanupHook as getCleanupHook } from '@angular/core/testing';
3545
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
3646
import { afterEach, beforeEach } from 'vitest';
3747
${providersImport}
48+
${sourceMapSetup}
3849
3950
// The beforeEach and afterEach hooks are registered outside the globalThis guard.
4051
// This ensures that the hooks are always applied, even in non-isolated browser environments.
@@ -98,6 +109,8 @@ export async function getVitestBuildOptions(
98109
});
99110
entryPoints.set('init-testbed', 'angular:test-bed-init');
100111

112+
const hasBrowsers = !!options.browsers?.length;
113+
101114
// The 'vitest' package is always external for testing purposes
102115
const externalDependencies = ['vitest'];
103116
if (baseBuildOptions.externalDependencies) {
@@ -134,6 +147,7 @@ export async function getVitestBuildOptions(
134147
providersFile,
135148
projectSourceRoot,
136149
buildOptions.polyfills,
150+
hasBrowsers,
137151
);
138152

139153
return {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import assert from 'node:assert/strict';
2+
import { applyVitestBuilder } from '../../utils/vitest';
3+
import { ng, noSilentNg } from '../../utils/process';
4+
import { installPackage } from '../../utils/packages';
5+
import { writeFile } from '../../utils/fs';
6+
7+
export default async function (): Promise<void> {
8+
await applyVitestBuilder();
9+
await installPackage('playwright@1');
10+
await installPackage('@vitest/browser-playwright@4');
11+
await ng('generate', 'component', 'my-comp');
12+
13+
// Add a failing test to verify source map support
14+
await writeFile(
15+
'src/app/failing.spec.ts',
16+
`
17+
describe('Failing Test', () => {
18+
it('should fail', () => {
19+
expect(true).toBe(false);
20+
});
21+
});
22+
`,
23+
);
24+
25+
try {
26+
await noSilentNg('test', '--no-watch', '--browsers', 'chromiumHeadless');
27+
throw new Error('Expected "ng test" to fail.');
28+
} catch (error: any) {
29+
const stdout = error.stdout || error.message;
30+
// We expect the failure from failing.spec.ts
31+
assert.match(stdout, /1failed/, 'Expected 1 test to fail.');
32+
// Check that the stack trace points to the correct file
33+
assert.match(
34+
stdout,
35+
/src\/app\/failing\.spec\.ts:\d+:\d+/,
36+
'Expected stack trace to point to the source file.',
37+
);
38+
}
39+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /