cypress 5.2.0 → 5.6.0
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/index.js +6 -6
- package/lib/cli.js +119 -107
- package/lib/cypress.js +21 -21
- package/lib/errors.js +233 -276
- package/lib/exec/info.js +29 -32
- package/lib/exec/open.js +7 -8
- package/lib/exec/run.js +20 -20
- package/lib/exec/spawn.js +53 -49
- package/lib/exec/versions.js +18 -17
- package/lib/exec/xvfb.js +43 -37
- package/lib/fs.js +1 -1
- package/lib/logger.js +24 -50
- package/lib/tasks/cache.js +96 -36
- package/lib/tasks/download.js +113 -133
- package/lib/tasks/get-folder-size.js +41 -0
- package/lib/tasks/install.js +165 -249
- package/lib/tasks/state.js +54 -56
- package/lib/tasks/unzip.js +72 -69
- package/lib/tasks/verify.js +112 -147
- package/lib/util.js +172 -176
- package/package.json +4 -4
- package/types/cypress-npm-api.d.ts +13 -5
- package/types/cypress.d.ts +15 -15
- package/types/mocha/index.d.ts +123 -308
- package/types/net-stubbing.ts +132 -21
package/lib/exec/info.js
CHANGED
@@ -1,67 +1,64 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
/* eslint-disable no-console */
|
4
|
-
|
4
|
+
const spawn = require('./spawn');
|
5
5
|
|
6
|
-
|
6
|
+
const util = require('../util');
|
7
7
|
|
8
|
-
|
8
|
+
const state = require('../tasks/state');
|
9
9
|
|
10
|
-
|
10
|
+
const os = require('os');
|
11
11
|
|
12
|
-
|
12
|
+
const chalk = require('chalk');
|
13
13
|
|
14
|
-
|
14
|
+
const prettyBytes = require('pretty-bytes');
|
15
15
|
|
16
|
-
|
16
|
+
const _ = require('lodash');
|
17
17
|
|
18
|
-
|
18
|
+
const R = require('ramda'); // color for numbers and show values
|
19
19
|
|
20
20
|
|
21
|
-
|
21
|
+
const g = chalk.green; // color for paths
|
22
22
|
|
23
|
-
|
23
|
+
const p = chalk.cyan; // urls
|
24
24
|
|
25
|
-
|
25
|
+
const link = chalk.blue.underline; // to be exported
|
26
26
|
|
27
|
-
|
27
|
+
const methods = {};
|
28
28
|
|
29
|
-
methods.findProxyEnvironmentVariables =
|
29
|
+
methods.findProxyEnvironmentVariables = () => {
|
30
30
|
return _.pick(process.env, ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY']);
|
31
31
|
};
|
32
32
|
|
33
|
-
|
33
|
+
const maskSensitiveVariables = R.evolve({
|
34
34
|
CYPRESS_RECORD_KEY: R.always('<redacted>')
|
35
35
|
});
|
36
36
|
|
37
|
-
methods.findCypressEnvironmentVariables =
|
38
|
-
|
39
|
-
return key.startsWith('CYPRESS_');
|
40
|
-
};
|
37
|
+
methods.findCypressEnvironmentVariables = () => {
|
38
|
+
const isCyVariable = (val, key) => key.startsWith('CYPRESS_');
|
41
39
|
|
42
40
|
return R.pickBy(isCyVariable)(process.env);
|
43
41
|
};
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
const formatCypressVariables = () => {
|
44
|
+
const vars = methods.findCypressEnvironmentVariables();
|
47
45
|
return maskSensitiveVariables(vars);
|
48
46
|
};
|
49
47
|
|
50
|
-
methods.start =
|
51
|
-
|
52
|
-
var args = ['--mode=info'];
|
48
|
+
methods.start = (options = {}) => {
|
49
|
+
const args = ['--mode=info'];
|
53
50
|
return spawn.start(args, {
|
54
51
|
dev: options.dev
|
55
|
-
}).then(
|
52
|
+
}).then(() => {
|
56
53
|
console.log();
|
57
|
-
|
54
|
+
const proxyVars = methods.findProxyEnvironmentVariables();
|
58
55
|
|
59
56
|
if (_.isEmpty(proxyVars)) {
|
60
57
|
console.log('Proxy Settings: none detected');
|
61
58
|
} else {
|
62
59
|
console.log('Proxy Settings:');
|
63
60
|
|
64
|
-
_.forEach(proxyVars,
|
61
|
+
_.forEach(proxyVars, (value, key) => {
|
65
62
|
console.log('%s: %s', key, g(value));
|
66
63
|
});
|
67
64
|
|
@@ -69,26 +66,26 @@ methods.start = function () {
|
|
69
66
|
console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'));
|
70
67
|
console.log();
|
71
68
|
}
|
72
|
-
}).then(
|
73
|
-
|
69
|
+
}).then(() => {
|
70
|
+
const cyVars = formatCypressVariables();
|
74
71
|
|
75
72
|
if (_.isEmpty(cyVars)) {
|
76
73
|
console.log('Environment Variables: none detected');
|
77
74
|
} else {
|
78
75
|
console.log('Environment Variables:');
|
79
76
|
|
80
|
-
_.forEach(cyVars,
|
77
|
+
_.forEach(cyVars, (value, key) => {
|
81
78
|
console.log('%s: %s', key, g(value));
|
82
79
|
});
|
83
80
|
}
|
84
|
-
}).then(
|
81
|
+
}).then(() => {
|
85
82
|
console.log();
|
86
83
|
console.log('Application Data:', p(util.getApplicationDataFolder()));
|
87
84
|
console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')));
|
88
85
|
console.log('Binary Caches: %s', p(state.getCacheDir()));
|
89
|
-
}).then(
|
86
|
+
}).then(() => {
|
90
87
|
console.log();
|
91
|
-
return util.getOsVersionAsync().then(
|
88
|
+
return util.getOsVersionAsync().then(osVersion => {
|
92
89
|
console.log('Cypress Version: %s', g(util.pkgVersion()));
|
93
90
|
console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion));
|
94
91
|
console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())));
|
package/lib/exec/open.js
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const debug = require('debug')('cypress:cli');
|
4
4
|
|
5
|
-
|
5
|
+
const util = require('../util');
|
6
6
|
|
7
|
-
|
7
|
+
const spawn = require('./spawn');
|
8
8
|
|
9
|
-
|
9
|
+
const verify = require('../tasks/verify');
|
10
10
|
|
11
11
|
module.exports = {
|
12
|
-
start
|
13
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
14
|
-
|
12
|
+
start(options = {}) {
|
15
13
|
if (!util.isInstalledGlobally() && !options.global && !options.project) {
|
16
14
|
options.project = process.cwd();
|
17
15
|
}
|
18
16
|
|
19
|
-
|
17
|
+
const args = [];
|
20
18
|
|
21
19
|
if (options.config) {
|
22
20
|
args.push('--config', options.config);
|
@@ -59,4 +57,5 @@ module.exports = {
|
|
59
57
|
|
60
58
|
return verify.start().then(open);
|
61
59
|
}
|
60
|
+
|
62
61
|
};
|
package/lib/exec/run.js
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const _ = require('lodash');
|
4
4
|
|
5
|
-
|
5
|
+
const debug = require('debug')('cypress:cli:run');
|
6
6
|
|
7
|
-
|
7
|
+
const util = require('../util');
|
8
8
|
|
9
|
-
|
9
|
+
const spawn = require('./spawn');
|
10
10
|
|
11
|
-
|
11
|
+
const verify = require('../tasks/verify');
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
const {
|
14
|
+
exitWithError,
|
15
|
+
errors
|
16
|
+
} = require('../errors');
|
16
17
|
/**
|
17
18
|
* Throws an error with "details" property from
|
18
19
|
* "errors" object.
|
@@ -20,14 +21,14 @@ var _require = require('../errors'),
|
|
20
21
|
*/
|
21
22
|
|
22
23
|
|
23
|
-
|
24
|
+
const throwInvalidOptionError = details => {
|
24
25
|
if (!details) {
|
25
26
|
details = errors.unknownError;
|
26
27
|
} // throw this error synchronously, it will be caught later on and
|
27
28
|
// the details will be propagated to the promise chain
|
28
29
|
|
29
30
|
|
30
|
-
|
31
|
+
const err = new Error();
|
31
32
|
err.details = details;
|
32
33
|
throw err;
|
33
34
|
};
|
@@ -39,7 +40,7 @@ var throwInvalidOptionError = function throwInvalidOptionError(details) {
|
|
39
40
|
*/
|
40
41
|
|
41
42
|
|
42
|
-
|
43
|
+
const isValidProject = v => {
|
43
44
|
if (typeof v === 'boolean') {
|
44
45
|
return false;
|
45
46
|
}
|
@@ -61,8 +62,7 @@ var isValidProject = function isValidProject(v) {
|
|
61
62
|
*/
|
62
63
|
|
63
64
|
|
64
|
-
|
65
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
65
|
+
const processRunOptions = (options = {}) => {
|
66
66
|
debug('processing run options %o', options);
|
67
67
|
|
68
68
|
if (!isValidProject(options.project)) {
|
@@ -72,7 +72,7 @@ var processRunOptions = function processRunOptions() {
|
|
72
72
|
return throwInvalidOptionError(errors.invalidRunProjectPath);
|
73
73
|
}
|
74
74
|
|
75
|
-
|
75
|
+
const args = ['--run-project', options.project];
|
76
76
|
|
77
77
|
if (options.browser) {
|
78
78
|
args.push('--browser', options.browser);
|
@@ -177,12 +177,11 @@ var processRunOptions = function processRunOptions() {
|
|
177
177
|
};
|
178
178
|
|
179
179
|
module.exports = {
|
180
|
-
processRunOptions
|
181
|
-
isValidProject
|
182
|
-
// resolves with the number of failed tests
|
183
|
-
start: function start() {
|
184
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
180
|
+
processRunOptions,
|
181
|
+
isValidProject,
|
185
182
|
|
183
|
+
// resolves with the number of failed tests
|
184
|
+
start(options = {}) {
|
186
185
|
_.defaults(options, {
|
187
186
|
key: null,
|
188
187
|
spec: null,
|
@@ -192,7 +191,7 @@ module.exports = {
|
|
192
191
|
});
|
193
192
|
|
194
193
|
function run() {
|
195
|
-
|
194
|
+
let args;
|
196
195
|
|
197
196
|
try {
|
198
197
|
args = processRunOptions(options);
|
@@ -216,4 +215,5 @@ module.exports = {
|
|
216
215
|
|
217
216
|
return verify.start().then(run);
|
218
217
|
}
|
218
|
+
|
219
219
|
};
|
package/lib/exec/spawn.js
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const _ = require('lodash');
|
4
4
|
|
5
|
-
|
5
|
+
const os = require('os');
|
6
6
|
|
7
|
-
|
7
|
+
const cp = require('child_process');
|
8
8
|
|
9
|
-
|
9
|
+
const path = require('path');
|
10
10
|
|
11
|
-
|
11
|
+
const Promise = require('bluebird');
|
12
12
|
|
13
|
-
|
13
|
+
const debug = require('debug')('cypress:cli');
|
14
14
|
|
15
|
-
|
15
|
+
const debugElectron = require('debug')('cypress:electron');
|
16
16
|
|
17
|
-
|
17
|
+
const util = require('../util');
|
18
18
|
|
19
|
-
|
19
|
+
const state = require('../tasks/state');
|
20
20
|
|
21
|
-
|
21
|
+
const xvfb = require('./xvfb');
|
22
22
|
|
23
|
-
|
23
|
+
const verify = require('../tasks/verify');
|
24
24
|
|
25
|
-
|
25
|
+
const errors = require('../errors');
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
const isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
|
28
|
+
const isHighSierraWarningRe = /\*\*\* WARNING/;
|
29
|
+
const isRenderWorkerRe = /\.RenderWorker-/;
|
30
|
+
const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe];
|
31
31
|
|
32
|
-
|
33
|
-
return _.some(GARBAGE_WARNINGS,
|
32
|
+
const isGarbageLineWarning = str => {
|
33
|
+
return _.some(GARBAGE_WARNINGS, re => {
|
34
34
|
return re.test(str);
|
35
35
|
});
|
36
36
|
};
|
@@ -66,11 +66,11 @@ function getStdio(needsXvfb) {
|
|
66
66
|
}
|
67
67
|
|
68
68
|
module.exports = {
|
69
|
-
isGarbageLineWarning
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
isGarbageLineWarning,
|
70
|
+
|
71
|
+
start(args, options = {}) {
|
72
|
+
const needsXvfb = xvfb.isNeeded();
|
73
|
+
let executable = state.getPathToExecutable(state.getBinaryDir());
|
74
74
|
|
75
75
|
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
76
76
|
executable = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
@@ -93,9 +93,8 @@ module.exports = {
|
|
93
93
|
stdio: getStdio(needsXvfb)
|
94
94
|
});
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
return new Promise(function (resolve, reject) {
|
96
|
+
const spawn = (overrides = {}) => {
|
97
|
+
return new Promise((resolve, reject) => {
|
99
98
|
_.defaults(overrides, {
|
100
99
|
onStderrData: false,
|
101
100
|
electronLogging: false
|
@@ -109,13 +108,15 @@ module.exports = {
|
|
109
108
|
debug('in dev mode the args became %o', args);
|
110
109
|
}
|
111
110
|
|
112
|
-
|
113
|
-
|
114
|
-
|
111
|
+
const {
|
112
|
+
onStderrData,
|
113
|
+
electronLogging
|
114
|
+
} = overrides;
|
115
|
+
const envOverrides = util.getEnvOverrides(options);
|
115
116
|
|
116
|
-
|
117
|
+
const electronArgs = _.clone(args);
|
117
118
|
|
118
|
-
|
119
|
+
const node11WindowsFix = isPlatform('win32');
|
119
120
|
|
120
121
|
if (!options.dev && verify.needsSandbox()) {
|
121
122
|
// this is one of the Electron's command line switches
|
@@ -124,7 +125,7 @@ module.exports = {
|
|
124
125
|
} // strip dev out of child process options
|
125
126
|
|
126
127
|
|
127
|
-
|
128
|
+
let stdioOptions = _.pick(options, 'env', 'detached', 'stdio'); // figure out if we're going to be force enabling or disabling colors.
|
128
129
|
// also figure out whether we should force stdout and stderr into thinking
|
129
130
|
// it is a tty as opposed to a pipe.
|
130
131
|
|
@@ -149,18 +150,18 @@ module.exports = {
|
|
149
150
|
|
150
151
|
debug('spawning Cypress with executable: %s', executable);
|
151
152
|
debug('spawn args %o %o', electronArgs, _.omit(stdioOptions, 'env'));
|
152
|
-
|
153
|
+
const child = cp.spawn(executable, electronArgs, stdioOptions);
|
153
154
|
|
154
155
|
function resolveOn(event) {
|
155
156
|
return function (code, signal) {
|
156
157
|
debug('child event fired %o', {
|
157
|
-
event
|
158
|
-
code
|
159
|
-
signal
|
158
|
+
event,
|
159
|
+
code,
|
160
|
+
signal
|
160
161
|
});
|
161
162
|
|
162
163
|
if (code === null) {
|
163
|
-
|
164
|
+
const errorObject = errors.errors.childProcessKilled(event, signal);
|
164
165
|
return errors.getError(errorObject).then(reject);
|
165
166
|
}
|
166
167
|
|
@@ -190,8 +191,8 @@ module.exports = {
|
|
190
191
|
|
191
192
|
if (child.stderr) {
|
192
193
|
debug('piping child STDERR to process STDERR');
|
193
|
-
child.stderr.on('data',
|
194
|
-
|
194
|
+
child.stderr.on('data', data => {
|
195
|
+
const str = data.toString(); // bail if this is warning line garbage
|
195
196
|
|
196
197
|
if (isGarbageLineWarning(str)) {
|
197
198
|
return;
|
@@ -215,7 +216,7 @@ module.exports = {
|
|
215
216
|
// error here and not doing anything.
|
216
217
|
|
217
218
|
|
218
|
-
process.stdin.on('error',
|
219
|
+
process.stdin.on('error', err => {
|
219
220
|
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
|
220
221
|
return;
|
221
222
|
}
|
@@ -229,19 +230,20 @@ module.exports = {
|
|
229
230
|
});
|
230
231
|
};
|
231
232
|
|
232
|
-
|
233
|
-
return xvfb.start().then(userFriendlySpawn)
|
233
|
+
const spawnInXvfb = () => {
|
234
|
+
return xvfb.start().then(userFriendlySpawn).finally(xvfb.stop);
|
234
235
|
};
|
235
236
|
|
236
|
-
|
237
|
+
const userFriendlySpawn = linuxWithDisplayEnv => {
|
237
238
|
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
|
238
|
-
|
239
|
-
|
239
|
+
let brokenGtkDisplay;
|
240
|
+
const overrides = {};
|
240
241
|
|
241
242
|
if (linuxWithDisplayEnv) {
|
242
243
|
_.extend(overrides, {
|
243
244
|
electronLogging: true,
|
244
|
-
|
245
|
+
|
246
|
+
onStderrData(str) {
|
245
247
|
// if we receive a broken pipe anywhere
|
246
248
|
// then we know that's why cypress exited early
|
247
249
|
if (util.isBrokenGtkDisplay(str)) {
|
@@ -255,10 +257,11 @@ module.exports = {
|
|
255
257
|
return false;
|
256
258
|
}
|
257
259
|
}
|
260
|
+
|
258
261
|
});
|
259
262
|
}
|
260
263
|
|
261
|
-
return spawn(overrides).then(
|
264
|
+
return spawn(overrides).then(code => {
|
262
265
|
if (code !== 0 && brokenGtkDisplay) {
|
263
266
|
util.logBrokenGtkDisplayWarning();
|
264
267
|
return spawnInXvfb();
|
@@ -267,7 +270,7 @@ module.exports = {
|
|
267
270
|
return code;
|
268
271
|
}) // we can format and handle an error message from the code above
|
269
272
|
// prevent wrapping error again by using "known: undefined" filter
|
270
|
-
|
273
|
+
.catch({
|
271
274
|
known: undefined
|
272
275
|
}, errors.throwFormErrorText(errors.errors.unexpected));
|
273
276
|
};
|
@@ -279,7 +282,8 @@ module.exports = {
|
|
279
282
|
// spawning our own Xvfb server
|
280
283
|
|
281
284
|
|
282
|
-
|
285
|
+
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
283
286
|
return userFriendlySpawn(linuxWithDisplayEnv);
|
284
287
|
}
|
288
|
+
|
285
289
|
};
|
package/lib/exec/versions.js
CHANGED
@@ -1,46 +1,47 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const Promise = require('bluebird');
|
4
4
|
|
5
|
-
|
5
|
+
const debug = require('debug')('cypress:cli');
|
6
6
|
|
7
|
-
|
7
|
+
const path = require('path');
|
8
8
|
|
9
|
-
|
9
|
+
const util = require('../util');
|
10
10
|
|
11
|
-
|
11
|
+
const state = require('../tasks/state');
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
const {
|
14
|
+
throwFormErrorText,
|
15
|
+
errors
|
16
|
+
} = require('../errors');
|
16
17
|
|
17
|
-
|
18
|
-
return Promise
|
18
|
+
const getVersions = () => {
|
19
|
+
return Promise.try(() => {
|
19
20
|
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
20
|
-
|
21
|
-
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath).then(
|
21
|
+
let envBinaryPath = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
22
|
+
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath).then(envBinaryDir => {
|
22
23
|
if (!envBinaryDir) {
|
23
24
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
|
24
25
|
}
|
25
26
|
|
26
27
|
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
27
28
|
return envBinaryDir;
|
28
|
-
})
|
29
|
+
}).catch({
|
29
30
|
code: 'ENOENT'
|
30
|
-
},
|
31
|
+
}, err => {
|
31
32
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
|
32
33
|
});
|
33
34
|
}
|
34
35
|
|
35
36
|
return state.getBinaryDir();
|
36
|
-
}).then(state.getBinaryPkgVersionAsync).then(
|
37
|
+
}).then(state.getBinaryPkgVersionAsync).then(binaryVersion => {
|
37
38
|
return {
|
38
|
-
|
39
|
+
package: util.pkgVersion(),
|
39
40
|
binary: binaryVersion || 'not installed'
|
40
41
|
};
|
41
42
|
});
|
42
43
|
};
|
43
44
|
|
44
45
|
module.exports = {
|
45
|
-
getVersions
|
46
|
+
getVersions
|
46
47
|
};
|
package/lib/exec/xvfb.js
CHANGED
@@ -1,61 +1,54 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
4
|
-
var data = _taggedTemplateLiteral(["\n DISPLAY environment variable is set to ", " on Linux\n Assuming this DISPLAY points at working X11 server,\n Cypress will not spawn own Xvfb\n\n NOTE: if the X11 server is NOT working, Cypress will exit without explanation,\n see ", "\n Solution: Unset the DISPLAY variable and try again:\n DISPLAY= npx cypress run ...\n "]);
|
3
|
+
const os = require('os');
|
5
4
|
|
6
|
-
|
7
|
-
return data;
|
8
|
-
};
|
5
|
+
const Promise = require('bluebird');
|
9
6
|
|
10
|
-
|
11
|
-
}
|
7
|
+
const Xvfb = require('@cypress/xvfb');
|
12
8
|
|
13
|
-
|
9
|
+
const {
|
10
|
+
stripIndent
|
11
|
+
} = require('common-tags');
|
14
12
|
|
15
|
-
|
13
|
+
const debug = require('debug')('cypress:cli');
|
16
14
|
|
17
|
-
|
15
|
+
const debugXvfb = require('debug')('cypress:xvfb');
|
18
16
|
|
19
|
-
|
17
|
+
const {
|
18
|
+
throwFormErrorText,
|
19
|
+
errors
|
20
|
+
} = require('../errors');
|
20
21
|
|
21
|
-
|
22
|
-
stripIndent = _require.stripIndent;
|
22
|
+
const util = require('../util');
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
var debugXvfb = require('debug')('cypress:xvfb');
|
27
|
-
|
28
|
-
var _require2 = require('../errors'),
|
29
|
-
throwFormErrorText = _require2.throwFormErrorText,
|
30
|
-
errors = _require2.errors;
|
31
|
-
|
32
|
-
var util = require('../util');
|
33
|
-
|
34
|
-
var xvfbOptions = {
|
24
|
+
const xvfbOptions = {
|
35
25
|
timeout: 30000,
|
36
26
|
// milliseconds
|
37
27
|
// need to explicitly define screen otherwise electron will crash
|
38
28
|
// https://github.com/cypress-io/cypress/issues/6184
|
39
29
|
xvfb_args: ['-screen', '0', '1280x1024x24'],
|
40
|
-
|
30
|
+
|
31
|
+
onStderrData(data) {
|
41
32
|
if (debugXvfb.enabled) {
|
42
33
|
debugXvfb(data.toString());
|
43
34
|
}
|
44
35
|
}
|
36
|
+
|
45
37
|
};
|
46
|
-
|
38
|
+
const xvfb = Promise.promisifyAll(new Xvfb(xvfbOptions));
|
47
39
|
module.exports = {
|
48
40
|
_debugXvfb: debugXvfb,
|
49
41
|
// expose for testing
|
50
42
|
_xvfb: xvfb,
|
51
43
|
// expose for testing
|
52
44
|
_xvfbOptions: xvfbOptions,
|
45
|
+
|
53
46
|
// expose for testing
|
54
|
-
start
|
47
|
+
start() {
|
55
48
|
debug('Starting Xvfb');
|
56
|
-
return xvfb.startAsync()
|
49
|
+
return xvfb.startAsync().return(null).catch({
|
57
50
|
nonZeroExitCode: true
|
58
|
-
}, throwFormErrorText(errors.nonZeroExitCodeXvfb))
|
51
|
+
}, throwFormErrorText(errors.nonZeroExitCodeXvfb)).catch(err => {
|
59
52
|
if (err.known) {
|
60
53
|
throw err;
|
61
54
|
}
|
@@ -63,19 +56,30 @@ module.exports = {
|
|
63
56
|
return throwFormErrorText(errors.missingXvfb)(err);
|
64
57
|
});
|
65
58
|
},
|
66
|
-
|
59
|
+
|
60
|
+
stop() {
|
67
61
|
debug('Stopping Xvfb');
|
68
|
-
return xvfb.stopAsync()
|
62
|
+
return xvfb.stopAsync().return(null).catch(() => {// noop
|
69
63
|
});
|
70
64
|
},
|
71
|
-
|
65
|
+
|
66
|
+
isNeeded() {
|
72
67
|
if (os.platform() !== 'linux') {
|
73
68
|
return false;
|
74
69
|
}
|
75
70
|
|
76
71
|
if (process.env.DISPLAY) {
|
77
|
-
|
78
|
-
|
72
|
+
const issueUrl = util.getGitHubIssueUrl(4034);
|
73
|
+
const message = stripIndent`
|
74
|
+
DISPLAY environment variable is set to ${process.env.DISPLAY} on Linux
|
75
|
+
Assuming this DISPLAY points at working X11 server,
|
76
|
+
Cypress will not spawn own Xvfb
|
77
|
+
|
78
|
+
NOTE: if the X11 server is NOT working, Cypress will exit without explanation,
|
79
|
+
see ${issueUrl}
|
80
|
+
Solution: Unset the DISPLAY variable and try again:
|
81
|
+
DISPLAY= npx cypress run ...
|
82
|
+
`;
|
79
83
|
debug(message);
|
80
84
|
return false;
|
81
85
|
}
|
@@ -84,11 +88,13 @@ module.exports = {
|
|
84
88
|
debug('Cypress will spawn its own Xvfb');
|
85
89
|
return true;
|
86
90
|
},
|
91
|
+
|
87
92
|
// async method, resolved with Boolean
|
88
|
-
verify
|
89
|
-
return xvfb.startAsync()
|
93
|
+
verify() {
|
94
|
+
return xvfb.startAsync().return(true).catch(err => {
|
90
95
|
debug('Could not verify xvfb: %s', err.message);
|
91
96
|
return false;
|
92
|
-
})
|
97
|
+
}).finally(xvfb.stopAsync);
|
93
98
|
}
|
99
|
+
|
94
100
|
};
|