Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cf722f5

Browse files
committed
refactor(@angular/build): co-locate vitest browser provider logic
Refactors the Vitest test runner to improve code organization and separation of concerns. The browser-specific helper functions (`findBrowserProvider`, `normalizeBrowserName`, and `setupBrowserConfiguration`) are moved from the main `executor.ts` file into a new, dedicated `browser-provider.ts` file. This cleanup allows the main executor to focus solely on its primary responsibility of managing the test execution lifecycle, while properly encapsulating the browser setup logic in a single, co-located file.
1 parent d1dd3a8 commit cf722f5

File tree

2 files changed

+93
-83
lines changed

2 files changed

+93
-83
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { createRequire } from 'node:module';
10+
11+
function findBrowserProvider(
12+
projectResolver: NodeJS.RequireResolve,
13+
): import('vitest/node').BrowserBuiltinProvider | undefined {
14+
// One of these must be installed in the project to use browser testing
15+
const vitestBuiltinProviders = ['playwright', 'webdriverio'] as const;
16+
17+
for (const providerName of vitestBuiltinProviders) {
18+
try {
19+
projectResolver(providerName);
20+
21+
return providerName;
22+
} catch {}
23+
}
24+
25+
return undefined;
26+
}
27+
28+
function normalizeBrowserName(browserName: string): string {
29+
// Normalize browser names to match Vitest's expectations for headless but also supports karma's names
30+
// e.g., 'ChromeHeadless' -> 'chrome', 'FirefoxHeadless' -> 'firefox'
31+
// and 'Chrome' -> 'chrome', 'Firefox' -> 'firefox'.
32+
const normalized = browserName.toLowerCase();
33+
34+
return normalized.replace(/headless$/, '');
35+
}
36+
37+
export function setupBrowserConfiguration(
38+
browsers: string[] | undefined,
39+
debug: boolean,
40+
projectSourceRoot: string,
41+
): { browser?: import('vitest/node').BrowserConfigOptions; errors?: string[] } {
42+
if (browsers === undefined) {
43+
return {};
44+
}
45+
46+
const projectResolver = createRequire(projectSourceRoot + '/').resolve;
47+
let errors: string[] | undefined;
48+
49+
try {
50+
projectResolver('@vitest/browser');
51+
} catch {
52+
errors ??= [];
53+
errors.push(
54+
'The "browsers" option requires the "@vitest/browser" package to be installed within the project.' +
55+
' Please install this package and rerun the test command.',
56+
);
57+
}
58+
59+
const provider = findBrowserProvider(projectResolver);
60+
if (!provider) {
61+
errors ??= [];
62+
errors.push(
63+
'The "browsers" option requires either "playwright" or "webdriverio" to be installed within the project.' +
64+
' Please install one of these packages and rerun the test command.',
65+
);
66+
}
67+
68+
// Vitest current requires the playwright browser provider to use the inspect-brk option used by "debug"
69+
if (debug && provider !== 'playwright') {
70+
errors ??= [];
71+
errors.push(
72+
'Debugging browser mode tests currently requires the use of "playwright".' +
73+
' Please install this package and rerun the test command.',
74+
);
75+
}
76+
77+
if (errors) {
78+
return { errors };
79+
}
80+
81+
const browser = {
82+
enabled: true,
83+
provider,
84+
headless: browsers.some((name) => name.toLowerCase().includes('headless')),
85+
86+
instances: browsers.map((browserName) => ({
87+
browser: normalizeBrowserName(browserName),
88+
})),
89+
};
90+
91+
return { browser };
92+
}

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

Lines changed: 1 addition & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type { FullResult, IncrementalResult } from '../../../application/results
1919
import { writeTestFiles } from '../../../karma/application_builder';
2020
import { NormalizedUnitTestBuilderOptions } from '../../options';
2121
import type { TestExecutor } from '../api';
22+
import { setupBrowserConfiguration } from './browser-provider';
2223

2324
type VitestCoverageOption = Exclude<InlineConfig['coverage'], undefined>;
2425

@@ -171,89 +172,6 @@ export class VitestExecutor implements TestExecutor {
171172
}
172173
}
173174

174-
function findBrowserProvider(
175-
projectResolver: NodeJS.RequireResolve,
176-
): import('vitest/node').BrowserBuiltinProvider | undefined {
177-
// One of these must be installed in the project to use browser testing
178-
const vitestBuiltinProviders = ['playwright', 'webdriverio'] as const;
179-
180-
for (const providerName of vitestBuiltinProviders) {
181-
try {
182-
projectResolver(providerName);
183-
184-
return providerName;
185-
} catch {}
186-
}
187-
188-
return undefined;
189-
}
190-
191-
function normalizeBrowserName(browserName: string): string {
192-
// Normalize browser names to match Vitest's expectations for headless but also supports karma's names
193-
// e.g., 'ChromeHeadless' -> 'chrome', 'FirefoxHeadless' -> 'firefox'
194-
// and 'Chrome' -> 'chrome', 'Firefox' -> 'firefox'.
195-
const normalized = browserName.toLowerCase();
196-
197-
return normalized.replace(/headless$/, '');
198-
}
199-
200-
function setupBrowserConfiguration(
201-
browsers: string[] | undefined,
202-
debug: boolean,
203-
projectSourceRoot: string,
204-
): { browser?: import('vitest/node').BrowserConfigOptions; errors?: string[] } {
205-
if (browsers === undefined) {
206-
return {};
207-
}
208-
209-
const projectResolver = createRequire(projectSourceRoot + '/').resolve;
210-
let errors: string[] | undefined;
211-
212-
try {
213-
projectResolver('@vitest/browser');
214-
} catch {
215-
errors ??= [];
216-
errors.push(
217-
'The "browsers" option requires the "@vitest/browser" package to be installed within the project.' +
218-
' Please install this package and rerun the test command.',
219-
);
220-
}
221-
222-
const provider = findBrowserProvider(projectResolver);
223-
if (!provider) {
224-
errors ??= [];
225-
errors.push(
226-
'The "browsers" option requires either "playwright" or "webdriverio" to be installed within the project.' +
227-
' Please install one of these packages and rerun the test command.',
228-
);
229-
}
230-
231-
// Vitest current requires the playwright browser provider to use the inspect-brk option used by "debug"
232-
if (debug && provider !== 'playwright') {
233-
errors ??= [];
234-
errors.push(
235-
'Debugging browser mode tests currently requires the use of "playwright".' +
236-
' Please install this package and rerun the test command.',
237-
);
238-
}
239-
240-
if (errors) {
241-
return { errors };
242-
}
243-
244-
const browser = {
245-
enabled: true,
246-
provider,
247-
headless: browsers.some((name) => name.toLowerCase().includes('headless')),
248-
249-
instances: browsers.map((browserName) => ({
250-
browser: normalizeBrowserName(browserName),
251-
})),
252-
};
253-
254-
return { browser };
255-
}
256-
257175
function generateOutputPath(): string {
258176
const datePrefix = new Date().toISOString().replaceAll(/[-:.]/g, '');
259177
const uuidSuffix = randomUUID().slice(0, 8);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /