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 0e49a753de..86960d8fc7 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 @@ -4,7 +4,6 @@ import { joinPathFragments, ProjectGraph, readProjectConfiguration, - stripIndents, Tree, updateProjectConfiguration, } from '@nx/devkit'; @@ -40,6 +39,10 @@ describe('Cypress Component Testing Configuration', () => { mockedInstalledCypressVersion.mockReturnValue(10); }); + afterEach(() => { + jest.clearAllMocks(); + }); + describe('updateProjectConfig', () => { it('should add project config with --target=:', async () => { await generateTestApplication(tree, { @@ -165,7 +168,7 @@ describe('Cypress Component Testing Configuration', () => { }); }); - it('should throw with invalid --build-target', async () => { + it('should not throw with invalid --build-target', async () => { await generateTestApplication(tree, { name: 'fancy-app', }); @@ -213,12 +216,11 @@ describe('Cypress Component Testing Configuration', () => { buildTarget: 'fancy-app:build', generateTests: false, }); - }).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? @nx/angular:webpack-browser, @nrwl/angular:webpack-browser, @angular-devkit/build-angular:browser" - `); + }).resolves; + + expect( + require('@nx/devkit').createProjectGraphAsync + ).not.toHaveBeenCalled(); }); it('should use own project config', async () => { await generateTestApplication(tree, { @@ -847,6 +849,7 @@ async function setup( } } } + function getCmpsFromTree( tree: Tree, options: { basePath: string; name: string } diff --git a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts index 0e71a95bbc..cf1afd3bf9 100644 --- a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts +++ b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts @@ -1,9 +1,12 @@ import { cypressComponentConfiguration as baseCyCTConfig } from '@nx/cypress'; import { - addMountDefinition, addDefaultCTConfig, + addMountDefinition, } from '@nx/cypress/src/utils/config'; -import { findBuildConfig } from '@nx/cypress/src/utils/find-target-options'; +import { + findBuildConfig, + FoundTarget, +} from '@nx/cypress/src/utils/find-target-options'; import { formatFiles, joinPathFragments, @@ -45,6 +48,7 @@ export async function cypressComponentConfiguration( installTask(); }; } + async function addFiles( tree: Tree, projectConfig: ProjectConfiguration, @@ -116,17 +120,21 @@ async function updateProjectConfig( tree: Tree, options: CypressComponentConfigSchema ) { - const found = await findBuildConfig(tree, { - project: options.project, - buildTarget: options.buildTarget, - validExecutorNames: new Set([ - '@nx/angular:webpack-browser', - '@nrwl/angular:webpack-browser', - '@angular-devkit/build-angular:browser', - ]), - }); + let found: FoundTarget = { target: options.buildTarget, config: undefined }; - assertValidConfig(found?.config); + if (!options.buildTarget) { + found = await findBuildConfig(tree, { + project: options.project, + buildTarget: options.buildTarget, + validExecutorNames: new Set([ + '@nx/angular:webpack-browser', + '@nrwl/angular:webpack-browser', + '@angular-devkit/build-angular:browser', + ]), + }); + + assertValidConfig(found?.config); + } const projectConfig = readProjectConfiguration(tree, options.project); projectConfig.targets['component-test'].options = { diff --git a/packages/cypress/src/utils/find-target-options.ts b/packages/cypress/src/utils/find-target-options.ts index 5dd8ca2476..2fe0a089f3 100644 --- a/packages/cypress/src/utils/find-target-options.ts +++ b/packages/cypress/src/utils/find-target-options.ts @@ -27,7 +27,7 @@ interface FindTargetOptions { skipGetOptions?: boolean; } -interface FoundTarget { +export interface FoundTarget { config?: TargetConfiguration; target: string; } 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 12f4da2197..56f69fed00 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 @@ -37,6 +37,10 @@ describe('React:CypressComponentTestConfiguration', () => { tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('should generate cypress config with vite', async () => { mockedAssertCypressVersion.mockReturnValue(); @@ -395,7 +399,8 @@ 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 () => { + + it('should not throw error when an invalid --build-target is provided', async () => { mockedAssertCypressVersion.mockReturnValue(); await applicationGenerator(tree, { e2eTestRunner: 'none', @@ -442,12 +447,10 @@ describe('React:CypressComponentTestConfiguration', () => { 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? @nx/webpack:webpack, @nx/vite:build, @nrwl/webpack:webpack, @nrwl/vite:build" - `); + }).resolves; + expect( + require('@nx/devkit').createProjectGraphAsync + ).not.toHaveBeenCalled(); }); it('should setup cypress config files correctly', async () => { diff --git a/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.ts b/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.ts index cb9eecaa09..dd2b75a552 100644 --- a/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.ts +++ b/packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.ts @@ -6,7 +6,7 @@ import { } from '@nx/devkit'; import { nxVersion } from '../../utils/versions'; import { addFiles } from './lib/add-files'; -import { FoundTarget, addCTTargetWithBuildTarget } from '../../utils/ct-utils'; +import { addCTTargetWithBuildTarget } from '../../utils/ct-utils'; import { CypressComponentConfigurationSchema } from './schema.d'; /** @@ -27,7 +27,7 @@ export async function cypressComponentConfigGenerator( skipFormat: true, }); - const found: FoundTarget = await addCTTargetWithBuildTarget(tree, { + const found = await addCTTargetWithBuildTarget(tree, { project: options.project, buildTarget: options.buildTarget, validExecutorNames: new Set([ diff --git a/packages/react/src/generators/cypress-component-configuration/lib/add-files.ts b/packages/react/src/generators/cypress-component-configuration/lib/add-files.ts index b226a2bd6a..5ae0c0f827 100644 --- a/packages/react/src/generators/cypress-component-configuration/lib/add-files.ts +++ b/packages/react/src/generators/cypress-component-configuration/lib/add-files.ts @@ -9,11 +9,8 @@ import { import { nxVersion } from 'nx/src/utils/versions'; import { componentTestGenerator } from '../../component-test/component-test'; import type { CypressComponentConfigurationSchema } from '../schema'; -import { - FoundTarget, - getBundlerFromTarget, - isComponent, -} from '../../../utils/ct-utils'; +import { getBundlerFromTarget, isComponent } from '../../../utils/ct-utils'; +import { FoundTarget } from '@nx/cypress/src/utils/find-target-options'; export async function addFiles( tree: Tree, @@ -26,7 +23,12 @@ export async function addFiles( const { addMountDefinition, addDefaultCTConfig } = await import( '@nx/cypress/src/utils/config' ); - const actualBundler = await getBundlerFromTarget(found, tree); + + // Specifically undefined to allow Remix workaround of passing an empty string + const actualBundler = + options.buildTarget !== undefined && options.bundler + ? options.bundler + : await getBundlerFromTarget(found, tree); if (options.bundler && options.bundler !== actualBundler) { logger.warn( diff --git a/packages/react/src/utils/ct-utils.ts b/packages/react/src/utils/ct-utils.ts index 34387a57b6..6c244a5da2 100644 --- a/packages/react/src/utils/ct-utils.ts +++ b/packages/react/src/utils/ct-utils.ts @@ -2,23 +2,18 @@ import { createProjectGraphAsync, parseTargetString, readProjectConfiguration, - TargetConfiguration, Tree, updateProjectConfiguration, } from '@nx/devkit'; import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript'; import { getComponentNode } from './ast-utils'; +import { type FoundTarget } from '@nx/cypress/src/utils/find-target-options'; let tsModule: typeof import('typescript'); const allowedFileExt = new RegExp(/\.[jt]sx?/); const isSpecFile = new RegExp(/(spec|test)\./); -export interface FoundTarget { - config?: TargetConfiguration; - target: string; -} - export async function addCTTargetWithBuildTarget( tree: Tree, options: { @@ -27,16 +22,21 @@ export async function addCTTargetWithBuildTarget( validExecutorNames: Set; } ): Promise { - const { findBuildConfig } = await import( - '@nx/cypress/src/utils/find-target-options' - ); - const found = await findBuildConfig(tree, { - project: options.project, - buildTarget: options.buildTarget, - validExecutorNames: options.validExecutorNames, - }); + let found: FoundTarget = { target: options.buildTarget, config: undefined }; - assertValidConfig(found?.config); + // Specifically undefined as a workaround for Remix to pass an empty string as the buildTarget + if (options.buildTarget === undefined) { + const { findBuildConfig } = await import( + '@nx/cypress/src/utils/find-target-options' + ); + found = await findBuildConfig(tree, { + project: options.project, + buildTarget: options.buildTarget, + validExecutorNames: options.validExecutorNames, + }); + + assertValidConfig(found?.config); + } const projectConfig = readProjectConfiguration(tree, options.project); projectConfig.targets['component-test'].options = {