Skip to content

Commit 127adee

Browse files
committed
build(@angular/build): update vitest to v4.0.0-beta
This commit updates the version of `vitest` and its related packages from `3.2.4` to `4.0.0-beta.17` within the unit testing system. This major version update for Vitest introduces several changes that are addressed here: - The `coverage.all` option has been removed in Vitest v4. Accordingly, the `coverageAll` option has been removed from the unit-test builders schema and its usage has been removed from the Karma and Vitest test runner implementations. - The browser provider mechanism has been updated. Vitest now uses provider-specific packages (e.g., @vitest/browser-playwright) instead of the general @vitest/browser package. The browser configuration setup has been made asynchronous and now dynamically loads the appropriate provider. - A workaround has been added to filter non-string values from the resolved coverage exclude patterns. This prevents an error caused by Vitest incorrectly adding boolean values into the array.
1 parent 2e23f5a commit 127adee

File tree

13 files changed

+133
-215
lines changed

13 files changed

+133
-215
lines changed

goldens/public-api/angular/build/index.api.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ export type UnitTestBuilderOptions = {
219219
browsers?: string[];
220220
buildTarget?: string;
221221
coverage?: boolean;
222-
coverageAll?: boolean;
223222
coverageExclude?: string[];
224223
coverageInclude?: string[];
225224
coverageReporters?: SchemaCoverageReporter[];

modules/testing/builder/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"@angular-devkit/architect": "workspace:*",
55
"@angular/ssr": "workspace:*",
66
"@angular-devkit/build-angular": "workspace:*",
7-
"@vitest/coverage-v8": "3.2.4",
7+
"@vitest/coverage-v8": "4.0.0-beta.17",
88
"jsdom": "27.0.0",
99
"rxjs": "7.8.2",
10-
"vitest": "3.2.4"
10+
"vitest": "4.0.0-beta.17"
1111
}
1212
}

