Skip to content

Commit b892d66

Browse files
Coly010FrozenPandaz
authored andcommitted
fix(testing): application generators should accurately configure e2e projects (#27453)
- feat(devkit): add util for determining the e2e web server info - feat(vite): add util for determining the e2e web server info - feat(webpack): add util for determining the e2e web server info - fix(webpack): allow port override - fix(devkit): e2e web server info util should handle target defaults - feat(webpack): export the e2e web server info utils - fix(vite): rename util - fix(devkit): util should determine the devTarget for cypress - fix(react): improve accuracy of e2e project generation <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> The logic for finding the correct targets and web addresses to use when setting up e2e projects is flawed and missing some key considerations. ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> The logic is accurate and usage is simplified across plugins Projects: - [x] Angular - [x] Expo - [x] Next - [x] Nuxt - [x] Vue - [x] Web - [x] Remix - [x] React - [x] React Native ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # (cherry picked from commit 320d9f2)
1 parent 7ee3071 commit b892d66

File tree

40 files changed

+1220
-454
lines changed

40 files changed

+1220
-454
lines changed

docs/generated/packages/expo/generators/application.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"description": "Adds the specified e2e test runner",
7777
"type": "string",
7878
"enum": ["playwright", "cypress", "detox", "none"],
79-
"default": "playwright"
79+
"default": "none"
8080
},
8181
"standaloneConfig": {
8282
"description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside `workspace.json`.",

e2e/web/src/file-server-legacy.test.ts

-8
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ describe('file-server', () => {
3535
},
3636
}
3737
);
38-
runCLI(
39-
`generate @nx/web:static-config --buildTarget=${ngAppName}:build --outputPath=dist/apps/${ngAppName}/browser --no-interactive`,
40-
{
41-
env: {
42-
NX_ADD_PLUGINS: 'false',
43-
},
44-
}
45-
);
4638
runCLI(
4739
`generate @nx/web:static-config --buildTarget=${reactAppName}:build --targetName=custom-serve-static --no-interactive`,
4840
{

packages/angular/src/generators/application/lib/add-e2e.ts

+53-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Tree } from '@nx/devkit';
1+
import { Tree } from '@nx/devkit';
22
import {
33
addDependenciesToPackageJson,
44
addProjectConfiguration,
@@ -13,6 +13,7 @@ import { nxVersion } from '../../../utils/versions';
1313
import { getInstalledAngularVersionInfo } from '../../utils/version-utils';
1414
import type { NormalizedSchema } from './normalized-schema';
1515
import { addE2eCiTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
16+
import { E2EWebServerDetails } from '@nx/devkit/src/generators/e2e-web-server-info-utils';
1617

1718
export async function addE2e(tree: Tree, options: NormalizedSchema) {
1819
// since e2e are separate projects, default to adding plugins
@@ -21,12 +22,19 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
2122
process.env.NX_ADD_PLUGINS !== 'false' &&
2223
nxJson.useInferencePlugins !== false;
2324

25+
const e2eWebServerInfo = getAngularE2EWebServerInfo(
26+
tree,
27+
options.name,
28+
options.port
29+
);
30+
// TODO: This can call `@nx/web:static-config` generator when ready
31+
addFileServerTarget(tree, options, 'serve-static', e2eWebServerInfo.e2ePort);
32+
2433
if (options.e2eTestRunner === 'cypress') {
2534
const { configurationGenerator } = ensurePackage<
2635
typeof import('@nx/cypress')
2736
>('@nx/cypress', nxVersion);
28-
// TODO: This can call `@nx/web:static-config` generator when ready
29-
addFileServerTarget(tree, options, 'serve-static');
37+
3038
addProjectConfiguration(tree, options.e2eProjectName, {
3139
projectType: 'application',
3240
root: options.e2eProjectRoot,
@@ -41,8 +49,14 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
4149
linter: options.linter,
4250
skipPackageJson: options.skipPackageJson,
4351
skipFormat: true,
44-
devServerTarget: `${options.name}:${options.e2eWebServerTarget}:development`,
45-
baseUrl: options.e2eWebServerAddress,
52+
devServerTarget: e2eWebServerInfo.e2eDevServerTarget,
53+
baseUrl: e2eWebServerInfo.e2eWebServerAddress,
54+
webServerCommands: {
55+
default: e2eWebServerInfo.e2eWebServerCommand,
56+
production: e2eWebServerInfo.e2eCiWebServerCommand,
57+
},
58+
ciWebServerCommand: e2eWebServerInfo.e2eCiWebServerCommand,
59+
ciBaseUrl: e2eWebServerInfo.e2eCiBaseUrl,
4660
rootProject: options.rootProject,
4761
addPlugin,
4862
});
@@ -73,10 +87,8 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
7387
js: false,
7488
linter: options.linter,
7589
setParserOptionsProject: options.setParserOptionsProject,
76-
webServerCommand: `${getPackageManagerCommand().exec} nx ${
77-
options.e2eWebServerTarget
78-
} ${options.name}`,
79-
webServerAddress: options.e2eWebServerAddress,
90+
webServerCommand: e2eWebServerInfo.e2eWebServerCommand,
91+
webServerAddress: e2eWebServerInfo.e2eWebServerAddress,
8092
rootProject: options.rootProject,
8193
addPlugin,
8294
});
@@ -94,7 +106,8 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
94106
function addFileServerTarget(
95107
tree: Tree,
96108
options: NormalizedSchema,
97-
targetName: string
109+
targetName: string,
110+
e2ePort: number
98111
) {
99112
if (!options.skipPackageJson) {
100113
addDependenciesToPackageJson(tree, {}, { '@nx/web': nxVersion });
@@ -109,7 +122,7 @@ function addFileServerTarget(
109122
executor: '@nx/web:file-server',
110123
options: {
111124
buildTarget: `${options.name}:build`,
112-
port: options.e2ePort,
125+
port: e2ePort,
113126
staticFilePath: isUsingApplicationBuilder
114127
? joinPathFragments(options.outputPath, 'browser')
115128
: undefined,
@@ -118,3 +131,32 @@ function addFileServerTarget(
118131
};
119132
updateProjectConfiguration(tree, options.name, projectConfig);
120133
}
134+
135+
function getAngularE2EWebServerInfo(
136+
tree: Tree,
137+
projectName: string,
138+
portOverride: number
139+
): E2EWebServerDetails & { e2ePort: number } {
140+
const nxJson = readNxJson(tree);
141+
let e2ePort = portOverride ?? 4200;
142+
143+
if (
144+
nxJson.targetDefaults?.['serve'] &&
145+
(nxJson.targetDefaults?.['serve'].options?.port ||
146+
nxJson.targetDefaults?.['serve'].options?.env?.PORT)
147+
) {
148+
e2ePort =
149+
nxJson.targetDefaults?.['serve'].options?.port ||
150+
nxJson.targetDefaults?.['serve'].options?.env?.PORT;
151+
}
152+
153+
const pm = getPackageManagerCommand();
154+
return {
155+
e2eCiBaseUrl: 'http://localhost:4200',
156+
e2eCiWebServerCommand: `${pm.exec} nx run ${projectName}:serve-static`,
157+
e2eWebServerCommand: `${pm.exec} nx run ${projectName}:serve`,
158+
e2eWebServerAddress: `http://localhost:${e2ePort}`,
159+
e2eDevServerTarget: `${projectName}:serve`,
160+
e2ePort,
161+
};
162+
}

packages/angular/src/generators/application/lib/normalize-options.ts

-15
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,9 @@ export async function normalizeOptions(
2626
options.projectNameAndRootFormat = projectNameAndRootFormat;
2727

2828
const nxJson = readNxJson(host);
29-
let e2eWebServerTarget = 'serve';
30-
let e2ePort = options.port ?? 4200;
31-
if (
32-
nxJson.targetDefaults?.[e2eWebServerTarget] &&
33-
(nxJson.targetDefaults?.[e2eWebServerTarget].options?.port ||
34-
nxJson.targetDefaults?.[e2eWebServerTarget].options?.env?.PORT)
35-
) {
36-
e2ePort =
37-
nxJson.targetDefaults?.[e2eWebServerTarget].options?.port ||
38-
nxJson.targetDefaults?.[e2eWebServerTarget].options?.env?.PORT;
39-
}
4029

4130
const e2eProjectName = options.rootProject ? 'e2e' : `${appProjectName}-e2e`;
4231
const e2eProjectRoot = options.rootProject ? 'e2e' : `${appProjectRoot}-e2e`;
43-
const e2eWebServerAddress = `http://localhost:${e2ePort}`;
4432

4533
const parsedTags = options.tags
4634
? options.tags.split(',').map((s) => s.trim())
@@ -72,9 +60,6 @@ export async function normalizeOptions(
7260
appProjectSourceRoot: `${appProjectRoot}/src`,
7361
e2eProjectRoot,
7462
e2eProjectName,
75-
e2eWebServerAddress,
76-
e2eWebServerTarget,
77-
e2ePort,
7863
parsedTags,
7964
bundler,
8065
outputPath: joinPathFragments(

packages/angular/src/generators/application/lib/normalized-schema.ts

-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ export interface NormalizedSchema extends Schema {
1212
appProjectSourceRoot: string;
1313
e2eProjectName: string;
1414
e2eProjectRoot: string;
15-
e2eWebServerAddress: string;
16-
e2eWebServerTarget: string;
17-
e2ePort: number;
1815
parsedTags: string[];
1916
outputPath: string;
2017
}

0 commit comments

Comments
 (0)