Skip to content

Commit

Permalink
fix(testing): provide better error messages around component test --b…
Browse files Browse the repository at this point in the history
…uild-target
  • Loading branch information
barbados-clemens committed Oct 28, 2022
1 parent 2cddd68 commit c96817f
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 13 deletions.
Expand Up @@ -5,6 +5,7 @@ import {
ProjectGraph,
readProjectConfiguration,
Tree,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { applicationGenerator } from '../application/application';
Expand Down Expand Up @@ -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');
delete appConfig.targets['build'];
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, {
Expand Down Expand Up @@ -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',
Expand Down
22 changes: 22 additions & 0 deletions packages/cypress/src/utils/find-target-options.ts
Expand Up @@ -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}
Expand All @@ -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;

Expand Down
Expand Up @@ -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';
Expand All @@ -16,6 +21,7 @@ import { cypressComponentConfigGenerator } from './cypress-component-configurati
let projectGraph: ProjectGraph;
jest.mock('@nrwl/devkit', () => ({
...jest.requireActual<any>('@nrwl/devkit'),
readTargetOptions: jest.fn().mockImplementation(() => ({})),
createProjectGraphAsync: jest
.fn()
.mockImplementation(async () => projectGraph),
Expand All @@ -27,7 +33,7 @@ describe('React:CypressComponentTestConfiguration', () => {
ReturnType<typeof assertMinimumCypressVersion>
> = assertMinimumCypressVersion as never;
beforeEach(() => {
tree = createTreeWithEmptyV1Workspace();
tree = createTreeWithEmptyWorkspace();
});
it('should generate cypress component test config with --build-target', async () => {
mockedAssertCypressVersion.mockReturnValue();
Expand Down Expand Up @@ -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');
delete appConfig.targets['build'];
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"
`);
});
});
Expand Up @@ -19,7 +19,7 @@ export async function updateProjectConfig(
validExecutorNames: new Set<string>(['@nrwl/webpack:webpack']),
});

assetValidConfig(found.config);
assetValidConfig(found?.config);

const projectConfig = readProjectConfiguration(tree, options.project);
projectConfig.targets['component-test'].options = {
Expand Down

0 comments on commit c96817f

Please sign in to comment.