packages/angular/build/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"ng-packagr": "21.0.0-next.4",
5757
"postcss": "8.5.6",
5858
"rxjs": "7.8.2",
59-
"vitest": "3.2.4"
59+
"vitest": "4.0.0-beta.17"
6060
},
6161
"peerDependencies": {
6262
"@angular/core": "0.0.0-ANGULAR-FW-PEER-DEP",
@@ -74,7 +74,7 @@
7474
"tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
7575
"tslib": "^2.3.0",
7676
"typescript": ">=5.9 <6.0",
77-
"vitest": "^3.1.1"
77+
"vitest": "^4.0.0-beta.17"
7878
},
7979
"peerDependenciesMeta": {
8080
"@angular/core": {

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ export async function normalizeOptions(
8585
runnerName: runner,
8686
coverage: options.coverage
8787
? {
88-
all: options.coverageAll,
8988
exclude: options.coverageExclude,
9089
include: options.coverageInclude,
9190
reporters: normalizeReporterOption(options.coverageReporters),

packages/angular/build/src/builders/unit-test/runners/karma/executor.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ export class KarmaExecutor implements TestExecutor {
3939
);
4040
}
4141

42-
if (unitTestOptions.coverage?.all) {
43-
context.logger.warn(
44-
'The "karma" test runner does not support the "coverageAll" option. The option will be ignored.',
45-
);
46-
}
47-
4842
if (unitTestOptions.coverage?.include) {
4943
context.logger.warn(
5044
'The "karma" test runner does not support the "coverageInclude" option. The option will be ignored.',

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

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import { createRequire } from 'node:module';
10+
import { assertIsError } from '../../../../utils/error';
1011

1112
export interface BrowserConfiguration {
1213
browser?: import('vitest/node').BrowserConfigOptions;
@@ -39,45 +40,60 @@ function normalizeBrowserName(browserName: string): string {
3940
return normalized.replace(/headless$/, '');
4041
}
4142

42-
export function setupBrowserConfiguration(
43+
export async function setupBrowserConfiguration(
4344
browsers: string[] | undefined,
4445
debug: boolean,
4546
projectSourceRoot: string,
4647
viewport: { width: number; height: number } | undefined,
47-
): BrowserConfiguration {
48+
): Promise<BrowserConfiguration> {
4849
if (browsers === undefined) {
4950
return {};
5051
}
5152

5253
const projectResolver = createRequire(projectSourceRoot + '/').resolve;
5354
let errors: string[] | undefined;
5455

55-
try {
56-
projectResolver('@vitest/browser');
57-
} catch {
58-
errors ??= [];
59-
errors.push(
60-
'The "browsers" option requires the "@vitest/browser" package to be installed within the project.' +
61-
' Please install this package and rerun the test command.',
62-
);
63-
}
64-
65-
const provider = findBrowserProvider(projectResolver);
66-
if (!provider) {
56+
const providerName = findBrowserProvider(projectResolver);
57+
if (!providerName) {
6758
errors ??= [];
6859
errors.push(
6960
'The "browsers" option requires either "playwright" or "webdriverio" to be installed within the project.' +
7061
' Please install one of these packages and rerun the test command.',
7162
);
7263
}
7364

74-
// Vitest current requires the playwright browser provider to use the inspect-brk option used by "debug"
75-
if (debug && provider !== 'playwright') {
76-
errors ??= [];
77-
errors.push(
78-
'Debugging browser mode tests currently requires the use of "playwright".' +
79-
' Please install this package and rerun the test command.',
80-
);
65+
let provider: import('vitest/node').BrowserProviderOption | undefined;
66+
if (providerName) {
67+
const providerPackage = `@vitest/browser-${providerName}`;
68+
try {
69+
const providerModule = await import(providerPackage);
70+
71+
// Validate that the imported module has the expected structure
72+
const providerFactory = providerModule[providerName];
73+
if (typeof providerFactory === 'function') {
74+
provider = providerFactory();
75+
} else {
76+
errors ??= [];
77+
errors.push(
78+
`The "${providerPackage}" package does not have a valid browser provider export.`,
79+
);
80+
}
81+
} catch (e) {
82+
assertIsError(e);
83+
errors ??= [];
84+
// Check for a module not found error to provide a more specific message
85+
if (e.code === 'ERR_MODULE_NOT_FOUND') {
86+
errors.push(
87+
`The "browsers" option with "${providerName}" requires the "${providerPackage}" package.` +
88+
' Please install this package and rerun the test command.',
89+
);
90+
} else {
91+
// Handle other potential errors during import
92+
errors.push(
93+
`An error occurred while loading the "${providerPackage}" browser provider:\n ${e.message}`,
94+
);
95+
}
96+
}
8197
}
8298

8399
if (errors) {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export class VitestExecutor implements TestExecutor {
154154
const { startVitest } = vitestNodeModule;
155155

156156
// Setup vitest browser options if configured
157-
const browserOptions = setupBrowserConfiguration(
157+
const browserOptions = await setupBrowserConfiguration(
158158
browsers,
159159
debug,
160160
this.options.projectSourceRoot,
@@ -237,7 +237,6 @@ async function generateCoverageOption(
237237

238238
return {
239239
enabled: true,
240-
all: coverage.all,
241240
excludeAfterRemap: true,
242241
include: coverage.include,
243242
reportsDirectory: toPosixPath(path.join('coverage', projectName)),

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const VitestTestRunner: TestRunner = {
2323
checker.check('vitest');
2424

2525
if (options.browsers?.length) {
26-
checker.check('@vitest/browser');
2726
checker.checkAny(
2827
['playwright', 'webdriverio'],
2928
'The "browsers" option requires either "playwright" or "webdriverio" to be installed.',

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function createVitestPlugins(
4545
// Create a subproject that can be configured with plugins for browser mode.
4646
// Plugins defined directly in the vite overrides will not be present in the
4747
// browser specific Vite instance.
48-
await context.injectTestProjects({
48+
const [project] = await context.injectTestProjects({
4949
test: {
5050
name: projectName,
5151
root: workspaceRoot,
@@ -155,6 +155,13 @@ export function createVitestPlugins(
155155
},
156156
],
157157
});
158+
159+
// Filter the resolved coverage exclude patterns to remove non-string values.
160+
// This is a workaround for vitest adding `false` into the array when `startVitest` is
161+
// used with `config: false`. This can be removed once corrected in Vitest.
162+
project.config.coverage.exclude = project.config.coverage.exclude.filter(
163+
(pattern) => typeof pattern === 'string',
164+
);
158165
},
159166
},
160167
];

packages/angular/build/src/builders/unit-test/schema.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@
6464
"description": "Enables coverage reporting for tests.",
6565
"default": false
6666
},
67-
"coverageAll": {
68-
"type": "boolean",
69-
"description": "Includes all files that match the `coverageInclude` pattern in the coverage report, not just those touched by tests.",
70-
"default": true
71-
},
7267
"coverageInclude": {
7368
"type": "array",
7469
"description": "Specifies glob patterns of files to include in the coverage report.",

0 commit comments

Comments
 (0)