Skip to content

Commit

Permalink
fix(testing): component testing generator should trust user to provid…
Browse files Browse the repository at this point in the history
…e valid build target (#17600)
  • Loading branch information
Coly010 authored Jun 15, 2023
1 parent f8ea4b6 commit a25d1fc
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
joinPathFragments,
ProjectGraph,
readProjectConfiguration,
stripIndents,
Tree,
updateProjectConfiguration,
} from '@nx/devkit';
Expand Down Expand Up @@ -40,6 +39,10 @@ describe('Cypress Component Testing Configuration', () => {
mockedInstalledCypressVersion.mockReturnValue(10);
});

afterEach(() => {
jest.clearAllMocks();
});

describe('updateProjectConfig', () => {
it('should add project config with --target=<project>:<target>', async () => {
await generateTestApplication(tree, {
Expand Down Expand Up @@ -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',
});
Expand Down Expand Up @@ -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, {
Expand Down Expand Up @@ -847,6 +849,7 @@ async function setup(
}
}
}

function getCmpsFromTree(
tree: Tree,
options: { basePath: string; name: string }
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -45,6 +48,7 @@ export async function cypressComponentConfiguration(
installTask();
};
}

async function addFiles(
tree: Tree,
projectConfig: ProjectConfiguration,
Expand Down Expand Up @@ -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<string>([
'@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<string>([
'@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 = {
Expand Down
2 changes: 1 addition & 1 deletion packages/cypress/src/utils/find-target-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface FindTargetOptions {
skipGetOptions?: boolean;
}

interface FoundTarget {
export interface FoundTarget {
config?: TargetConfiguration;
target: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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<string>([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(
Expand Down
30 changes: 15 additions & 15 deletions packages/react/src/utils/ct-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -27,16 +22,21 @@ export async function addCTTargetWithBuildTarget(
validExecutorNames: Set<string>;
}
): Promise<FoundTarget> {
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 = {
Expand Down

1 comment on commit a25d1fc

@vercel
Copy link

@vercel vercel bot commented on a25d1fc Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-nrwl.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx.dev

Please sign in to comment.