diff --git a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts index a13d8ea44a1c7..940204006de42 100644 --- a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts +++ b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts @@ -5,6 +5,7 @@ import { ProjectGraph, readProjectConfiguration, Tree, + updateProjectConfiguration, } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { applicationGenerator } from '../application/application'; @@ -158,21 +159,60 @@ describe('Cypress Component Testing Configuration', () => { }); }); - it('should throw if --build-target is invalid', async () => { + it('should throw with invalid --build-target', async () => { + await applicationGenerator(tree, { + name: 'fancy-app', + }); await libraryGenerator(tree, { name: 'fancy-lib', }); - await expect( - cypressComponentConfiguration(tree, { + await componentGenerator(tree, { + name: 'fancy-cmp', + project: 'fancy-lib', + export: true, + }); + const appConfig = readProjectConfiguration(tree, 'fancy-app'); + appConfig.targets['build'].executor = 'something/else'; + updateProjectConfiguration(tree, 'fancy-app', appConfig); + projectGraph = { + nodes: { + 'fancy-app': { + name: 'fancy-app', + type: 'app', + data: { + ...appConfig, + }, + }, + 'fancy-lib': { + name: 'fancy-lib', + type: 'lib', + data: { + ...readProjectConfiguration(tree, 'fancy-lib'), + }, + }, + }, + dependencies: { + 'fancy-app': [ + { + type: DependencyType.static, + source: 'fancy-app', + target: 'fancy-lib', + }, + ], + }, + }; + await expect(async () => { + await cypressComponentConfiguration(tree, { project: 'fancy-lib', - buildTarget: 'fancy-app:build:development', + buildTarget: 'fancy-app:build', generateTests: false, - }) - ).rejects - .toThrow(`Error trying to find build configuration. Try manually specifying the build target with the --build-target flag. -Provided project? fancy-lib -Provided build target? fancy-app:build:development -Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular:browser`); + }); + }).rejects.toThrowErrorMatchingInlineSnapshot(` + "Error trying to find build configuration. Try manually specifying the build target with the --build-target flag. + Provided project? fancy-lib + Provided build target? fancy-app:build + Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular:browser" + `); }); it('should use own project config', async () => { await applicationGenerator(tree, { @@ -273,6 +313,7 @@ Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular }); }); + it('should throw if an invalid --build-target', async () => {}); it('should work with simple components', async () => { await libraryGenerator(tree, { name: 'my-lib', diff --git a/packages/cypress/src/utils/find-target-options.ts b/packages/cypress/src/utils/find-target-options.ts index 6238037d83f81..7b0ddb72608fe 100644 --- a/packages/cypress/src/utils/find-target-options.ts +++ b/packages/cypress/src/utils/find-target-options.ts @@ -58,6 +58,7 @@ export async function findBuildConfig( // attempt to find any projects with the valid config in the graph that consumes this project return await findInGraph(tree, graph, options); } catch (e) { + logger.error(e); throw new Error(stripIndents`Error trying to find build configuration. Try manually specifying the build target with the --build-target flag. Provided project? ${options.project} Provided build target? ${options.buildTarget} @@ -74,6 +75,27 @@ function findInTarget( options.buildTarget ); const projectConfig = readProjectConfiguration(tree, project); + const executorName = projectConfig?.targets?.[target]?.executor; + if (!options.validExecutorNames.has(executorName)) { + logger.error(stripIndents`NX The provided build target, ${ + options.buildTarget + }, uses the '${executorName}' executor. +But only the follow executors are allowed +${Array.from(options.validExecutorNames) + .map((ve) => ` - ${ve}`) + .join('\n')} + +This is most likely because the provided --build-target is not a build target for an application. +For example, the provide build target, '${options.buildTarget}' is: + - the build target for a buildable/publishable library instead of an app. + - using a different framework than expected like react library using an angular app build target. + +If you do not have an app in the workspace to you can make a new app with 'nx g app' and use it just for component testing +`); + throw new Error( + 'The provided --build-target does not use an executor in the allow list of executors defined.' + ); + } const foundConfig = configuration || projectConfig?.targets?.[target]?.defaultConfiguration; diff --git a/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts b/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts index bb9feb126df1b..b788de479dc71 100644 --- a/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts +++ b/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts @@ -4,9 +4,14 @@ import { ProjectGraph, readJson, readProjectConfiguration, + readTargetOptions, Tree, + updateProjectConfiguration, } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { + createTreeWithEmptyV1Workspace, + createTreeWithEmptyWorkspace, +} from '@nrwl/devkit/testing'; import { Linter } from '@nrwl/linter'; import { applicationGenerator } from '../application/application'; import { componentGenerator } from '../component/component'; @@ -16,6 +21,7 @@ import { cypressComponentConfigGenerator } from './cypress-component-configurati let projectGraph: ProjectGraph; jest.mock('@nrwl/devkit', () => ({ ...jest.requireActual('@nrwl/devkit'), + readTargetOptions: jest.fn().mockImplementation(() => ({})), createProjectGraphAsync: jest .fn() .mockImplementation(async () => projectGraph), @@ -27,7 +33,7 @@ describe('React:CypressComponentTestConfiguration', () => { ReturnType > = assertMinimumCypressVersion as never; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); it('should generate cypress component test config with --build-target', async () => { mockedAssertCypressVersion.mockReturnValue(); @@ -271,4 +277,57 @@ describe('React:CypressComponentTestConfiguration', () => { tree.exists('libs/some-lib/src/lib/another-cmp/another-cmp.spec.cy.js') ).toBeFalsy(); }); + it('should throw error when an invalid --build-target is provided', async () => { + mockedAssertCypressVersion.mockReturnValue(); + await applicationGenerator(tree, { + e2eTestRunner: 'none', + linter: Linter.EsLint, + skipFormat: true, + style: 'scss', + unitTestRunner: 'none', + name: 'my-app', + }); + await libraryGenerator(tree, { + name: 'some-lib', + style: 'scss', + unitTestRunner: 'none', + linter: Linter.None, + skipFormat: false, + skipTsConfig: false, + }); + const appConfig = readProjectConfiguration(tree, 'my-app'); + appConfig.targets['build'].executor = 'something/else'; + updateProjectConfiguration(tree, 'my-app', appConfig); + projectGraph = { + nodes: { + 'my-app': { + name: 'my-app', + type: 'app', + data: { + ...appConfig, + }, + }, + 'some-lib': { + name: 'some-lib', + type: 'lib', + data: { + ...readProjectConfiguration(tree, 'some-lib'), + }, + }, + }, + dependencies: {}, + }; + await expect(async () => { + await cypressComponentConfigGenerator(tree, { + project: 'some-lib', + generateTests: true, + buildTarget: 'my-app:build', + }); + }).rejects.toThrowErrorMatchingInlineSnapshot(` + "Error trying to find build configuration. Try manually specifying the build target with the --build-target flag. + Provided project? some-lib + Provided build target? my-app:build + Provided Executors? @nrwl/webpack:webpack" + `); + }); }); diff --git a/packages/react/src/generators/cypress-component-configuration/lib/update-configs.ts b/packages/react/src/generators/cypress-component-configuration/lib/update-configs.ts index f1484aec62341..577158b4eff5d 100644 --- a/packages/react/src/generators/cypress-component-configuration/lib/update-configs.ts +++ b/packages/react/src/generators/cypress-component-configuration/lib/update-configs.ts @@ -19,7 +19,7 @@ export async function updateProjectConfig( validExecutorNames: new Set(['@nrwl/webpack:webpack']), }); - assetValidConfig(found.config); + assetValidConfig(found?.config); const projectConfig = readProjectConfiguration(tree, options.project); projectConfig.targets['component-test'].options = {