Skip to content

Commit bfb7edf

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 bfb7edf

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+
import { readFile } from '../../utils/fs';
8+
9+
/** Escapes a string for use in a regular expression. */
10+
function escapeRegExp(text: string): string {
11+
return text.replace(/[.*+?^${}()|[\\]/g, '\\$&');
12+
}
13+
14+
export default async function () {
15+
await applyVitestBuilder();
16+
await installPackage('@vitest/coverage-v8@4');
17+
18+
// Add coverage and threshold configuration to ensure coverage is calculated.
19+
// Use the 'json' reporter to get a machine-readable output for assertions.
20+
await updateJsonFile('angular.json', (json) => {
21+
const project = Object.values(json['projects'])[0] as any;
22+
const test = project['architect']['test'];
23+
test.options = {
24+
coverageReporters: ['json', 'text'],
25+
coverageThresholds: {
26+
// The generated component/service/pipe files are basic
27+
// A threshold of 75 should be safe.
28+
statements: 75,
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(`src/app/${name}/${name}${fileSuffix}`);
61+
}
62+
63+
const totalTests = initialTestCount + artifactCount;
64+
const expectedMessage = new RegExp(`${totalTests} passed`);
65+
const coverageJsonPath = 'coverage/test-project/coverage-final.json';
66+
67+
// Run tests in default (JSDOM) mode with coverage
68+
const { stdout: jsdomStdout } = await ng('test', '--no-watch', '--coverage');
69+
assert.match(jsdomStdout, expectedMessage, `Expected ${totalTests} tests to pass in JSDOM mode.`);
70+
71+
// Assert that every generated file is in the coverage report by reading the JSON output.
72+
const jsdomSummary = JSON.parse(await readFile(coverageJsonPath));
73+
const jsdomSummaryKeys = Object.keys(jsdomSummary);
74+
for (const file of generatedFiles) {
75+
const found = jsdomSummaryKeys.some((key) => key.endsWith(file));
76+
assert.ok(found, `Expected ${file} to be in the JSDOM coverage report.`);
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+
const browserSummary = JSON.parse(await readFile(coverageJsonPath));
100+
const browserSummaryKeys = Object.keys(browserSummary);
101+
for (const file of generatedFiles) {
102+
const found = browserSummaryKeys.some((key) => key.endsWith(file));
103+
assert.ok(found, `Expected ${file} to be in the browser coverage report.`);
104+
}
105+
}

0 commit comments

Comments
 (0)