cypress 5.4.0 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +6 -6
- package/lib/cli.js +103 -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 +62 -67
- package/lib/tasks/download.js +113 -133
- package/lib/tasks/get-folder-size.js +19 -85
- 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 +164 -167
- package/package.json +3 -3
- package/types/cypress.d.ts +2 -2
- package/types/net-stubbing.ts +74 -6
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
|
};
|