Skip to content

Commit f1db9ce

Browse files
barbados-clemensFrozenPandaz
authored andcommitted
fix(testing): provide better error messages around component test --build-target (#12886)
(cherry picked from commit 39518e3)
1 parent 39d197f commit f1db9ce

File tree

4 files changed

+135
-13
lines changed

4 files changed

+135
-13
lines changed

packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ProjectGraph,
66
readProjectConfiguration,
77
Tree,
8+
updateProjectConfiguration,
89
} from '@nrwl/devkit';
910
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
1011
import { applicationGenerator } from '../application/application';
@@ -158,21 +159,60 @@ describe('Cypress Component Testing Configuration', () => {
158159
});
159160
});
160161

161-
it('should throw if --build-target is invalid', async () => {
162+
it('should throw with invalid --build-target', async () => {
163+
await applicationGenerator(tree, {
164+
name: 'fancy-app',
165+
});
162166
await libraryGenerator(tree, {
163167
name: 'fancy-lib',
164168
});
165-
await expect(
166-
cypressComponentConfiguration(tree, {
169+
await componentGenerator(tree, {
170+
name: 'fancy-cmp',
171+
project: 'fancy-lib',
172+
export: true,
173+
});
174+
const appConfig = readProjectConfiguration(tree, 'fancy-app');
175+
appConfig.targets['build'].executor = 'something/else';
176+
updateProjectConfiguration(tree, 'fancy-app', appConfig);
177+
projectGraph = {
178+
nodes: {
179+
'fancy-app': {
180+
name: 'fancy-app',
181+
type: 'app',
182+
data: {
183+
...appConfig,
184+
},
185+
},
186+
'fancy-lib': {
187+
name: 'fancy-lib',
188+
type: 'lib',
189+
data: {
190+
...readProjectConfiguration(tree, 'fancy-lib'),
191+
},
192+
},
193+
},
194+
dependencies: {
195+
'fancy-app': [
196+
{
197+
type: DependencyType.static,
198+
source: 'fancy-app',
199+
target: 'fancy-lib',
200+
},
201+
],
202+
},
203+
};
204+
await expect(async () => {
205+
await cypressComponentConfiguration(tree, {
167206
project: 'fancy-lib',
168-
buildTarget: 'fancy-app:build:development',
207+
buildTarget: 'fancy-app:build',
169208
generateTests: false,
170-
})
171-
).rejects
172-
.toThrow(`Error trying to find build configuration. Try manually specifying the build target with the --build-target flag.
173-
Provided project? fancy-lib
174-
Provided build target? fancy-app:build:development
175-
Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular:browser`);
209+
});
210+
}).rejects.toThrowErrorMatchingInlineSnapshot(`
211+
"Error trying to find build configuration. Try manually specifying the build target with the --build-target flag.
212+
Provided project? fancy-lib
213+
Provided build target? fancy-app:build
214+
Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular:browser"
215+
`);
176216
});
177217
it('should use own project config', async () => {
178218
await applicationGenerator(tree, {
@@ -273,6 +313,7 @@ Provided Executors? @nrwl/angular:webpack-browser, @angular-devkit/build-angular
273313
});
274314
});
275315

316+
it('should throw if an invalid --build-target', async () => {});
276317
it('should work with simple components', async () => {
277318
await libraryGenerator(tree, {
278319
name: 'my-lib',

packages/cypress/src/utils/find-target-options.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export async function findBuildConfig(
5858
// attempt to find any projects with the valid config in the graph that consumes this project
5959
return await findInGraph(tree, graph, options);
6060
} catch (e) {
61+
logger.error(e);
6162
throw new Error(stripIndents`Error trying to find build configuration. Try manually specifying the build target with the --build-target flag.
6263
Provided project? ${options.project}
6364
Provided build target? ${options.buildTarget}
@@ -74,6 +75,27 @@ function findInTarget(
7475
options.buildTarget
7576
);
7677
const projectConfig = readProjectConfiguration(tree, project);
78+
const executorName = projectConfig?.targets?.[target]?.executor;
79+
if (!options.validExecutorNames.has(executorName)) {
80+
logger.error(stripIndents`NX The provided build target, ${
81+
options.buildTarget
82+
}, uses the '${executorName}' executor.
83+
But only the follow executors are allowed
84+
${Array.from(options.validExecutorNames)
85+
.map((ve) => ` - ${ve}`)
86+
.join('\n')}
87+
88+
This is most likely because the provided --build-target is not a build target for an application.
89+
For example, the provide build target, '${options.buildTarget}' is:
90+
- the build target for a buildable/publishable library instead of an app.
91+
- using a different framework than expected like react library using an angular app build target.
92+
93+
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
94+
`);
95+
throw new Error(
96+
'The provided --build-target does not use an executor in the allow list of executors defined.'
97+
);
98+
}
7799
const foundConfig =
78100
configuration || projectConfig?.targets?.[target]?.defaultConfiguration;
79101

packages/react/src/generators/cypress-component-configuration/cypress-component-configuration.spec.ts

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import {
44
ProjectGraph,
55
readJson,
66
readProjectConfiguration,
7+
readTargetOptions,
78
Tree,
9+
updateProjectConfiguration,
810
} from '@nrwl/devkit';
9-
import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing';
11+
import {
12+
createTreeWithEmptyV1Workspace,
13+
createTreeWithEmptyWorkspace,
14+
} from '@nrwl/devkit/testing';
1015
import { Linter } from '@nrwl/linter';
1116
import { applicationGenerator } from '../application/application';
1217
import { componentGenerator } from '../component/component';
@@ -16,6 +21,7 @@ import { cypressComponentConfigGenerator } from './cypress-component-configurati
1621
let projectGraph: ProjectGraph;
1722
jest.mock('@nrwl/devkit', () => ({
1823
...jest.requireActual<any>('@nrwl/devkit'),
24+
readTargetOptions: jest.fn().mockImplementation(() => ({})),
1925
createProjectGraphAsync: jest
2026
.fn()
2127
.mockImplementation(async () => projectGraph),
@@ -27,7 +33,7 @@ describe('React:CypressComponentTestConfiguration', () => {
2733
ReturnType<typeof assertMinimumCypressVersion>
2834
> = assertMinimumCypressVersion as never;
2935
beforeEach(() => {
30-
tree = createTreeWithEmptyV1Workspace();
36+
tree = createTreeWithEmptyWorkspace();
3137
});
3238
it('should generate cypress component test config with --build-target', async () => {
3339
mockedAssertCypressVersion.mockReturnValue();
@@ -271,4 +277,57 @@ describe('React:CypressComponentTestConfiguration', () => {
271277
tree.exists('libs/some-lib/src/lib/another-cmp/another-cmp.spec.cy.js')
272278
).toBeFalsy();
273279
});
280+
it('should throw error when an invalid --build-target is provided', async () => {
281+
mockedAssertCypressVersion.mockReturnValue();
282+
await applicationGenerator(tree, {
283+
e2eTestRunner: 'none',
284+
linter: Linter.EsLint,
285+
skipFormat: true,
286+
style: 'scss',
287+
unitTestRunner: 'none',
288+
name: 'my-app',
289+
});
290+
await libraryGenerator(tree, {
291+
name: 'some-lib',
292+
style: 'scss',
293+
unitTestRunner: 'none',
294+
linter: Linter.None,
295+
skipFormat: false,
296+
skipTsConfig: false,
297+
});
298+
const appConfig = readProjectConfiguration(tree, 'my-app');
299+
appConfig.targets['build'].executor = 'something/else';
300+
updateProjectConfiguration(tree, 'my-app', appConfig);
301+
projectGraph = {
302+
nodes: {
303+
'my-app': {
304+
name: 'my-app',
305+
type: 'app',
306+
data: {
307+
...appConfig,
308+
},
309+
},
310+
'some-lib': {
311+
name: 'some-lib',
312+
type: 'lib',
313+
data: {
314+
...readProjectConfiguration(tree, 'some-lib'),
315+
},
316+
},
317+
},
318+
dependencies: {},
319+
};
320+
await expect(async () => {
321+
await cypressComponentConfigGenerator(tree, {
322+
project: 'some-lib',
323+
generateTests: true,
324+
buildTarget: 'my-app:build',
325+
});
326+
}).rejects.toThrowErrorMatchingInlineSnapshot(`
327+
"Error trying to find build configuration. Try manually specifying the build target with the --build-target flag.
328+
Provided project? some-lib
329+
Provided build target? my-app:build
330+
Provided Executors? @nrwl/webpack:webpack"
331+
`);
332+
});
274333
});

packages/react/src/generators/cypress-component-configuration/lib/update-configs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export async function updateProjectConfig(
1919
validExecutorNames: new Set<string>(['@nrwl/webpack:webpack']),
2020
});
2121

22-
assetValidConfig(found.config);
22+
assetValidConfig(found?.config);
2323

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

0 commit comments

Comments
 (0)