diff --git a/packages/angular/migrations.json b/packages/angular/migrations.json index 6428c9e93e..08bcf298de 100644 --- a/packages/angular/migrations.json +++ b/packages/angular/migrations.json @@ -177,6 +177,12 @@ "description": "Replace @nrwl/angular with @nx/angular", "implementation": "./src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages" }, + "remove-protractor-defaults-from-generators": { + "cli": "nx", + "version": "16.0.0-beta.6", + "description": "Remove protractor as default e2eTestRunner from nxJson and project configurations", + "implementation": "./src/migrations/update-16-0-0/remove-protractor-defaults" + }, "remove-karma-defaults-from-generators": { "cli": "nx", "version": "16.0.0-beta.6", diff --git a/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.spec.ts b/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.spec.ts new file mode 100644 index 0000000000..f741a21e8c --- /dev/null +++ b/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.spec.ts @@ -0,0 +1,179 @@ +import { + addProjectConfiguration, + readNxJson, + readProjectConfiguration, + updateNxJson, +} from '@nx/devkit'; +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import removeProtractorDefaults from './remove-protractor-defaults'; + +describe('removeProtractorDefaults', () => { + it('should remove protractor as default unit test runner from nx.json when exists', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace(); + + const nxJson = readNxJson(tree); + nxJson.generators = { + '@nrwl/angular:application': { + e2eTestRunner: 'protractor', + }, + '@nrwl/angular:host': { + e2eTestRunner: 'protractor', + }, + '@nrwl/angular:remote': { + e2eTestRunner: 'protractor', + }, + }; + updateNxJson(tree, nxJson); + + // ACT + await removeProtractorDefaults(tree); + + // ASSERT + expect(readNxJson(tree).generators).toMatchInlineSnapshot(` + { + "@nrwl/angular:application": {}, + "@nrwl/angular:host": {}, + "@nrwl/angular:remote": {}, + } + `); + }); + + it('should only remove protractor as default unit test runner from nx.json when set', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace(); + + const nxJson = readNxJson(tree); + nxJson.generators = { + '@nrwl/angular:application': { + style: 'scss', + e2eTestRunner: 'protractor', + }, + '@nrwl/angular:host': { + style: 'scss', + e2eTestRunner: 'protractor', + }, + '@nrwl/angular:remote': { + e2eTestRunner: 'cypress', + }, + }; + updateNxJson(tree, nxJson); + + // ACT + await removeProtractorDefaults(tree); + + // ASSERT + expect(readNxJson(tree).generators).toMatchInlineSnapshot(` + { + "@nrwl/angular:application": { + "style": "scss", + }, + "@nrwl/angular:host": { + "style": "scss", + }, + "@nrwl/angular:remote": { + "e2eTestRunner": "cypress", + }, + } + `); + }); + + it('should not remove protractor as default e2e test runner from unsupported generator', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace(); + + const nxJson = readNxJson(tree); + nxJson.generators = { + '@my/custom:plugin': { + style: 'scss', + e2eTestRunner: 'protractor', + }, + }; + updateNxJson(tree, nxJson); + + // ACT + await removeProtractorDefaults(tree); + + // ASSERT + expect(readNxJson(tree).generators).toMatchInlineSnapshot(` + { + "@my/custom:plugin": { + "e2eTestRunner": "protractor", + "style": "scss", + }, + } + `); + }); + + it('should remove protractor as default for project specific generators', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace(); + addProjectConfiguration(tree, 'test', { + name: 'test', + root: '.', + sourceRoot: 'src', + generators: { + '@nrwl/angular:application': { + style: 'scss', + e2eTestRunner: 'protractor', + }, + }, + }); + + // ACT + await removeProtractorDefaults(tree); + + // ASSERT + expect(readProjectConfiguration(tree, 'test').generators) + .toMatchInlineSnapshot(` + { + "@nrwl/angular:application": { + "style": "scss", + }, + } + `); + }); + + it('should remove protractor when using nested generator default syntax', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace(); + + const nxJson = readNxJson(tree); + nxJson.generators = { + '@nrwl/angular:application': { + style: 'scss', + e2eTestRunner: 'protractor', + }, + '@nrwl/angular': { + host: { + style: 'scss', + e2eTestRunner: 'protractor', + }, + remote: { + e2eTestRunner: 'cypress', + }, + }, + }; + updateNxJson(tree, nxJson); + + // ACT + await removeProtractorDefaults(tree); + + // ASSERT + expect(readNxJson(tree).generators).toMatchInlineSnapshot(` + { + "@nrwl/angular": { + "host": { + "style": "scss", + }, + "remote": { + "e2eTestRunner": "cypress", + }, + }, + "@nrwl/angular:application": { + "style": "scss", + }, + } + `); + }); +}); diff --git a/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.ts b/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.ts new file mode 100644 index 0000000000..5ed0c64661 --- /dev/null +++ b/packages/angular/src/migrations/update-16-0-0/remove-protractor-defaults.ts @@ -0,0 +1,83 @@ +import type { + NxJsonConfiguration, + ProjectConfiguration, + Tree, +} from '@nx/devkit'; +import { + formatFiles, + getProjects, + readNxJson, + updateNxJson, + updateProjectConfiguration, +} from '@nx/devkit'; + +const GENERATORS = ['application', 'host', 'remote']; +const CANDIDATE_GENERATOR_COLLECTIONS = ['@nrwl/angular', '@nx/angular']; + +export default async function removeProtractorDefaults(tree: Tree) { + const nxJson = readNxJson(tree); + + if (nxJson.generators) { + const updatedConfig = updateE2ETestRunner(nxJson.generators); + + if (updatedConfig) { + updateNxJson(tree, nxJson); + } + } + + const projects = getProjects(tree); + + for (const [projectName, projectConfig] of projects) { + if (projectConfig.generators) { + const updatedProject = updateE2ETestRunner(projectConfig.generators); + + if (updatedProject) { + updateProjectConfiguration(tree, projectName, projectConfig); + } + } + } + + await formatFiles(tree); +} + +function updateE2ETestRunner( + generatorsConfig: + | NxJsonConfiguration['generators'] + | ProjectConfiguration['generators'] +) { + const generators = Object.entries(generatorsConfig); + + let updatedConfig = false; + for (const [generatorName, generatorDefaults] of generators) { + if (CANDIDATE_GENERATOR_COLLECTIONS.includes(generatorName)) { + for (const possibleGenerator of GENERATORS) { + if ( + generatorDefaults[possibleGenerator] && + generatorDefaults[possibleGenerator]['e2eTestRunner'] && + generatorDefaults[possibleGenerator]['e2eTestRunner'] === 'protractor' + ) { + generatorsConfig[generatorName][possibleGenerator]['e2eTestRunner'] = + undefined; + updatedConfig = true; + } + } + } + + if ( + !GENERATORS.map((v) => `@nrwl/angular:${v}`).includes(generatorName) && + !GENERATORS.map((v) => `@nx/angular:${v}`).includes(generatorName) + ) { + continue; + } + + if ( + generatorDefaults['e2eTestRunner'] && + generatorDefaults['e2eTestRunner'] === 'protractor' + ) { + generatorsConfig[generatorName]['e2eTestRunner'] = undefined; + updatedConfig = true; + } + } + + return updatedConfig; +}