@nx/cypress 17.2.0-beta.3 → 17.2.0-beta.4
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/package.json +5 -5
- package/plugins/cypress-preset.d.ts +12 -0
- package/plugins/cypress-preset.js +66 -24
- package/src/plugins/plugin.js +6 -3
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.4",
|
|
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,15 +34,15 @@
|
|
|
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.4",
|
|
38
|
+
"@nx/eslint": "17.2.0-beta.4",
|
|
39
|
+
"@nx/js": "17.2.0-beta.4",
|
|
40
40
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
41
41
|
"detect-port": "^1.5.1",
|
|
42
42
|
"string-argv": "^0.3.2",
|
|
43
43
|
"semver": "7.5.3",
|
|
44
44
|
"tslib": "^2.3.0",
|
|
45
|
-
"@nrwl/cypress": "17.2.0-beta.
|
|
45
|
+
"@nrwl/cypress": "17.2.0-beta.4"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"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
|
/**
|
|
@@ -42,5 +53,6 @@ export type NxCypressE2EPresetOptions = {
|
|
|
42
53
|
cypressDir?: string;
|
|
43
54
|
webServerCommands?: Record<string, string>;
|
|
44
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 string_argv_1 = require("string-argv");
|
|
9
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
|
|
@@ -65,33 +76,64 @@ function nxE2EPreset(pathToConfig, options) {
|
|
|
65
76
|
if (!webServerCommand) {
|
|
66
77
|
return;
|
|
67
78
|
}
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
config.baseUrl = message.baseUrl;
|
|
84
|
-
resolve(config);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
on('after:run', () => {
|
|
88
|
-
serverProcess.kill('SIGTERM');
|
|
89
|
-
});
|
|
79
|
+
if (config.baseUrl && webServerCommand) {
|
|
80
|
+
if (await isServerUp(config.baseUrl)) {
|
|
81
|
+
if (options.webServerConfig.reuseExistingServer === undefined
|
|
82
|
+
? true
|
|
83
|
+
: options.webServerConfig.reuseExistingServer) {
|
|
84
|
+
console.log(`Reusing the server already running on ${config.baseUrl}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
throw new Error(`Web server is already running at ${config.baseUrl}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const killWebServer = startWebServer(webServerCommand);
|
|
92
|
+
on('after:run', () => {
|
|
93
|
+
killWebServer();
|
|
90
94
|
});
|
|
95
|
+
await waitForServer(config.baseUrl, options.webServerConfig);
|
|
91
96
|
}
|
|
92
|
-
return config;
|
|
93
97
|
},
|
|
94
98
|
};
|
|
95
99
|
return baseConfig;
|
|
96
100
|
}
|
|
97
101
|
exports.nxE2EPreset = nxE2EPreset;
|
|
102
|
+
function waitForServer(url, webServerConfig) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
let pollTimeout;
|
|
105
|
+
const { protocol } = new URL(url);
|
|
106
|
+
const timeoutDuration = webServerConfig?.timeout ?? 5 * 1000;
|
|
107
|
+
const timeout = setTimeout(() => {
|
|
108
|
+
clearTimeout(pollTimeout);
|
|
109
|
+
reject(new Error(`Web server failed to start in ${timeoutDuration}ms. This can be configured in cypress.config.ts.`));
|
|
110
|
+
}, timeoutDuration);
|
|
111
|
+
const makeRequest = protocol === 'https:' ? https_1.request : http_1.request;
|
|
112
|
+
function pollForServer() {
|
|
113
|
+
const request = makeRequest(url, () => {
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
resolve();
|
|
116
|
+
});
|
|
117
|
+
request.on('error', () => {
|
|
118
|
+
pollTimeout = setTimeout(pollForServer, 100);
|
|
119
|
+
});
|
|
120
|
+
// Don't forget to end the request
|
|
121
|
+
request.end();
|
|
122
|
+
}
|
|
123
|
+
pollForServer();
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function isServerUp(url) {
|
|
127
|
+
const { protocol } = new URL(url);
|
|
128
|
+
const makeRequest = protocol === 'https:' ? https_1.request : http_1.request;
|
|
129
|
+
return new Promise((resolve) => {
|
|
130
|
+
const request = makeRequest(url, () => {
|
|
131
|
+
resolve(true);
|
|
132
|
+
});
|
|
133
|
+
request.on('error', () => {
|
|
134
|
+
resolve(false);
|
|
135
|
+
});
|
|
136
|
+
// Don't forget to end the request
|
|
137
|
+
request.end();
|
|
138
|
+
});
|
|
139
|
+
}
|
package/src/plugins/plugin.js
CHANGED
|
@@ -128,8 +128,8 @@ function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
131
|
+
const ciWebServerCommand = cypressEnv?.ciWebServerCommand;
|
|
132
|
+
if (ciWebServerCommand) {
|
|
133
133
|
const specPatterns = Array.isArray(cypressConfig.e2e.specPattern)
|
|
134
134
|
? cypressConfig.e2e.specPattern.map((p) => (0, path_1.join)(projectRoot, p))
|
|
135
135
|
: [(0, path_1.join)(projectRoot, cypressConfig.e2e.specPattern)];
|
|
@@ -150,7 +150,10 @@ function buildCypressTargets(configFilePath, projectRoot, options, context) {
|
|
|
150
150
|
outputs,
|
|
151
151
|
inputs,
|
|
152
152
|
cache: true,
|
|
153
|
-
command: `cypress run --config-file ${relativeConfigPath} --e2e --env.webServerCommand
|
|
153
|
+
command: `cypress run --config-file ${relativeConfigPath} --e2e --env=${JSON.stringify({ webServerCommand: ciWebServerCommand })} --spec ${relativeSpecFilePath}`,
|
|
154
|
+
options: {
|
|
155
|
+
cwd: projectRoot,
|
|
156
|
+
},
|
|
154
157
|
};
|
|
155
158
|
dependsOn.push({
|
|
156
159
|
target: targetName,
|