Skip to content

Commit 16ac741

Browse files
committed
fix(@schematics/angular): add actionable feedback to vitest-browser schematic
This commit adds a message at the end of the vitest-browser schematic to inform users how to configure browsers in angular.json or via the CLI. It also adds unit tests for the schematic.
1 parent 51fc778 commit 16ac741

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ export default function (options: VitestBrowserOptions): Rule {
9898
install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto,
9999
}),
100100
),
101+
(_, context) => {
102+
context.logger.info(
103+
'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.",
106+
);
107+
},
101108
]);
102109
};
103110
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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 { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
10+
import { parse } from 'jsonc-parser';
11+
12+
describe('Vitest Browser Provider Schematic', () => {
13+
const schematicRunner = new SchematicTestRunner(
14+
'@schematics/angular',
15+
require.resolve('../collection.json'),
16+
);
17+
18+
let tree: UnitTestTree;
19+
20+
beforeEach(async () => {
21+
tree = await schematicRunner.runSchematic('workspace', {
22+
name: 'workspace',
23+
newProjectRoot: 'projects',
24+
version: '6.0.0',
25+
});
26+
27+
tree = await schematicRunner.runSchematic(
28+
'application',
29+
{
30+
name: 'app',
31+
skipInstall: true,
32+
testRunner: 'vitest',
33+
},
34+
tree,
35+
);
36+
});
37+
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+
};
44+
45+
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
46+
47+
const packageJson = parse(resultTree.readContent('/package.json'));
48+
expect(packageJson.devDependencies['@vitest/browser-playwright']).toBeDefined();
49+
expect(packageJson.devDependencies['playwright']).toBeDefined();
50+
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');
55+
});
56+
57+
it('should add webdriverio dependency when @vitest/browser-webdriverio is used', async () => {
58+
const options = {
59+
project: 'app',
60+
package: '@vitest/browser-webdriverio',
61+
skipInstall: true,
62+
};
63+
64+
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
65+
66+
const packageJson = parse(resultTree.readContent('/package.json'));
67+
expect(packageJson.devDependencies['@vitest/browser-webdriverio']).toBeDefined();
68+
expect(packageJson.devDependencies['webdriverio']).toBeDefined();
69+
});
70+
71+
it('should update tsconfig.spec.json for a library project', async () => {
72+
tree = await schematicRunner.runSchematic(
73+
'library',
74+
{
75+
name: 'lib',
76+
skipInstall: true,
77+
},
78+
tree,
79+
);
80+
81+
const options = {
82+
project: 'lib',
83+
package: '@vitest/browser-playwright',
84+
skipInstall: true,
85+
};
86+
87+
const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree);
88+
89+
const tsConfig = parse(resultTree.readContent('/projects/lib/tsconfig.spec.json'));
90+
expect(tsConfig.compilerOptions.types).toContain('vitest/globals');
91+
expect(tsConfig.compilerOptions.types).toContain('@vitest/browser-playwright');
92+
// Library schematic might put jasmine types by default.
93+
expect(tsConfig.compilerOptions.types).not.toContain('jasmine');
94+
});
95+
96+
it('should throw if project does not exist', async () => {
97+
const options = {
98+
project: 'invalid',
99+
package: '@vitest/browser-playwright',
100+
};
101+
102+
await expectAsync(
103+
schematicRunner.runSchematic('vitest-browser', options, tree),
104+
).toBeRejectedWithError('Project "invalid" does not exist.');
105+
});
106+
107+
it('should throw if project uses Karma', async () => {
108+
const angularJson = parse(tree.readContent('/angular.json'));
109+
const project = angularJson.projects.app;
110+
const targets = project.architect || project.targets;
111+
112+
targets.test.options ??= {};
113+
targets.test.options.runner = 'karma';
114+
tree.overwrite('/angular.json', JSON.stringify(angularJson));
115+
116+
const options = {
117+
project: 'app',
118+
package: '@vitest/browser-playwright',
119+
};
120+
121+
await expectAsync(
122+
schematicRunner.runSchematic('vitest-browser', options, tree),
123+
).toBeRejectedWithError(
124+
'Project "app" is configured to use Karma. Please migrate to Vitest before adding browser testing support.',
125+
);
126+
});
127+
});

0 commit comments

Comments
 (0)