From 8f828989916c5814661ef343e41280fc681050b5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 20 Oct 2025 15:34:12 -0400 Subject: [PATCH] feat(@schematics/angular): configure Vitest for new projects and allow runner choice This commit updates the application, ng-new, and library schematics to configure Vitest as the default unit testing runner, replacing Karma and Jasmine. It also introduces a `testRunner` option to allow users to choose between `vitest` and `karma`. Key changes: Application & Ng-New Schematics: - Adds a `testRunner` option to allow choosing between `vitest` (default) and `karma`. - Sets "@angular/build:unit-test" as the builder for the "test" target when `vitest` is chosen, and "@angular/build:karma" for `karma`. - Conditionally adds dependencies based on the selected runner. - Updates "tsconfig.spec.json" to include "vitest/globals" or "jasmine" for type support. Library Schematic: - Conditionally configures the "test" target with the "@angular/build:unit-test" builder if Vitest is detected in the workspace. - Dynamically sets the "types" in "tsconfig.spec.json" to "vitest/globals" or "jasmine" based on the presence of Vitest. --- .../common-files/tsconfig.spec.json.template | 7 +- .../schematics/angular/application/index.ts | 90 +++++++++++++++--- .../angular/application/index_spec.ts | 94 +++++++++---------- .../angular/application/schema.json | 6 ++ .../schematics/angular/config/index_spec.ts | 6 ++ .../library/files/tsconfig.spec.json.template | 2 +- packages/schematics/angular/library/index.ts | 26 +++-- .../schematics/angular/library/index_spec.ts | 11 +++ packages/schematics/angular/ng-new/index.ts | 8 ++ .../schematics/angular/ng-new/index_spec.ts | 26 +++++ .../schematics/angular/ng-new/schema.json | 6 ++ .../utility/latest-versions/package.json | 2 + .../angular/utility/workspace-models.ts | 1 + .../workspace/files/package.json.template | 9 +- .../e2e/initialize/500-create-project.ts | 2 + .../generate/directive/directive-prefix.ts | 4 +- .../misc/update-git-clean-subdirectory.ts | 2 +- 17 files changed, 217 insertions(+), 85 deletions(-) diff --git a/packages/schematics/angular/application/files/common-files/tsconfig.spec.json.template b/packages/schematics/angular/application/files/common-files/tsconfig.spec.json.template index 11ab3b8614ff..75c646e8480a 100644 --- a/packages/schematics/angular/application/files/common-files/tsconfig.spec.json.template +++ b/packages/schematics/angular/application/files/common-files/tsconfig.spec.json.template @@ -4,10 +4,9 @@ "extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json", "compilerOptions": { "outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/spec", - "types": [ - "jasmine" - ] - }, + "types": [ + "<%= testRunner === 'vitest' ? 'vitest/globals' : 'jasmine' %>" + ] }, "include": [ "src/**/*.ts" ] diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index 38d1f8b0ffd3..295c65ba93ca 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -132,6 +132,7 @@ export default function (options: ApplicationOptions): Rule { appName: options.name, folderName, suffix, + testRunner: options.testRunner, }), move(appDir), ]), @@ -183,6 +184,65 @@ function addDependenciesToPackageJson(options: ApplicationOptions): Rule { ); } + if (!options.skipTests) { + if (options.testRunner === 'vitest') { + rules.push( + addDependency('vitest', latestVersions['vitest'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('jsdom', latestVersions['jsdom'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + ); + } else { + rules.push( + addDependency('karma', latestVersions['karma'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-chrome-launcher', latestVersions['karma-chrome-launcher'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-coverage', latestVersions['karma-coverage'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-jasmine', latestVersions['karma-jasmine'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency( + 'karma-jasmine-html-reporter', + latestVersions['karma-jasmine-html-reporter'], + { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }, + ), + addDependency('jasmine-core', latestVersions['jasmine-core'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('@types/jasmine', latestVersions['@types/jasmine'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + ); + } + } + return chain(rules); } @@ -327,18 +387,24 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul }, }, }, - test: options.minimal - ? undefined - : { - builder: Builders.BuildKarma, - options: { - polyfills: options.zoneless ? undefined : ['zone.js', 'zone.js/testing'], - tsConfig: `${projectRoot}tsconfig.spec.json`, - inlineStyleLanguage, - assets: [{ 'glob': '**/*', 'input': `${projectRoot}public` }], - styles: [`${sourceRoot}/styles.${options.style}`], - }, - }, + test: + options.skipTests || options.minimal + ? undefined + : options.testRunner === 'vitest' + ? { + builder: Builders.BuildUnitTest, + options: {}, + } + : { + builder: Builders.BuildKarma, + options: { + polyfills: options.zoneless ? undefined : ['zone.js', 'zone.js/testing'], + tsConfig: `${projectRoot}tsconfig.spec.json`, + inlineStyleLanguage, + assets: [{ 'glob': '**/*', 'input': `${projectRoot}public` }], + styles: [`${sourceRoot}/styles.${options.style}`], + }, + }, }, }; diff --git a/packages/schematics/angular/application/index_spec.ts b/packages/schematics/angular/application/index_spec.ts index 96916066343c..863d0d021cb6 100644 --- a/packages/schematics/angular/application/index_spec.ts +++ b/packages/schematics/angular/application/index_spec.ts @@ -110,6 +110,19 @@ describe('Application Schematic', () => { expect(_extends).toBe('../../tsconfig.json'); }); + it('should set the right types in the tsconfig.spec.json when testRunner is karma', async () => { + const tree = await schematicRunner.runSchematic( + 'application', + { ...defaultOptions, testRunner: 'karma' }, + workspaceTree, + ); + + const { + compilerOptions: { types }, + } = readJsonFile(tree, '/projects/foo/tsconfig.spec.json'); + expect(types).toEqual(['jasmine']); + }); + it('should add project references in the root tsconfig.json', async () => { const tree = await schematicRunner.runSchematic('application', defaultOptions, workspaceTree); @@ -324,6 +337,30 @@ describe('Application Schematic', () => { expect(pkg.dependencies['zone.js']).toBeUndefined(); }); + it('should add karma dependencies when testRunner is karma', async () => { + const tree = await schematicRunner.runSchematic( + 'application', + { + ...defaultOptions, + testRunner: 'karma', + }, + workspaceTree, + ); + + const pkg = JSON.parse(tree.readContent('/package.json')); + expect(pkg.devDependencies['karma']).toEqual(latestVersions['karma']); + expect(pkg.devDependencies['karma-chrome-launcher']).toEqual( + latestVersions['karma-chrome-launcher'], + ); + expect(pkg.devDependencies['karma-coverage']).toEqual(latestVersions['karma-coverage']); + expect(pkg.devDependencies['karma-jasmine']).toEqual(latestVersions['karma-jasmine']); + expect(pkg.devDependencies['karma-jasmine-html-reporter']).toEqual( + latestVersions['karma-jasmine-html-reporter'], + ); + expect(pkg.devDependencies['jasmine-core']).toEqual(latestVersions['jasmine-core']); + expect(pkg.devDependencies['@types/jasmine']).toEqual(latestVersions['@types/jasmine']); + }); + it(`should not override existing users dependencies`, async () => { const oldPackageJson = workspaceTree.readContent('package.json'); workspaceTree.overwrite( @@ -391,12 +428,6 @@ describe('Application Schematic', () => { expect(buildOpt.assets).toEqual([{ 'glob': '**/*', 'input': 'public' }]); expect(buildOpt.polyfills).toBeUndefined(); expect(buildOpt.tsConfig).toEqual('tsconfig.app.json'); - - const testOpt = prj.architect.test.options; - expect(testOpt.tsConfig).toEqual('tsconfig.spec.json'); - expect(testOpt.karmaConfig).toBeUndefined(); - expect(testOpt.assets).toEqual([{ 'glob': '**/*', 'input': 'public' }]); - expect(testOpt.styles).toEqual(['src/styles.css']); }); it('should set values in angular.json correctly when using a style preprocessor', async () => { @@ -407,51 +438,20 @@ describe('Application Schematic', () => { const prj = config.projects.foo; const buildOpt = prj.architect.build.options; expect(buildOpt.styles).toEqual(['src/styles.sass']); - const testOpt = prj.architect.test.options; - expect(testOpt.styles).toEqual(['src/styles.sass']); expect(tree.exists('src/styles.sass')).toBe(true); }); - it('sets "inlineStyleLanguage" in angular.json when using a style preprocessor', async () => { - const options = { ...defaultOptions, projectRoot: '', style: Style.Sass }; - const tree = await schematicRunner.runSchematic('application', options, workspaceTree); - - const config = JSON.parse(tree.readContent('/angular.json')); - const prj = config.projects.foo; - - const buildOpt = prj.architect.build.options; - expect(buildOpt.inlineStyleLanguage).toBe('sass'); - - const testOpt = prj.architect.test.options; - expect(testOpt.inlineStyleLanguage).toBe('sass'); - }); - - it('does not set "inlineStyleLanguage" in angular.json when not using a style preprocessor', async () => { - const options = { ...defaultOptions, projectRoot: '' }; + it('should set values in angular.json correctly when testRunner is karma', async () => { + const options = { ...defaultOptions, projectRoot: '', testRunner: 'karma' as const }; const tree = await schematicRunner.runSchematic('application', options, workspaceTree); const config = JSON.parse(tree.readContent('/angular.json')); const prj = config.projects.foo; - - const buildOpt = prj.architect.build.options; - expect(buildOpt.inlineStyleLanguage).toBeUndefined(); - - const testOpt = prj.architect.test.options; - expect(testOpt.inlineStyleLanguage).toBeUndefined(); - }); - - it('does not set "inlineStyleLanguage" in angular.json when using CSS styles', async () => { - const options = { ...defaultOptions, projectRoot: '', style: Style.Css }; - const tree = await schematicRunner.runSchematic('application', options, workspaceTree); - - const config = JSON.parse(tree.readContent('/angular.json')); - const prj = config.projects.foo; - - const buildOpt = prj.architect.build.options; - expect(buildOpt.inlineStyleLanguage).toBeUndefined(); - - const testOpt = prj.architect.test.options; - expect(testOpt.inlineStyleLanguage).toBeUndefined(); + const testOpt = prj.architect.test; + expect(testOpt.builder).toEqual('@angular/build:karma'); + expect(testOpt.options.tsConfig).toEqual('tsconfig.spec.json'); + expect(testOpt.options.assets).toEqual([{ glob: '**/*', input: 'public' }]); + expect(testOpt.options.styles).toEqual(['src/styles.css']); }); it('should set the relative tsconfig paths', async () => { @@ -482,12 +482,6 @@ describe('Application Schematic', () => { expect(buildOpt.tsConfig).toEqual('foo/tsconfig.app.json'); expect(buildOpt.assets).toEqual([{ 'glob': '**/*', 'input': 'foo/public' }]); - const testOpt = project.architect.test.options; - expect(testOpt.tsConfig).toEqual('foo/tsconfig.spec.json'); - expect(testOpt.karmaConfig).toBeUndefined(); - expect(testOpt.assets).toEqual([{ 'glob': '**/*', 'input': 'foo/public' }]); - expect(testOpt.styles).toEqual(['foo/src/styles.css']); - const appTsConfig = readJsonFile(tree, '/foo/tsconfig.app.json'); expect(appTsConfig.extends).toEqual('../tsconfig.json'); const specTsConfig = readJsonFile(tree, '/foo/tsconfig.spec.json'); diff --git a/packages/schematics/angular/application/schema.json b/packages/schematics/angular/application/schema.json index bc3504be298a..f047232c23cc 100644 --- a/packages/schematics/angular/application/schema.json +++ b/packages/schematics/angular/application/schema.json @@ -89,6 +89,12 @@ "default": false, "alias": "S" }, + "testRunner": { + "description": "The unit testing runner to use.", + "type": "string", + "enum": ["vitest", "karma"], + "default": "vitest" + }, "skipPackageJson": { "type": "boolean", "default": false, diff --git a/packages/schematics/angular/config/index_spec.ts b/packages/schematics/angular/config/index_spec.ts index f7f7b335ad68..1bbc08d9e85b 100644 --- a/packages/schematics/angular/config/index_spec.ts +++ b/packages/schematics/angular/config/index_spec.ts @@ -50,6 +50,12 @@ describe('Config Schematic', () => { defaultAppOptions, workspaceTree, ); + + // Set builder to a karma builder for testing purposes + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const angularJson = applicationTree.readJson('angular.json') as any; + angularJson['projects']['foo']['architect']['test']['builder'] = '@angular/build:karma'; + applicationTree.overwrite('angular.json', JSON.stringify(angularJson)); }); describe(`when 'type' is 'karma'`, () => { diff --git a/packages/schematics/angular/library/files/tsconfig.spec.json.template b/packages/schematics/angular/library/files/tsconfig.spec.json.template index 11ab3b8614ff..0cec657c8ae9 100644 --- a/packages/schematics/angular/library/files/tsconfig.spec.json.template +++ b/packages/schematics/angular/library/files/tsconfig.spec.json.template @@ -5,7 +5,7 @@ "compilerOptions": { "outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/spec", "types": [ - "jasmine" + "<%= testTypesPackage %>" ] }, "include": [ diff --git a/packages/schematics/angular/library/index.ts b/packages/schematics/angular/library/index.ts index 973cab7987d7..b02e35b27758 100644 --- a/packages/schematics/angular/library/index.ts +++ b/packages/schematics/angular/library/index.ts @@ -91,6 +91,7 @@ function addLibToWorkspaceFile( projectRoot: string, projectName: string, hasZoneDependency: boolean, + hasVitest: boolean, ): Rule { return updateWorkspace((workspace) => { workspace.projects.add({ @@ -112,13 +113,20 @@ function addLibToWorkspaceFile( }, }, }, - test: { - builder: Builders.BuildKarma, - options: { - tsConfig: `${projectRoot}/tsconfig.spec.json`, - polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined, - }, - }, + test: hasVitest + ? { + builder: Builders.BuildUnitTest, + options: { + tsConfig: `${projectRoot}/tsconfig.spec.json`, + }, + } + : { + builder: Builders.BuildKarma, + options: { + tsConfig: `${projectRoot}/tsconfig.spec.json`, + polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined, + }, + }, }, }); }); @@ -150,6 +158,7 @@ export default function (options: LibraryOptions): Rule { const distRoot = `dist/${folderName}`; const sourceDir = `${libDir}/src/lib`; + const hasVitest = getDependency(host, 'vitest') !== null; const templateSource = apply(url('./files'), [ applyTemplates({ @@ -163,6 +172,7 @@ export default function (options: LibraryOptions): Rule { angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''), tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''), folderName, + testTypesPackage: hasVitest ? 'vitest/globals' : 'jasmine', }), move(libDir), ]); @@ -171,7 +181,7 @@ export default function (options: LibraryOptions): Rule { return chain([ mergeWith(templateSource), - addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency), + addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency, hasVitest), options.skipPackageJson ? noop() : addDependenciesToPackageJson(!!options.skipInstall), options.skipTsConfig ? noop() : updateTsConfig(packageName, './' + distRoot), options.skipTsConfig diff --git a/packages/schematics/angular/library/index_spec.ts b/packages/schematics/angular/library/index_spec.ts index ecf628577f11..319abbaa5162 100644 --- a/packages/schematics/angular/library/index_spec.ts +++ b/packages/schematics/angular/library/index_spec.ts @@ -414,6 +414,17 @@ describe('Library Schematic', () => { expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:karma'); }); + it(`should add 'unit-test' test builder`, async () => { + const packageJson = getJsonFileContent(workspaceTree, 'package.json'); + packageJson['devDependencies']['vitest'] = '^4.0.0'; + workspaceTree.overwrite('package.json', JSON.stringify(packageJson)); + + const tree = await schematicRunner.runSchematic('library', defaultOptions, workspaceTree); + + const workspace = JSON.parse(tree.readContent('/angular.json')); + expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:unit-test'); + }); + describe('standalone=false', () => { const defaultNonStandaloneOptions = { ...defaultOptions, standalone: false }; diff --git a/packages/schematics/angular/ng-new/index.ts b/packages/schematics/angular/ng-new/index.ts index 019a193290bd..7fca64d69ce3 100644 --- a/packages/schematics/angular/ng-new/index.ts +++ b/packages/schematics/angular/ng-new/index.ts @@ -23,6 +23,7 @@ import { RepositoryInitializerTask, } from '@angular-devkit/schematics/tasks'; import { Schema as ApplicationOptions } from '../application/schema'; +import { JSONFile } from '../utility/json-file'; import { Schema as WorkspaceOptions } from '../workspace/schema'; import { Schema as NgNewOptions } from './schema'; @@ -50,6 +51,7 @@ export default function (options: NgNewOptions): Rule { routing: options.routing, style: options.style, skipTests: options.skipTests, + testRunner: options.testRunner, skipPackageJson: false, // always 'skipInstall' here, so that we do it after the move skipInstall: true, @@ -69,6 +71,12 @@ export default function (options: NgNewOptions): Rule { schematic('ai-config', { tool: options.aiConfig?.length ? options.aiConfig : undefined, }), + (tree: Tree) => { + if (options.testRunner === 'karma') { + const file = new JSONFile(tree, 'angular.json'); + file.modify(['schematics', '@schematics/angular:application', 'testRunner'], 'karma'); + } + }, move(options.directory), ]), ), diff --git a/packages/schematics/angular/ng-new/index_spec.ts b/packages/schematics/angular/ng-new/index_spec.ts index 50d9abf04191..20306b875a9a 100644 --- a/packages/schematics/angular/ng-new/index_spec.ts +++ b/packages/schematics/angular/ng-new/index_spec.ts @@ -158,6 +158,32 @@ describe('Ng New Schematic', () => { expect(schematics['@schematics/angular:resolver'].typeSeparator).toBe('.'); }); + it(`should set 'testRunner' to 'karma'`, async () => { + const options = { ...defaultOptions, testRunner: 'karma' as const }; + const tree = await schematicRunner.runSchematic('ng-new', options); + + const { + projects: { + 'foo': { + architect: { test }, + }, + }, + } = JSON.parse(tree.readContent('/bar/angular.json')); + expect(test.builder).toBe('@angular/build:karma'); + + const { devDependencies } = JSON.parse(tree.readContent('/bar/package.json')); + expect(devDependencies['karma']).toBeDefined(); + expect(devDependencies['jasmine-core']).toBeDefined(); + }); + + it(`should set 'testRunner' to 'karma' in workspace schematic options`, async () => { + const options = { ...defaultOptions, testRunner: 'karma' as const }; + const tree = await schematicRunner.runSchematic('ng-new', options); + + const { schematics } = JSON.parse(tree.readContent('/bar/angular.json')); + expect(schematics['@schematics/angular:application'].testRunner).toBe('karma'); + }); + it(`should not add type to class name when file name style guide is '2016'`, async () => { const options = { ...defaultOptions, fileNameStyleGuide: '2016' }; diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index afdef38e88da..3bbb0eb3dee4 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -108,6 +108,12 @@ "default": false, "alias": "S" }, + "testRunner": { + "description": "The unit testing runner to use.", + "type": "string", + "enum": ["vitest", "karma"], + "default": "vitest" + }, "createApplication": { "description": "Create a new initial application project in the new workspace. When false, creates an empty workspace with no initial application. You can then use the `ng generate application` command to create applications in the `projects` directory.", "type": "boolean", diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 28342b63df4e..0c6385202905 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -15,6 +15,7 @@ "karma-jasmine-html-reporter": "~2.1.0", "karma-jasmine": "~5.1.0", "karma": "~6.4.0", + "jsdom": "^27.0.0", "less": "^4.2.0", "postcss": "^8.5.3", "protractor": "~7.0.0", @@ -24,6 +25,7 @@ "tslib": "^2.3.0", "ts-node": "~10.9.0", "typescript": "~5.9.2", + "vitest": "^4.0.0", "zone.js": "~0.15.0" } } diff --git a/packages/schematics/angular/utility/workspace-models.ts b/packages/schematics/angular/utility/workspace-models.ts index 34c329b470d1..e4a570410371 100644 --- a/packages/schematics/angular/utility/workspace-models.ts +++ b/packages/schematics/angular/utility/workspace-models.ts @@ -27,6 +27,7 @@ export enum Builders { BrowserEsbuild = '@angular-devkit/build-angular:browser-esbuild', Karma = '@angular-devkit/build-angular:karma', BuildKarma = '@angular/build:karma', + BuildUnitTest = '@angular/build:unit-test', TsLint = '@angular-devkit/build-angular:tslint', NgPackagr = '@angular-devkit/build-angular:ng-packagr', BuildNgPackagr = '@angular/build:ng-packagr', diff --git a/packages/schematics/angular/workspace/files/package.json.template b/packages/schematics/angular/workspace/files/package.json.template index 629ae681ceac..790f65acf407 100644 --- a/packages/schematics/angular/workspace/files/package.json.template +++ b/packages/schematics/angular/workspace/files/package.json.template @@ -34,14 +34,7 @@ }, "devDependencies": { "@angular/cli": "<%= '^' + version %>", - "@angular/compiler-cli": "<%= latestVersions.Angular %>",<% if (!minimal) { %> - "@types/jasmine": "<%= latestVersions['@types/jasmine'] %>", - "jasmine-core": "<%= latestVersions['jasmine-core'] %>", - "karma": "<%= latestVersions['karma'] %>", - "karma-chrome-launcher": "<%= latestVersions['karma-chrome-launcher'] %>", - "karma-coverage": "<%= latestVersions['karma-coverage'] %>", - "karma-jasmine": "<%= latestVersions['karma-jasmine'] %>", - "karma-jasmine-html-reporter": "<%= latestVersions['karma-jasmine-html-reporter'] %>",<% } %> + "@angular/compiler-cli": "<%= latestVersions.Angular %>", "typescript": "<%= latestVersions['typescript'] %>" } } diff --git a/tests/legacy-cli/e2e/initialize/500-create-project.ts b/tests/legacy-cli/e2e/initialize/500-create-project.ts index 2b8fd9143b9a..c6c0f8ef243d 100644 --- a/tests/legacy-cli/e2e/initialize/500-create-project.ts +++ b/tests/legacy-cli/e2e/initialize/500-create-project.ts @@ -24,6 +24,8 @@ export default async function () { 'new', 'test-project', '--skip-install', + '--test-runner', + 'karma', '--package-manager', getActivePackageManager(), ); diff --git a/tests/legacy-cli/e2e/tests/generate/directive/directive-prefix.ts b/tests/legacy-cli/e2e/tests/generate/directive/directive-prefix.ts index b0a95ce399cb..a8b5981b34a3 100644 --- a/tests/legacy-cli/e2e/tests/generate/directive/directive-prefix.ts +++ b/tests/legacy-cli/e2e/tests/generate/directive/directive-prefix.ts @@ -17,7 +17,9 @@ export default function () { ) .then(() => ng('generate', 'directive', 'test2-directive')) .then(() => expectFileToMatch(join(directiveDir, 'test2-directive.ts'), /selector: '\[preW/)) - .then(() => ng('generate', 'application', 'app-two', '--skip-install')) + .then(() => + ng('generate', 'application', 'app-two', '--skip-install', '--test-runner', 'karma'), + ) .then(() => useCIDefaults('app-two')) .then(() => useCIChrome('app-two', './projects/app-two')) .then(() => diff --git a/tests/legacy-cli/e2e/tests/misc/update-git-clean-subdirectory.ts b/tests/legacy-cli/e2e/tests/misc/update-git-clean-subdirectory.ts index 11040c618bbb..733a91164019 100644 --- a/tests/legacy-cli/e2e/tests/misc/update-git-clean-subdirectory.ts +++ b/tests/legacy-cli/e2e/tests/misc/update-git-clean-subdirectory.ts @@ -11,7 +11,7 @@ export default async function () { await silentGit('init', '.'); - await ng('new', 'subdirectory-test-project', '--skip-install'); + await ng('new', 'subdirectory-test-project', '--skip-install', '--test-runner', 'karma'); process.chdir('./subdirectory-test-project'); await prepareProjectForE2e('subdirectory-test-project');