Skip to content

Commit 54f8234

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 54f8234

File tree

1 file changed

+105
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)