Skip to content

Commit 08455a6

Browse files
maruthangalan-agius4
authored andcommitted
fix(@schematics/angular): add browsers option to angular.json during vitest browser provider ng-add
When adding a Vitest browser provider via ng-add, the schematic now automatically configures the 'browsers' option in angular.json with an appropriate default browser (chromium for Playwright/Preview, chrome for WebDriverIO) instead of only logging a manual instruction. Fixes #32401
1 parent d968259 commit 08455a6

2 files changed

Lines changed: 78 additions & 22 deletions

File tree

‎packages/schematics/angular/vitest-browser/index.ts‎

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '../utility/dependency';
2323
import { JSONFile } from '../utility/json-file';
2424
import { latestVersions } from '../utility/latest-versions';
25-
import { getWorkspace } from '../utility/workspace';
25+
import { getWorkspace, updateWorkspace } from '../utility/workspace';
2626
import { Builders } from '../utility/workspace-models';
2727
import { Schema as VitestBrowserOptions } from './schema';
2828

@@ -89,8 +89,33 @@ export default function (options: VitestBrowserOptions): Rule {
8989
}
9090
};
9191

92+
// Determine the default browser based on the provider package
93+
let defaultBrowser: string;
94+
if (packageName === '@vitest/browser-webdriverio') {
95+
defaultBrowser = 'chrome';
96+
} else {
97+
// Playwright and preview both use 'chromium' as the default
98+
defaultBrowser = 'chromium';
99+
}
100+
101+
// Update angular.json to add the browsers option to the test target
102+
const updateAngularJsonRule = updateWorkspace((workspace) => {
103+
const project = workspace.projects.get(options.project);
104+
if (project) {
105+
const testTarget = project.targets.get('test');
106+
if (testTarget) {
107+
testTarget.options ??= {};
108+
const existingBrowsers = testTarget.options['browsers'] as string[] | undefined;
109+
if (!existingBrowsers?.length) {
110+
testTarget.options['browsers'] = [defaultBrowser];
111+
}
112+
}
113+
}
114+
});
115+
92116
return chain([
93117
updateTsConfigRule,
118+
updateAngularJsonRule,
94119
...dependencies.map((name) =>
95120
addDependency(name, latestVersions[name], {
96121
type: DependencyType.Dev,
@@ -101,8 +126,7 @@ export default function (options: VitestBrowserOptions): Rule {
101126
(_, context) => {
102127
context.logger.info(
103128
'Vitest browser testing support has been added. ' +
104-
"To run tests in a browser, add a 'browsers' field to the 'test' target in 'angular.json', " +
105-
"or use the '--browsers' command line option.",
129+
`The test target has been configured with '${defaultBrowser}' as the default browser.`,
106130
);
107131
},
108132
]);

‎packages/schematics/angular/vitest-browser/index_spec.ts‎

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,37 +35,69 @@ describe('Vitest Browser Provider Schematic', () => {
3535
);
3636
});
3737

38-
it('should add dependencies and update tsconfig.spec.json', async () => {
39-
const options = {
40-
project: 'app',
41-
package: '@vitest/browser-playwright',
42-
skipInstall: true,
43-
};
38+
[
39+
{ pkg: '@vitest/browser-playwright', browser: 'chromium', extraDeps: ['playwright'] },
40+
{ pkg: '@vitest/browser-webdriverio', browser: 'chrome', extraDeps: ['webdriverio'] },
41+
{ pkg: '@vitest/browser-preview', browser: 'chromium', extraDeps: [] as string[] },
42+
].forEach(({ pkg, browser, extraDeps }) => {
43+
it(`should add ${browser} to browsers option in angular.json for ${pkg}`, async () => {
44+
const options = {
45+
project: 'app',
46+
package: pkg,
47+
skipInstall: true,
48+
};
4449

45-
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
50+
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
4651

47-
const packageJson = parse(resultTree.readContent('/package.json'));
48-
expect(packageJson.devDependencies['@vitest/browser-playwright']).toBeDefined();
49-
expect(packageJson.devDependencies['playwright']).toBeDefined();
52+
const angularJson = parse(resultTree.readContent('/angular.json'));
53+
const project = angularJson.projects.app;
54+
const targets = project.architect || project.targets;
55+
expect(targets.test.options.browsers).toEqual([browser]);
56+
});
5057

51-
const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json'));
52-
expect(tsConfig.compilerOptions.types).toContain('vitest/globals');
53-
expect(tsConfig.compilerOptions.types).toContain('@vitest/browser-playwright');
54-
expect(tsConfig.compilerOptions.types).not.toContain('jasmine');
58+
it(`should add dependencies and update tsconfig.spec.json for ${pkg}`, async () => {
59+
const options = {
60+
project: 'app',
61+
package: pkg,
62+
skipInstall: true,
63+
};
64+
65+
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
66+
67+
const packageJson = parse(resultTree.readContent('/package.json'));
68+
expect(packageJson.devDependencies[pkg]).toBeDefined();
69+
for (const dep of extraDeps) {
70+
expect(packageJson.devDependencies[dep]).toBeDefined();
71+
}
72+
73+
const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json'));
74+
expect(tsConfig.compilerOptions.types).toContain('vitest/globals');
75+
expect(tsConfig.compilerOptions.types).toContain(pkg);
76+
expect(tsConfig.compilerOptions.types).not.toContain('jasmine');
77+
});
5578
});
5679

57-
it('should add webdriverio dependency when @vitest/browser-webdriverio is used', async () => {
80+
it('should not overwrite existing browsers option in angular.json', async () => {
81+
// Set up existing browsers option
82+
const angularJson = parse(tree.readContent('/angular.json'));
83+
const project = angularJson.projects.app;
84+
const targets = project.architect || project.targets;
85+
targets.test.options ??= {};
86+
targets.test.options.browsers = ['firefox'];
87+
tree.overwrite('/angular.json', JSON.stringify(angularJson));
88+
5889
const options = {
5990
project: 'app',
60-
package: '@vitest/browser-webdriverio',
91+
package: '@vitest/browser-playwright',
6192
skipInstall: true,
6293
};
6394

6495
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
6596

66-
const packageJson = parse(resultTree.readContent('/package.json'));
67-
expect(packageJson.devDependencies['@vitest/browser-webdriverio']).toBeDefined();
68-
expect(packageJson.devDependencies['webdriverio']).toBeDefined();
97+
const updatedAngularJson = parse(resultTree.readContent('/angular.json'));
98+
const updatedProject = updatedAngularJson.projects.app;
99+
const updatedTargets = updatedProject.architect || updatedProject.targets;
100+
expect(updatedTargets.test.options.browsers).toEqual(['firefox']);
69101
});
70102

71103
it('should update tsconfig.spec.json for a library project', async () => {

0 commit comments

Comments
 (0)