From ce70b31ef67d9d0588a602b1b57b46921ab841c2 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 7 Jan 2026 11:28:50 -0500 Subject: [PATCH] fix(@angular/build): ensure correct project targeting during Vitest debugging This addresses issue #31652 where debugging failed to target the correct project instance. When running browser tests, Vitest appends the browser name to the project identifier. This change updates the CLI to match that naming convention when initiating a debug session, ensuring the correct project is selected. Fixes #31652 --- .../unit-test/runners/vitest/executor.ts | 22 ++++++++++++++++--- .../unit-test/runners/vitest/index.ts | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index 00782d1704cf..ed754d9f9c30 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { BuilderOutput } from '@angular-devkit/architect'; +import type { BuilderContext, BuilderOutput } from '@angular-devkit/architect'; import assert from 'node:assert'; -import path, { join } from 'node:path'; +import path from 'node:path'; import type { Vitest } from 'vitest/node'; import { DevServerExternalResultMetadata, @@ -32,6 +32,7 @@ export class VitestExecutor implements TestExecutor { private normalizePath: ((id: string) => string) | undefined; private readonly projectName: string; private readonly options: NormalizedUnitTestBuilderOptions; + private readonly logger: BuilderContext['logger']; private readonly buildResultFiles = new Map(); private readonly externalMetadata: DevServerExternalResultMetadata = { implicitBrowser: [], @@ -51,9 +52,11 @@ export class VitestExecutor implements TestExecutor { projectName: string, options: NormalizedUnitTestBuilderOptions, testEntryPointMappings: Map | undefined, + logger: BuilderContext['logger'], ) { this.projectName = projectName; this.options = options; + this.logger = logger; if (testEntryPointMappings) { for (const [entryPoint, testFile] of testEntryPointMappings) { @@ -209,13 +212,26 @@ export class VitestExecutor implements TestExecutor { ? await findVitestBaseConfig([projectRoot, workspaceRoot]) : runnerConfig; + let project = projectName; + if (debug && browserOptions.browser?.instances) { + if (browserOptions.browser.instances.length > 1) { + this.logger.warn( + 'Multiple browsers are configured, but only the first browser will be used for debugging.', + ); + } + + // When running browser tests, Vitest appends the browser name to the project identifier. + // The project name must match this augmented name to ensure the correct project is targeted. + project = `${projectName} (${browserOptions.browser.instances[0].browser})`; + } + return startVitest( 'test', undefined, { config: externalConfigPath, root: workspaceRoot, - project: projectName, + project, outputFile, cache: cacheOptions.enabled ? undefined : false, testNamePattern: this.options.filter, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts index fed814bdd78e..081d635c1a2b 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts @@ -67,7 +67,7 @@ const VitestTestRunner: TestRunner = { context.logger.info('Automatically searching for and using Vitest configuration file.'); } - return new VitestExecutor(projectName, options, testEntryPointMappings); + return new VitestExecutor(projectName, options, testEntryPointMappings, context.logger); }, };