Skip to content

Commit eafb83f

Browse files
committed
test(@angular/build): add e2e for larger project with Vitest coverage
Adds an end-to-end test to verify Vitest coverage collection and threshold enforcement for a larger number of generated components, services, and pipes. This test ensures that all generated source files are correctly included in the coverage report in both JSDOM and browser environments.
1 parent 960c80c commit eafb83f

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { ng } from '../../utils/process';
2+
import { applyVitestBuilder } from '../../utils/vitest';
3+
import assert from 'node:assert';
4+
import { installPackage } from '../../utils/packages';
5+
import { exec } from '../../utils/process';
6+
import { updateJsonFile } from '../../utils/project';
7+
8+
/** Escapes a string for use in a regular expression. */
9+
function escapeRegExp(text: string): string {
10+
return text.replace(/[.*+?^${}()|[\\]/g, '\\$&');
11+
}
12+
13+
export default async function () {
14+
await applyVitestBuilder();
15+
await installPackage('@vitest/coverage-v8@4');
16+
17+
// Add coverage and threshold configuration to ensure coverage is calculated.
18+
await updateJsonFile('angular.json', (json) => {
19+
const project = Object.values(json['projects'])[0] as any;
20+
const test = project['architect']['test'];
21+
test.options = {
22+
coverageThresholds: {
23+
// The generated component/service/pipe files are basic and have 100% coverage.
24+
// The main app component is also basic. A threshold of 80 should be safe.
25+
statements: 80,
26+
lines: 80,
27+
branches: 80,
28+
functions: 80,
29+
},
30+
};
31+
});
32+
33+
const artifactCount = 100;
34+
const initialTestCount = 1;
35+
const generatedFiles: string[] = [];
36+
37+
// Generate a mix of components, services, and pipes
38+
for (let i = 0; i < artifactCount; i++) {
39+
const type = i % 3;
40+
const name = `test-artifact${i}`;
41+
let generateType;
42+
let fileSuffix;
43+
44+
switch (type) {
45+
case 0:
46+
generateType = 'component';
47+
fileSuffix = '.ts';
48+
break;
49+
case 1:
50+
generateType = 'service';
51+
fileSuffix = '.ts';
52+
break;
53+
default:
54+
generateType = 'pipe';
55+
fileSuffix = '-pipe.ts';
56+
break;
57+
}
58+
59+
await ng('generate', generateType, name, '--skip-tests=false');
60+
generatedFiles.push(`${name}${fileSuffix}`);
61+
}
62+
63+
const totalTests = initialTestCount + artifactCount;
64+
const expectedMessage = new RegExp(`${totalTests} passed`);
65+
66+
// Run tests in default (JSDOM) mode with coverage
67+
const { stdout: jsdomStdout } = await ng('test', '--no-watch', '--coverage');
68+
assert.match(jsdomStdout, expectedMessage, `Expected ${totalTests} tests to pass in JSDOM mode.`);
69+
70+
// Assert that every generated file is in the coverage report.
71+
for (const file of generatedFiles) {
72+
assert.match(
73+
jsdomStdout,
74+
new RegExp(escapeRegExp(file)),
75+
`Expected ${file} to be in the JSDOM coverage report.`,
76+
);
77+
}
78+
79+
// Setup for browser mode
80+
await installPackage('playwright@1');
81+
await installPackage('@vitest/browser-playwright@4');
82+
await exec('npx', 'playwright', 'install', 'chromium', '--only-shell');
83+
84+
// Run tests in browser mode with coverage
85+
const { stdout: browserStdout } = await ng(
86+
'test',
87+
'--no-watch',
88+
'--coverage',
89+
'--browsers',
90+
'ChromiumHeadless',
91+
);
92+
assert.match(
93+
browserStdout,
94+
expectedMessage,
95+
`Expected ${totalTests} tests to pass in browser mode.`,
96+
);
97+
98+
// Assert that every generated file is in the coverage report for browser mode.
99+
for (const file of generatedFiles) {
100+
assert.match(
101+
browserStdout,
102+
new RegExp(escapeRegExp(file)),
103+
`Expected ${file} to be in the browser coverage report.`,
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)