@nx/cypress 17.2.0-beta.1 → 17.2.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/migrations.json +9 -10
- package/package.json +5 -5
- package/plugins/cypress-preset.d.ts +14 -2
- package/plugins/cypress-preset.js +72 -22
- package/src/executors/cypress/cypress.impl.js +0 -3
- package/src/generators/configuration/configuration.js +15 -15
- package/src/plugins/plugin.js +40 -46
- package/src/utils/add-linter.js +0 -3
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
- package/src/migrations/update-17-2-0/add-dev-server-targets-to-cypress-configs.d.ts +0 -2
- package/src/migrations/update-17-2-0/add-dev-server-targets-to-cypress-configs.js +0 -125
- package/src/migrations/update-17-2-0/add-nx-cypress-plugin.d.ts +0 -2
- package/src/migrations/update-17-2-0/add-nx-cypress-plugin.js +0 -16
package/migrations.json
CHANGED
|
@@ -47,16 +47,6 @@
|
|
|
47
47
|
"version": "16.8.0-beta.4",
|
|
48
48
|
"description": "Update to Cypress v13. Most noteable change is video recording is off by default. This migration will only update if the workspace is already on Cypress v12. https://docs.cypress.io/guides/references/migration-guide#Migrating-to-Cypress-130",
|
|
49
49
|
"implementation": "./src/migrations/update-16-8-0/cypress-13"
|
|
50
|
-
},
|
|
51
|
-
"add-nx-metadata": {
|
|
52
|
-
"version": "17.2.0-beta.0",
|
|
53
|
-
"description": "Add devServerTargets into cypress.config.ts files for @nx/cypress/plugin",
|
|
54
|
-
"implementation": "./src/migrations/update-17-2-0/add-dev-server-targets-to-cypress-configs"
|
|
55
|
-
},
|
|
56
|
-
"add-nx-cypress-plugin": {
|
|
57
|
-
"version": "17.2.0-beta.0",
|
|
58
|
-
"description": "Add the @nx/cypress/plugin to nx.json plugins",
|
|
59
|
-
"implementation": "./src/migrations/update-17-2-0/add-nx-cypress-plugin"
|
|
60
50
|
}
|
|
61
51
|
},
|
|
62
52
|
"packageJsonUpdates": {
|
|
@@ -92,6 +82,15 @@
|
|
|
92
82
|
"alwaysAddToPackageJson": false
|
|
93
83
|
}
|
|
94
84
|
}
|
|
85
|
+
},
|
|
86
|
+
"17.2.0-beta.2": {
|
|
87
|
+
"version": "17.2.0-beta.2",
|
|
88
|
+
"packages": {
|
|
89
|
+
"vite": {
|
|
90
|
+
"version": "^5.0.0",
|
|
91
|
+
"alwaysAddToPackageJson": false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/cypress",
|
|
3
|
-
"version": "17.2.0-beta.
|
|
3
|
+
"version": "17.2.0-beta.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Cypress contains executors and generators allowing your workspace to use the powerful Cypress integration testing capabilities.",
|
|
6
6
|
"repository": {
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"migrations": "./migrations.json"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@nx/devkit": "17.2.0-beta.
|
|
38
|
-
"@nx/eslint": "17.2.0-beta.
|
|
39
|
-
"@nx/js": "17.2.0-beta.
|
|
37
|
+
"@nx/devkit": "17.2.0-beta.11",
|
|
38
|
+
"@nx/eslint": "17.2.0-beta.11",
|
|
39
|
+
"@nx/js": "17.2.0-beta.11",
|
|
40
40
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
41
41
|
"detect-port": "^1.5.1",
|
|
42
42
|
"semver": "7.5.3",
|
|
43
43
|
"tslib": "^2.3.0",
|
|
44
|
-
"@nrwl/cypress": "17.2.0-beta.
|
|
44
|
+
"@nrwl/cypress": "17.2.0-beta.11"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"cypress": ">= 3 < 14"
|
|
@@ -32,6 +32,17 @@ export declare function nxBaseCypressPreset(pathToConfig: string, options?: {
|
|
|
32
32
|
*
|
|
33
33
|
*/
|
|
34
34
|
export declare function nxE2EPreset(pathToConfig: string, options?: NxCypressE2EPresetOptions): any;
|
|
35
|
+
export interface WebServerConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Timeout to wait for the webserver to start listening
|
|
38
|
+
*/
|
|
39
|
+
timeout?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Reuse an existing web server if it exists
|
|
42
|
+
* If this is false, an error will be thrown if the server is already running
|
|
43
|
+
*/
|
|
44
|
+
reuseExistingServer?: boolean;
|
|
45
|
+
}
|
|
35
46
|
export type NxCypressE2EPresetOptions = {
|
|
36
47
|
bundler?: string;
|
|
37
48
|
/**
|
|
@@ -40,7 +51,8 @@ export type NxCypressE2EPresetOptions = {
|
|
|
40
51
|
* default is 'src'
|
|
41
52
|
**/
|
|
42
53
|
cypressDir?: string;
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
webServerCommands?: Record<string, string>;
|
|
55
|
+
ciWebServerCommand?: string;
|
|
56
|
+
webServerConfig?: WebServerConfig;
|
|
45
57
|
};
|
|
46
58
|
export {};
|
|
@@ -5,8 +5,9 @@ const devkit_1 = require("@nx/devkit");
|
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const fs_1 = require("fs");
|
|
7
7
|
const preprocessor_vite_1 = require("../src/plugins/preprocessor-vite");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const http_1 = require("http");
|
|
10
|
+
const https_1 = require("https");
|
|
10
11
|
function nxBaseCypressPreset(pathToConfig, options) {
|
|
11
12
|
// used to set babel settings for react CT.
|
|
12
13
|
process.env.NX_CYPRESS_COMPONENT_TEST =
|
|
@@ -27,6 +28,16 @@ function nxBaseCypressPreset(pathToConfig, options) {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
exports.nxBaseCypressPreset = nxBaseCypressPreset;
|
|
31
|
+
function startWebServer(webServerCommand) {
|
|
32
|
+
const serverProcess = (0, child_process_1.exec)(webServerCommand, {
|
|
33
|
+
cwd: devkit_1.workspaceRoot,
|
|
34
|
+
});
|
|
35
|
+
serverProcess.stdout.pipe(process.stdout);
|
|
36
|
+
serverProcess.stderr.pipe(process.stderr);
|
|
37
|
+
return () => {
|
|
38
|
+
serverProcess.kill();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
30
41
|
/**
|
|
31
42
|
* nx E2E Preset for Cypress
|
|
32
43
|
* @description
|
|
@@ -51,40 +62,79 @@ function nxE2EPreset(pathToConfig, options) {
|
|
|
51
62
|
specPattern: `${basePath}/**/*.cy.{js,jsx,ts,tsx}`,
|
|
52
63
|
fixturesFolder: `${basePath}/fixtures`,
|
|
53
64
|
env: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
webServerCommand: options?.webServerCommands?.default,
|
|
66
|
+
webServerCommands: options?.webServerCommands,
|
|
67
|
+
ciWebServerCommand: options?.ciWebServerCommand,
|
|
57
68
|
},
|
|
58
69
|
async setupNodeEvents(on, config) {
|
|
59
70
|
if (options?.bundler === 'vite') {
|
|
60
71
|
on('file:preprocessor', (0, preprocessor_vite_1.default)());
|
|
61
72
|
}
|
|
62
|
-
if (!config.env.
|
|
73
|
+
if (!config.env.webServerCommands) {
|
|
63
74
|
return;
|
|
64
75
|
}
|
|
65
|
-
const
|
|
66
|
-
if (!
|
|
76
|
+
const webServerCommand = config.env.webServerCommand;
|
|
77
|
+
if (!webServerCommand) {
|
|
67
78
|
return;
|
|
68
79
|
}
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
if (config.baseUrl && webServerCommand) {
|
|
81
|
+
if (await isServerUp(config.baseUrl)) {
|
|
82
|
+
if (options?.webServerConfig?.reuseExistingServer === undefined
|
|
83
|
+
? true
|
|
84
|
+
: options.webServerConfig.reuseExistingServer) {
|
|
85
|
+
console.log(`Reusing the server already running on ${config.baseUrl}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
throw new Error(`Web server is already running at ${config.baseUrl}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const killWebServer = startWebServer(webServerCommand);
|
|
77
93
|
on('after:run', () => {
|
|
78
|
-
|
|
94
|
+
killWebServer();
|
|
79
95
|
});
|
|
80
|
-
|
|
81
|
-
if (!devServerValue) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
return { ...config, baseUrl: devServerValue.baseUrl };
|
|
96
|
+
await waitForServer(config.baseUrl, options.webServerConfig);
|
|
85
97
|
}
|
|
86
98
|
},
|
|
87
99
|
};
|
|
88
100
|
return baseConfig;
|
|
89
101
|
}
|
|
90
102
|
exports.nxE2EPreset = nxE2EPreset;
|
|
103
|
+
function waitForServer(url, webServerConfig) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
let pollTimeout;
|
|
106
|
+
const { protocol } = new URL(url);
|
|
107
|
+
const timeoutDuration = webServerConfig?.timeout ?? 5 * 1000;
|
|
108
|
+
const timeout = setTimeout(() => {
|
|
109
|
+
clearTimeout(pollTimeout);
|
|
110
|
+
reject(new Error(`Web server failed to start in ${timeoutDuration}ms. This can be configured in cypress.config.ts.`));
|
|
111
|
+
}, timeoutDuration);
|
|
112
|
+
const makeRequest = protocol === 'https:' ? https_1.request : http_1.request;
|
|
113
|
+
function pollForServer() {
|
|
114
|
+
const request = makeRequest(url, () => {
|
|
115
|
+
clearTimeout(timeout);
|
|
116
|
+
resolve();
|
|
117
|
+
});
|
|
118
|
+
request.on('error', () => {
|
|
119
|
+
pollTimeout = setTimeout(pollForServer, 100);
|
|
120
|
+
});
|
|
121
|
+
// Don't forget to end the request
|
|
122
|
+
request.end();
|
|
123
|
+
}
|
|
124
|
+
pollForServer();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function isServerUp(url) {
|
|
128
|
+
const { protocol } = new URL(url);
|
|
129
|
+
const makeRequest = protocol === 'https:' ? https_1.request : http_1.request;
|
|
130
|
+
return new Promise((resolve) => {
|
|
131
|
+
const request = makeRequest(url, () => {
|
|
132
|
+
resolve(true);
|
|
133
|
+
});
|
|
134
|
+
request.on('error', () => {
|
|
135
|
+
resolve(false);
|
|
136
|
+
});
|
|
137
|
+
// Don't forget to end the request
|
|
138
|
+
request.end();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
@@ -95,28 +95,28 @@ async function addFiles(tree, options, projectGraph, hasPlugin) {
|
|
|
95
95
|
jsx: options.jsx,
|
|
96
96
|
});
|
|
97
97
|
const cyFile = (0, devkit_1.joinPathFragments)(projectConfig.root, 'cypress.config.ts');
|
|
98
|
-
let
|
|
98
|
+
let webServerCommands;
|
|
99
99
|
let ciDevServerTarget;
|
|
100
|
-
if (hasPlugin &&
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
if (hasPlugin && options.devServerTarget) {
|
|
101
|
+
webServerCommands = {};
|
|
102
|
+
webServerCommands.default = 'nx run ' + options.devServerTarget;
|
|
103
103
|
const parsedTarget = (0, devkit_1.parseTargetString)(options.devServerTarget, projectGraph);
|
|
104
104
|
const devServerProjectConfig = (0, devkit_1.readProjectConfiguration)(tree, parsedTarget.project);
|
|
105
105
|
// Add production e2e target if serve target is found
|
|
106
106
|
if (parsedTarget.configuration !== 'production' &&
|
|
107
107
|
devServerProjectConfig.targets[parsedTarget.target]?.configurations?.['production']) {
|
|
108
|
-
|
|
108
|
+
webServerCommands.production = `nx run ${parsedTarget.project}:${parsedTarget.target}:production`;
|
|
109
109
|
}
|
|
110
110
|
// Add ci/static e2e target if serve target is found
|
|
111
111
|
if (devServerProjectConfig.targets?.['serve-static']) {
|
|
112
|
-
ciDevServerTarget =
|
|
112
|
+
ciDevServerTarget = `nx run ${parsedTarget.project}:serve-static`;
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
const updatedCyConfig = await (0, config_1.addDefaultE2EConfig)(tree.read(cyFile, 'utf-8'), {
|
|
116
116
|
cypressDir: options.directory,
|
|
117
117
|
bundler: options.bundler === 'vite' ? 'vite' : undefined,
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
webServerCommands,
|
|
119
|
+
ciWebServerCommand: ciDevServerTarget,
|
|
120
120
|
}, options.baseUrl);
|
|
121
121
|
tree.write(cyFile, updatedCyConfig);
|
|
122
122
|
}
|
|
@@ -148,13 +148,7 @@ function addTarget(tree, opts) {
|
|
|
148
148
|
testingType: 'e2e',
|
|
149
149
|
},
|
|
150
150
|
};
|
|
151
|
-
if (opts.
|
|
152
|
-
projectConfig.targets.e2e.options = {
|
|
153
|
-
...projectConfig.targets.e2e.options,
|
|
154
|
-
baseUrl: opts.baseUrl,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
else if (opts.devServerTarget) {
|
|
151
|
+
if (opts.devServerTarget) {
|
|
158
152
|
const parsedTarget = (0, devkit_1.parseTargetString)(opts.devServerTarget);
|
|
159
153
|
projectConfig.targets.e2e.options = {
|
|
160
154
|
...projectConfig.targets.e2e.options,
|
|
@@ -178,6 +172,12 @@ function addTarget(tree, opts) {
|
|
|
178
172
|
};
|
|
179
173
|
}
|
|
180
174
|
}
|
|
175
|
+
else if (opts.baseUrl) {
|
|
176
|
+
projectConfig.targets.e2e.options = {
|
|
177
|
+
...projectConfig.targets.e2e.options,
|
|
178
|
+
baseUrl: opts.baseUrl,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
181
|
(0, devkit_1.updateProjectConfiguration)(tree, opts.project, projectConfig);
|
|
182
182
|
}
|
|
183
183
|
exports.default = configurationGenerator;
|
package/src/plugins/plugin.js
CHANGED
|
@@ -36,7 +36,9 @@ exports.createNodes = [
|
|
|
36
36
|
!siblingFiles.includes('project.json')) {
|
|
37
37
|
return {};
|
|
38
38
|
}
|
|
39
|
-
const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context
|
|
39
|
+
const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [
|
|
40
|
+
(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)),
|
|
41
|
+
]);
|
|
40
42
|
const targets = targetsCache[hash]
|
|
41
43
|
? targetsCache[hash]
|
|
42
44
|
: buildCypressTargets(configFilePath, projectRoot, options, context);
|
|
@@ -61,7 +63,7 @@ function getOutputs(projectRoot, cypressConfig, testingType) {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
const { screenshotsFolder, videosFolder, e2e, component } = cypressConfig;
|
|
64
|
-
const outputs = [
|
|
66
|
+
const outputs = [];
|
|
65
67
|
if (videosFolder) {
|
|
66
68
|
outputs.push(getOutput(videosFolder));
|
|
67
69
|
}
|
|
@@ -92,55 +94,44 @@ function getOutputs(projectRoot, cypressConfig, testingType) {
|
|
|
92
94
|
}
|
|
93
95
|
function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
94
96
|
const cypressConfig = getCypressConfig(configFilePath, context);
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
options: {
|
|
99
|
-
cypressConfig: configFilePath,
|
|
100
|
-
},
|
|
97
|
+
const cypressEnv = {
|
|
98
|
+
...cypressConfig.env,
|
|
99
|
+
...cypressConfig.e2e?.env,
|
|
101
100
|
};
|
|
101
|
+
const webServerCommands = cypressEnv?.webServerCommands;
|
|
102
|
+
const relativeConfigPath = (0, path_1.relative)(projectRoot, configFilePath);
|
|
103
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
102
104
|
const targets = {};
|
|
103
105
|
if ('e2e' in cypressConfig) {
|
|
104
|
-
const e2eTargetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.targetName, context.nxJsonConfiguration.targetDefaults, '@nx/cypress:cypress');
|
|
105
106
|
targets[options.targetName] = {
|
|
106
|
-
|
|
107
|
+
command: `cypress run --config-file ${relativeConfigPath} --e2e`,
|
|
107
108
|
options: {
|
|
108
|
-
|
|
109
|
-
testingType: 'e2e',
|
|
109
|
+
cwd: projectRoot,
|
|
110
110
|
},
|
|
111
111
|
};
|
|
112
|
+
const e2eTargetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.targetName, context.nxJsonConfiguration.targetDefaults, 'run-commands');
|
|
112
113
|
if (e2eTargetDefaults?.cache === undefined) {
|
|
113
114
|
targets[options.targetName].cache = true;
|
|
114
115
|
}
|
|
115
116
|
if (e2eTargetDefaults?.inputs === undefined) {
|
|
116
|
-
targets[options.targetName].inputs =
|
|
117
|
-
'production' in namedInputs
|
|
118
|
-
? ['default', '^production']
|
|
119
|
-
: ['default', '^default'];
|
|
117
|
+
targets[options.targetName].inputs = getInputs(namedInputs);
|
|
120
118
|
}
|
|
121
119
|
if (e2eTargetDefaults?.outputs === undefined) {
|
|
122
120
|
targets[options.targetName].outputs = getOutputs(projectRoot, cypressConfig, 'e2e');
|
|
123
121
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
...cypressConfig.e2e?.env,
|
|
127
|
-
};
|
|
128
|
-
const devServerTargets = cypressEnv?.devServerTargets;
|
|
129
|
-
if (devServerTargets?.default) {
|
|
130
|
-
targets[options.targetName].options.devServerTarget =
|
|
131
|
-
devServerTargets.default;
|
|
132
|
-
delete devServerTargets.default;
|
|
122
|
+
if (webServerCommands?.default) {
|
|
123
|
+
delete webServerCommands.default;
|
|
133
124
|
}
|
|
134
|
-
if (Object.keys(
|
|
125
|
+
if (Object.keys(webServerCommands ?? {}).length > 0) {
|
|
135
126
|
targets[options.targetName].configurations ??= {};
|
|
136
|
-
for (const [configuration,
|
|
127
|
+
for (const [configuration, webServerCommand] of Object.entries(webServerCommands ?? {})) {
|
|
137
128
|
targets[options.targetName].configurations[configuration] = {
|
|
138
|
-
|
|
129
|
+
command: `cypress run --config-file ${relativeConfigPath} --e2e --env webServerCommand="${webServerCommand}"`,
|
|
139
130
|
};
|
|
140
131
|
}
|
|
141
132
|
}
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
133
|
+
const ciWebServerCommand = cypressEnv?.ciWebServerCommand;
|
|
134
|
+
if (ciWebServerCommand) {
|
|
144
135
|
const specPatterns = Array.isArray(cypressConfig.e2e.specPattern)
|
|
145
136
|
? cypressConfig.e2e.specPattern.map((p) => (0, path_1.join)(projectRoot, p))
|
|
146
137
|
: [(0, path_1.join)(projectRoot, cypressConfig.e2e.specPattern)];
|
|
@@ -153,21 +144,17 @@ function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
|
153
144
|
const specFiles = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, specPatterns, excludeSpecPatterns);
|
|
154
145
|
const dependsOn = [];
|
|
155
146
|
const outputs = getOutputs(projectRoot, cypressConfig, 'e2e');
|
|
156
|
-
const inputs =
|
|
157
|
-
? ['default', '^production']
|
|
158
|
-
: ['default', '^default'];
|
|
147
|
+
const inputs = getInputs(namedInputs);
|
|
159
148
|
for (const file of specFiles) {
|
|
160
|
-
const
|
|
149
|
+
const relativeSpecFilePath = (0, path_1.relative)(projectRoot, file);
|
|
150
|
+
const targetName = options.ciTargetName + '--' + relativeSpecFilePath;
|
|
161
151
|
targets[targetName] = {
|
|
162
|
-
...targets[options.targetName],
|
|
163
152
|
outputs,
|
|
164
153
|
inputs,
|
|
165
154
|
cache: true,
|
|
166
|
-
|
|
155
|
+
command: `cypress run --config-file ${relativeConfigPath} --e2e --env webServerCommand="${ciWebServerCommand}" --spec ${relativeSpecFilePath}`,
|
|
167
156
|
options: {
|
|
168
|
-
|
|
169
|
-
devServerTarget: ciDevServerTarget,
|
|
170
|
-
spec: file,
|
|
157
|
+
cwd: projectRoot,
|
|
171
158
|
},
|
|
172
159
|
};
|
|
173
160
|
dependsOn.push({
|
|
@@ -187,13 +174,12 @@ function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
|
187
174
|
}
|
|
188
175
|
}
|
|
189
176
|
if ('component' in cypressConfig) {
|
|
190
|
-
const componentTestingTargetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.componentTestingTargetName, context.nxJsonConfiguration.targetDefaults, '
|
|
177
|
+
const componentTestingTargetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.componentTestingTargetName, context.nxJsonConfiguration.targetDefaults, 'nx:run-commands');
|
|
191
178
|
// This will not override the e2e target if it is the same
|
|
192
179
|
targets[options.componentTestingTargetName] ??= {
|
|
193
|
-
|
|
180
|
+
command: `cypress open --config-file ${relativeConfigPath} --component`,
|
|
194
181
|
options: {
|
|
195
|
-
|
|
196
|
-
testingType: 'component',
|
|
182
|
+
cwd: projectRoot,
|
|
197
183
|
},
|
|
198
184
|
};
|
|
199
185
|
if (componentTestingTargetDefaults?.cache === undefined) {
|
|
@@ -201,9 +187,7 @@ function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
|
201
187
|
}
|
|
202
188
|
if (componentTestingTargetDefaults?.inputs === undefined) {
|
|
203
189
|
targets[options.componentTestingTargetName].inputs =
|
|
204
|
-
|
|
205
|
-
? ['default', '^production']
|
|
206
|
-
: ['default', '^default'];
|
|
190
|
+
getInputs(namedInputs);
|
|
207
191
|
}
|
|
208
192
|
if (componentTestingTargetDefaults?.outputs === undefined) {
|
|
209
193
|
targets[options.componentTestingTargetName].outputs = getOutputs(projectRoot, cypressConfig, 'component');
|
|
@@ -241,3 +225,13 @@ function normalizeOptions(options) {
|
|
|
241
225
|
options.ciTargetName ??= 'e2e-ci';
|
|
242
226
|
return options;
|
|
243
227
|
}
|
|
228
|
+
function getInputs(namedInputs) {
|
|
229
|
+
return [
|
|
230
|
+
...('production' in namedInputs
|
|
231
|
+
? ['default', '^production']
|
|
232
|
+
: ['default', '^default']),
|
|
233
|
+
{
|
|
234
|
+
externalDependencies: ['cypress'],
|
|
235
|
+
},
|
|
236
|
+
];
|
|
237
|
+
}
|
package/src/utils/add-linter.js
CHANGED
|
@@ -20,9 +20,6 @@ async function addLinterToCyProject(tree, options) {
|
|
|
20
20
|
linter: options.linter,
|
|
21
21
|
skipFormat: true,
|
|
22
22
|
tsConfigPaths: [(0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json')],
|
|
23
|
-
eslintFilePatterns: [
|
|
24
|
-
`${projectConfig.root}/**/*.${options.js ? 'js' : '{js,ts}'}`,
|
|
25
|
-
],
|
|
26
23
|
setParserOptionsProject: options.setParserOptionsProject,
|
|
27
24
|
skipPackageJson: options.skipPackageJson,
|
|
28
25
|
rootProject: options.rootProject,
|
package/src/utils/versions.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export declare const cypressViteDevServerVersion = "^2.2.1";
|
|
|
5
5
|
export declare const cypressVersion = "^13.0.0";
|
|
6
6
|
export declare const cypressWebpackVersion = "^2.0.0";
|
|
7
7
|
export declare const webpackHttpPluginVersion = "^5.5.0";
|
|
8
|
-
export declare const viteVersion = "
|
|
8
|
+
export declare const viteVersion = "^5.0.0";
|
|
9
9
|
export declare const htmlWebpackPluginVersion = "^5.5.0";
|
package/src/utils/versions.js
CHANGED
|
@@ -8,5 +8,5 @@ exports.cypressViteDevServerVersion = '^2.2.1';
|
|
|
8
8
|
exports.cypressVersion = '^13.0.0';
|
|
9
9
|
exports.cypressWebpackVersion = '^2.0.0';
|
|
10
10
|
exports.webpackHttpPluginVersion = '^5.5.0';
|
|
11
|
-
exports.viteVersion = '
|
|
11
|
+
exports.viteVersion = '^5.0.0';
|
|
12
12
|
exports.htmlWebpackPluginVersion = '^5.5.0';
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
|
5
|
-
const typescript_1 = require("typescript");
|
|
6
|
-
function addDevServerTargets(tree, cypressConfig, devServerTargets) {
|
|
7
|
-
const contents = tree.read(cypressConfig, 'utf-8');
|
|
8
|
-
const sourceFile = (0, typescript_1.createSourceFile)(cypressConfig, contents, typescript_1.ScriptTarget.ESNext);
|
|
9
|
-
const ciDevServerTarget = devServerTargets.ci;
|
|
10
|
-
delete devServerTargets.ci;
|
|
11
|
-
const changes = [];
|
|
12
|
-
const visit = (node) => {
|
|
13
|
-
if ((0, typescript_1.isCallExpression)(node) &&
|
|
14
|
-
(0, typescript_1.isIdentifier)(node.expression) &&
|
|
15
|
-
node.expression.text === 'nxE2EPreset') {
|
|
16
|
-
const argumentContents = ', ' +
|
|
17
|
-
JSON.stringify({
|
|
18
|
-
devServerTargets,
|
|
19
|
-
ciDevServerTarget,
|
|
20
|
-
});
|
|
21
|
-
if (node.arguments.length === 1) {
|
|
22
|
-
changes.push({
|
|
23
|
-
type: devkit_1.ChangeType.Insert,
|
|
24
|
-
index: node.arguments[0].getEnd(),
|
|
25
|
-
text: argumentContents,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
const lastArgument = node.arguments[node.arguments.length - 1];
|
|
30
|
-
if ((0, typescript_1.isObjectLiteralExpression)(lastArgument)) {
|
|
31
|
-
const lastProperty = lastArgument.properties[lastArgument.properties.length - 1];
|
|
32
|
-
const trailingComma = lastArgument.properties.hasTrailingComma;
|
|
33
|
-
changes.push({
|
|
34
|
-
type: devkit_1.ChangeType.Insert,
|
|
35
|
-
index: lastProperty.getEnd(),
|
|
36
|
-
text: (trailingComma ? '' : ', ') +
|
|
37
|
-
'devServerTargets: ' +
|
|
38
|
-
JSON.stringify(devServerTargets) +
|
|
39
|
-
(ciDevServerTarget
|
|
40
|
-
? `, ciDevServerTarget: '${ciDevServerTarget}'`
|
|
41
|
-
: ''),
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
(0, typescript_1.forEachChild)(node, visit);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
(0, typescript_1.forEachChild)(sourceFile, visit);
|
|
51
|
-
tree.write(cypressConfig, (0, devkit_1.applyChangesToString)(contents, changes));
|
|
52
|
-
}
|
|
53
|
-
async function update(tree) {
|
|
54
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
55
|
-
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
56
|
-
const devServerTargetsMap = new Map();
|
|
57
|
-
(0, executor_options_utils_1.forEachExecutorOptionsInGraph)(graph, '@nx/cypress:cypress', (options, project, target, configuration) => {
|
|
58
|
-
const targetConfig = projects.get(project).targets?.[target];
|
|
59
|
-
if (!targetConfig) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const cypressConfig = options.cypressConfig ?? targetConfig.options?.cypressConfig;
|
|
63
|
-
if (!cypressConfig) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const devServerTargets = {};
|
|
67
|
-
devServerTargets.default = targetConfig.options?.devServerTarget;
|
|
68
|
-
for (const [configuration, configurationOptions] of Object.entries(targetConfig.configurations ?? {})) {
|
|
69
|
-
devServerTargets[configuration] = configurationOptions.devServerTarget;
|
|
70
|
-
}
|
|
71
|
-
devServerTargetsMap.set(cypressConfig, devServerTargets);
|
|
72
|
-
});
|
|
73
|
-
for (const [cypressConfig, devServerTargets] of devServerTargetsMap) {
|
|
74
|
-
addDevServerTargets(tree, cypressConfig, devServerTargets);
|
|
75
|
-
}
|
|
76
|
-
// const configFiles = glob(tree, [createNodes[0]]);
|
|
77
|
-
//
|
|
78
|
-
// const proj = Object.fromEntries(getProjects(tree).entries());
|
|
79
|
-
//
|
|
80
|
-
// const rootMappings = createProjectRootMappingsFromProjectConfigurations(proj);
|
|
81
|
-
//
|
|
82
|
-
// for (const configFile of configFiles) {
|
|
83
|
-
// const siblings = tree.children(dirname(configFile));
|
|
84
|
-
// if (!siblings.includes('project.json')) {
|
|
85
|
-
// continue;
|
|
86
|
-
// }
|
|
87
|
-
//
|
|
88
|
-
// const projectName = findProjectForPath(configFile, rootMappings);
|
|
89
|
-
// const projectConfig = readProjectConfiguration(tree, projectName);
|
|
90
|
-
// const e2eTarget: TargetConfiguration<CypressExecutorOptions> =
|
|
91
|
-
// projectConfig.targets?.e2e;
|
|
92
|
-
//
|
|
93
|
-
// if (!e2eTarget || e2eTarget.executor !== '@nx/cypress:cypress') {
|
|
94
|
-
// continue;
|
|
95
|
-
// }
|
|
96
|
-
//
|
|
97
|
-
// nxMetadata.devServerTarget = e2eTarget.options?.devServerTarget;
|
|
98
|
-
// nxMetadata.productionDevServerTarget =
|
|
99
|
-
// e2eTarget.configurations?.production?.devServerTarget;
|
|
100
|
-
// nxMetadata.ciDevServerTarget =
|
|
101
|
-
// e2eTarget.configurations?.ci?.devServerTarget;
|
|
102
|
-
//
|
|
103
|
-
// if (Object.values(nxMetadata).filter((v) => !!v).length > 0) {
|
|
104
|
-
// let contents = tree.read(configFile, 'utf-8');
|
|
105
|
-
//
|
|
106
|
-
// contents =
|
|
107
|
-
// `import type { NxCypressMetadata } from '@nx/cypress/plugin';\n` +
|
|
108
|
-
// contents +
|
|
109
|
-
// `
|
|
110
|
-
//
|
|
111
|
-
// /**
|
|
112
|
-
// * This is metadata for the @nx/cypress/plugin
|
|
113
|
-
// */
|
|
114
|
-
// export const nx: NxCypressMetadata = ${JSON.stringify(
|
|
115
|
-
// nxMetadata,
|
|
116
|
-
// null,
|
|
117
|
-
// 2
|
|
118
|
-
// )};`;
|
|
119
|
-
//
|
|
120
|
-
// tree.write(configFile, contents);
|
|
121
|
-
// }
|
|
122
|
-
// }
|
|
123
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
124
|
-
}
|
|
125
|
-
exports.default = update;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const plugin_1 = require("../../plugins/plugin");
|
|
5
|
-
const find_project_for_path_1 = require("nx/src/project-graph/utils/find-project-for-path");
|
|
6
|
-
const replace_project_configuration_with_plugin_1 = require("@nx/devkit/src/utils/replace-project-configuration-with-plugin");
|
|
7
|
-
async function update(tree) {
|
|
8
|
-
const proj = Object.fromEntries((0, devkit_1.getProjects)(tree).entries());
|
|
9
|
-
const rootMappings = (0, find_project_for_path_1.createProjectRootMappingsFromProjectConfigurations)(proj);
|
|
10
|
-
await (0, replace_project_configuration_with_plugin_1.replaceProjectConfigurationsWithPlugin)(tree, rootMappings, '@nx/cypress/plugin', plugin_1.createNodes, {
|
|
11
|
-
targetName: 'e2e',
|
|
12
|
-
componentTestingTargetName: 'component-test',
|
|
13
|
-
});
|
|
14
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
15
|
-
}
|
|
16
|
-
exports.default = update;
|