cypress 12.1.0 → 12.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/angular/dist/index.js +1 -1
- package/index.js +2 -11
- package/lib/VerboseRenderer.js +2 -16
- package/lib/cli.js +25 -83
- package/lib/cypress.js +1 -14
- package/lib/errors.js +13 -38
- package/lib/exec/info.js +10 -31
- package/lib/exec/open.js +1 -24
- package/lib/exec/run.js +15 -52
- package/lib/exec/shared.js +6 -15
- package/lib/exec/spawn.js +45 -88
- package/lib/exec/versions.js +0 -9
- package/lib/exec/xvfb.js +5 -18
- package/lib/fs.js +0 -1
- package/lib/logger.js +3 -10
- package/lib/tasks/cache.js +5 -29
- package/lib/tasks/download.js +21 -57
- package/lib/tasks/get-folder-size.js +1 -9
- package/lib/tasks/install.js +20 -66
- package/lib/tasks/state.js +5 -51
- package/lib/tasks/unzip.js +7 -41
- package/lib/tasks/verify.js +11 -65
- package/lib/util.js +41 -128
- package/mount-utils/package.json +2 -2
- package/package.json +3 -3
- package/react/dist/cypress-react.cjs.js +8 -15
- package/react/dist/cypress-react.esm-bundler.js +1 -1
- package/react/package.json +1 -1
- package/react18/dist/cypress-react.cjs.js +7 -13
- package/react18/dist/cypress-react.esm-bundler.js +1 -1
- package/react18/package.json +1 -1
- package/svelte/dist/cypress-svelte.cjs.js +2 -4
- package/svelte/dist/cypress-svelte.esm-bundler.js +2 -2
- package/types/cypress.d.ts +11 -6
- package/types/net-stubbing.d.ts +11 -0
- package/vue/dist/cypress-vue.cjs.js +4 -7
- package/vue/dist/cypress-vue.esm-bundler.js +1 -1
- package/vue/package.json +1 -1
- package/vue2/dist/cypress-vue2.cjs.js +19 -28
- package/vue2/dist/cypress-vue2.esm-bundler.js +1 -4
package/lib/exec/shared.js
CHANGED
@@ -3,67 +3,58 @@
|
|
3
3
|
const {
|
4
4
|
errors
|
5
5
|
} = require('../errors');
|
6
|
+
|
6
7
|
/**
|
7
8
|
* Throws an error with "details" property from
|
8
9
|
* "errors" object.
|
9
10
|
* @param {Object} details - Error details
|
10
11
|
*/
|
11
|
-
|
12
|
-
|
13
12
|
const throwInvalidOptionError = details => {
|
14
13
|
if (!details) {
|
15
14
|
details = errors.unknownError;
|
16
|
-
}
|
17
|
-
// the details will be propagated to the promise chain
|
18
|
-
|
15
|
+
}
|
19
16
|
|
17
|
+
// throw this error synchronously, it will be caught later on and
|
18
|
+
// the details will be propagated to the promise chain
|
20
19
|
const err = new Error();
|
21
20
|
err.details = details;
|
22
21
|
throw err;
|
23
22
|
};
|
23
|
+
|
24
24
|
/**
|
25
25
|
* Selects exec args based on the configured `testingType`
|
26
26
|
* @param {string} testingType The type of tests being executed
|
27
27
|
* @returns {string[]} The array of new exec arguments
|
28
28
|
*/
|
29
|
-
|
30
|
-
|
31
29
|
const processTestingType = options => {
|
32
30
|
if (options.e2e && options.component) {
|
33
31
|
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
|
34
32
|
}
|
35
|
-
|
36
33
|
if (options.testingType && (options.component || options.e2e)) {
|
37
34
|
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
|
38
35
|
}
|
39
|
-
|
40
36
|
if (options.testingType === 'component' || options.component || options.ct) {
|
41
37
|
return ['--testing-type', 'component'];
|
42
38
|
}
|
43
|
-
|
44
39
|
if (options.testingType === 'e2e' || options.e2e) {
|
45
40
|
return ['--testing-type', 'e2e'];
|
46
41
|
}
|
47
|
-
|
48
42
|
if (options.testingType) {
|
49
43
|
return throwInvalidOptionError(errors.invalidTestingType);
|
50
44
|
}
|
51
|
-
|
52
45
|
return [];
|
53
46
|
};
|
47
|
+
|
54
48
|
/**
|
55
49
|
* Throws an error if configFile is string 'false' or boolean false
|
56
50
|
* @param {*} options
|
57
51
|
*/
|
58
|
-
|
59
|
-
|
60
52
|
const checkConfigFile = options => {
|
61
53
|
// CLI will parse as string, module API can pass in boolean
|
62
54
|
if (options.configFile === 'false' || options.configFile === false) {
|
63
55
|
throwInvalidOptionError(errors.invalidConfigFile);
|
64
56
|
}
|
65
57
|
};
|
66
|
-
|
67
58
|
module.exports = {
|
68
59
|
throwInvalidOptionError,
|
69
60
|
processTestingType,
|
package/lib/exec/spawn.js
CHANGED
@@ -1,129 +1,109 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
const _ = require('lodash');
|
4
|
-
|
5
4
|
const os = require('os');
|
6
|
-
|
7
5
|
const cp = require('child_process');
|
8
|
-
|
9
6
|
const path = require('path');
|
10
|
-
|
11
7
|
const Promise = require('bluebird');
|
12
|
-
|
13
8
|
const debug = require('debug')('cypress:cli');
|
14
|
-
|
15
9
|
const debugElectron = require('debug')('cypress:electron');
|
16
|
-
|
17
10
|
const util = require('../util');
|
18
|
-
|
19
11
|
const state = require('../tasks/state');
|
20
|
-
|
21
12
|
const xvfb = require('./xvfb');
|
22
|
-
|
23
13
|
const verify = require('../tasks/verify');
|
24
|
-
|
25
14
|
const errors = require('../errors');
|
26
|
-
|
27
15
|
const isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
|
28
16
|
const isHighSierraWarningRe = /\*\*\* WARNING/;
|
29
|
-
const isRenderWorkerRe = /\.RenderWorker-/;
|
17
|
+
const isRenderWorkerRe = /\.RenderWorker-/;
|
18
|
+
|
19
|
+
// Chromium (which Electron uses) always makes several attempts to connect to the system dbus.
|
30
20
|
// This works fine in most desktop environments, but in a docker container, there is no dbus service
|
31
21
|
// and Chromium emits several error lines, similar to these:
|
22
|
+
|
32
23
|
// [1957:0406/160550.146820:ERROR:bus.cc(392)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
|
33
24
|
// [1957:0406/160550.147994:ERROR:bus.cc(392)] Failed to connect to the bus: Address does not contain a colon
|
25
|
+
|
34
26
|
// These warnings are absolutely harmless. Failure to connect to dbus means that electron won't be able to access the user's
|
35
27
|
// credential wallet (none exists in a docker container) and won't show up in the system tray (again, none exists).
|
36
28
|
// Failure to connect is expected and normal here, but users frequently misidentify these errors as the cause of their problems.
|
29
|
+
|
37
30
|
// https://github.com/cypress-io/cypress/issues/19299
|
31
|
+
const isDbusWarning = /Failed to connect to the bus:/;
|
38
32
|
|
39
|
-
|
33
|
+
// Electron began logging these on self-signed certs with 17.0.0-alpha.4.
|
40
34
|
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/34583
|
41
35
|
// Sample:
|
42
36
|
// [3801:0606/152837.383892:ERROR:cert_verify_proc_builtin.cc(681)] CertVerifyProcBuiltin for www.googletagmanager.com failed:
|
43
37
|
// ----- Certificate i=0 (OU=Cypress Proxy Server Certificate,O=Cypress Proxy CA,L=Internet,ST=Internet,C=Internet,CN=www.googletagmanager.com) -----
|
44
38
|
// ERROR: No matching issuer found
|
39
|
+
const isCertVerifyProcBuiltin = /(^\[.*ERROR:cert_verify_proc_builtin\.cc|^----- Certificate i=0 \(OU=Cypress Proxy|^ERROR: No matching issuer found$)/;
|
45
40
|
|
46
|
-
|
41
|
+
// Electron logs a benign warning about WebSwapCGLLayer on MacOS v12 and Electron v18 due to a naming collision in shared libraries.
|
47
42
|
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/33685
|
48
43
|
// Sample:
|
49
44
|
// objc[60540]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffa5a006318) and /{path/to/app}/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x10f8a89c8). One of the two will be used. Which one is undefined.
|
50
|
-
|
51
45
|
const isMacOSElectronWebSwapCGLLayerWarning = /^objc\[\d+\]: Class WebSwapCGLLayer is implemented in both.*Which one is undefined\./;
|
52
46
|
const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe, isDbusWarning, isCertVerifyProcBuiltin, isMacOSElectronWebSwapCGLLayerWarning];
|
53
|
-
|
54
47
|
const isGarbageLineWarning = str => {
|
55
48
|
return _.some(GARBAGE_WARNINGS, re => {
|
56
49
|
return re.test(str);
|
57
50
|
});
|
58
51
|
};
|
59
|
-
|
60
52
|
function isPlatform(platform) {
|
61
53
|
return os.platform() === platform;
|
62
54
|
}
|
63
|
-
|
64
55
|
function needsStderrPiped(needsXvfb) {
|
65
56
|
return _.some([isPlatform('darwin'), needsXvfb && isPlatform('linux'), util.isPossibleLinuxWithIncorrectDisplay()]);
|
66
57
|
}
|
67
|
-
|
68
58
|
function needsEverythingPipedDirectly() {
|
69
59
|
return isPlatform('win32');
|
70
60
|
}
|
71
|
-
|
72
61
|
function getStdio(needsXvfb) {
|
73
62
|
if (needsEverythingPipedDirectly()) {
|
74
63
|
return 'pipe';
|
75
|
-
}
|
64
|
+
}
|
65
|
+
|
66
|
+
// https://github.com/cypress-io/cypress/issues/921
|
76
67
|
// https://github.com/cypress-io/cypress/issues/1143
|
77
68
|
// https://github.com/cypress-io/cypress/issues/1745
|
78
|
-
|
79
|
-
|
80
69
|
if (needsStderrPiped(needsXvfb)) {
|
81
70
|
// returning pipe here so we can massage stderr
|
82
71
|
// and remove garbage from Xlib and libuv
|
83
72
|
// due to starting the Xvfb process on linux
|
84
73
|
return ['inherit', 'inherit', 'pipe'];
|
85
74
|
}
|
86
|
-
|
87
75
|
return 'inherit';
|
88
76
|
}
|
89
|
-
|
90
77
|
module.exports = {
|
91
78
|
isGarbageLineWarning,
|
92
|
-
|
93
79
|
start(args, options = {}) {
|
94
80
|
const needsXvfb = xvfb.isNeeded();
|
95
81
|
let executable = state.getPathToExecutable(state.getBinaryDir());
|
96
|
-
|
97
82
|
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
98
83
|
executable = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
99
84
|
}
|
85
|
+
debug('needs to start own Xvfb?', needsXvfb);
|
100
86
|
|
101
|
-
|
87
|
+
// Always push cwd into the args
|
102
88
|
// which additionally acts as a signal to the
|
103
89
|
// binary that it was invoked through the NPM module
|
104
|
-
|
105
90
|
args = args || [];
|
106
|
-
|
107
91
|
if (typeof args === 'string') {
|
108
92
|
args = [args];
|
109
93
|
}
|
110
|
-
|
111
94
|
args = [...args, '--cwd', process.cwd(), '--userNodePath', process.execPath, '--userNodeVersion', process.versions.node];
|
112
|
-
|
113
95
|
_.defaults(options, {
|
114
96
|
dev: false,
|
115
97
|
env: process.env,
|
116
98
|
detached: false,
|
117
99
|
stdio: getStdio(needsXvfb)
|
118
100
|
});
|
119
|
-
|
120
101
|
const spawn = (overrides = {}) => {
|
121
102
|
return new Promise((resolve, reject) => {
|
122
103
|
_.defaults(overrides, {
|
123
104
|
onStderrData: false,
|
124
105
|
electronLogging: false
|
125
106
|
});
|
126
|
-
|
127
107
|
const {
|
128
108
|
onStderrData,
|
129
109
|
electronLogging
|
@@ -132,46 +112,39 @@ module.exports = {
|
|
132
112
|
const electronArgs = [];
|
133
113
|
const node11WindowsFix = isPlatform('win32');
|
134
114
|
let startScriptPath;
|
135
|
-
|
136
115
|
if (options.dev) {
|
137
|
-
executable = 'node';
|
116
|
+
executable = 'node';
|
117
|
+
// if we're in dev then reset
|
138
118
|
// the launch cmd to be 'npm run dev'
|
139
|
-
|
140
119
|
startScriptPath = path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'), debug('in dev mode the args became %o', args);
|
141
120
|
}
|
142
|
-
|
143
121
|
if (!options.dev && verify.needsSandbox()) {
|
144
122
|
electronArgs.push('--no-sandbox');
|
145
|
-
}
|
123
|
+
}
|
146
124
|
|
125
|
+
// strip dev out of child process options
|
147
126
|
/**
|
148
127
|
* @type {import('child_process').ForkOptions}
|
149
128
|
*/
|
129
|
+
let stdioOptions = _.pick(options, 'env', 'detached', 'stdio');
|
150
130
|
|
151
|
-
|
152
|
-
let stdioOptions = _.pick(options, 'env', 'detached', 'stdio'); // figure out if we're going to be force enabling or disabling colors.
|
131
|
+
// figure out if we're going to be force enabling or disabling colors.
|
153
132
|
// also figure out whether we should force stdout and stderr into thinking
|
154
133
|
// it is a tty as opposed to a pipe.
|
155
|
-
|
156
|
-
|
157
134
|
stdioOptions.env = _.extend({}, stdioOptions.env, envOverrides);
|
158
|
-
|
159
135
|
if (node11WindowsFix) {
|
160
136
|
stdioOptions = _.extend({}, stdioOptions, {
|
161
137
|
windowsHide: false
|
162
138
|
});
|
163
139
|
}
|
164
|
-
|
165
140
|
if (electronLogging) {
|
166
141
|
stdioOptions.env.ELECTRON_ENABLE_LOGGING = true;
|
167
142
|
}
|
168
|
-
|
169
143
|
if (util.isPossibleLinuxWithIncorrectDisplay()) {
|
170
144
|
// make sure we use the latest DISPLAY variable if any
|
171
145
|
debug('passing DISPLAY', process.env.DISPLAY);
|
172
146
|
stdioOptions.env.DISPLAY = process.env.DISPLAY;
|
173
147
|
}
|
174
|
-
|
175
148
|
if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
|
176
149
|
// Since we are running electron as node, we need to add an entry point file.
|
177
150
|
startScriptPath = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
|
@@ -182,19 +155,15 @@ module.exports = {
|
|
182
155
|
// https://github.com/cypress-io/cypress/issues/5466
|
183
156
|
args = [...electronArgs, '--', ...args];
|
184
157
|
}
|
185
|
-
|
186
158
|
if (startScriptPath) {
|
187
159
|
args.unshift(startScriptPath);
|
188
160
|
}
|
189
|
-
|
190
161
|
if (process.env.CYPRESS_INTERNAL_DEV_DEBUG) {
|
191
162
|
args.unshift(process.env.CYPRESS_INTERNAL_DEV_DEBUG);
|
192
163
|
}
|
193
|
-
|
194
164
|
debug('spawn args %o %o', args, _.omit(stdioOptions, 'env'));
|
195
165
|
debug('spawning Cypress with executable: %s', executable);
|
196
166
|
const child = cp.spawn(executable, args, stdioOptions);
|
197
|
-
|
198
167
|
function resolveOn(event) {
|
199
168
|
return function (code, signal) {
|
200
169
|
debug('child event fired %o', {
|
@@ -202,131 +171,119 @@ module.exports = {
|
|
202
171
|
code,
|
203
172
|
signal
|
204
173
|
});
|
205
|
-
|
206
174
|
if (code === null) {
|
207
175
|
const errorObject = errors.errors.childProcessKilled(event, signal);
|
208
176
|
return errors.getError(errorObject).then(reject);
|
209
177
|
}
|
210
|
-
|
211
178
|
resolve(code);
|
212
179
|
};
|
213
180
|
}
|
214
|
-
|
215
181
|
child.on('close', resolveOn('close'));
|
216
182
|
child.on('exit', resolveOn('exit'));
|
217
|
-
child.on('error', reject);
|
183
|
+
child.on('error', reject);
|
184
|
+
|
185
|
+
// if stdio options is set to 'pipe', then
|
218
186
|
// we should set up pipes:
|
219
187
|
// process STDIN (read stream) => child STDIN (writeable)
|
220
188
|
// child STDOUT => process STDOUT
|
221
189
|
// child STDERR => process STDERR with additional filtering
|
222
|
-
|
223
190
|
if (child.stdin) {
|
224
191
|
debug('piping process STDIN into child STDIN');
|
225
192
|
process.stdin.pipe(child.stdin);
|
226
193
|
}
|
227
|
-
|
228
194
|
if (child.stdout) {
|
229
195
|
debug('piping child STDOUT to process STDOUT');
|
230
196
|
child.stdout.pipe(process.stdout);
|
231
|
-
}
|
232
|
-
// to filter out the garbage
|
233
|
-
|
197
|
+
}
|
234
198
|
|
199
|
+
// if this is defined then we are manually piping for linux
|
200
|
+
// to filter out the garbage
|
235
201
|
if (child.stderr) {
|
236
202
|
debug('piping child STDERR to process STDERR');
|
237
203
|
child.stderr.on('data', data => {
|
238
|
-
const str = data.toString();
|
204
|
+
const str = data.toString();
|
239
205
|
|
206
|
+
// bail if this is warning line garbage
|
240
207
|
if (isGarbageLineWarning(str)) {
|
241
208
|
return;
|
242
|
-
}
|
243
|
-
// false then bail
|
244
|
-
|
209
|
+
}
|
245
210
|
|
211
|
+
// if we have a callback and this explictly returns
|
212
|
+
// false then bail
|
246
213
|
if (onStderrData && onStderrData(str) === false) {
|
247
214
|
return;
|
248
|
-
}
|
249
|
-
|
215
|
+
}
|
250
216
|
|
217
|
+
// else pass it along!
|
251
218
|
process.stderr.write(data);
|
252
219
|
});
|
253
|
-
}
|
220
|
+
}
|
221
|
+
|
222
|
+
// https://github.com/cypress-io/cypress/issues/1841
|
254
223
|
// https://github.com/cypress-io/cypress/issues/5241
|
255
224
|
// In some versions of node, it will throw on windows
|
256
225
|
// when you close the parent process after piping
|
257
226
|
// into the child process. unpiping does not seem
|
258
227
|
// to have any effect. so we're just catching the
|
259
228
|
// error here and not doing anything.
|
260
|
-
|
261
|
-
|
262
229
|
process.stdin.on('error', err => {
|
263
230
|
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
|
264
231
|
return;
|
265
232
|
}
|
266
|
-
|
267
233
|
throw err;
|
268
234
|
});
|
269
|
-
|
270
235
|
if (stdioOptions.detached) {
|
271
236
|
child.unref();
|
272
237
|
}
|
273
238
|
});
|
274
239
|
};
|
275
|
-
|
276
240
|
const spawnInXvfb = () => {
|
277
241
|
return xvfb.start().then(userFriendlySpawn).finally(xvfb.stop);
|
278
242
|
};
|
279
|
-
|
280
243
|
const userFriendlySpawn = linuxWithDisplayEnv => {
|
281
244
|
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
|
282
245
|
let brokenGtkDisplay;
|
283
246
|
const overrides = {};
|
284
|
-
|
285
247
|
if (linuxWithDisplayEnv) {
|
286
248
|
_.extend(overrides, {
|
287
249
|
electronLogging: true,
|
288
|
-
|
289
250
|
onStderrData(str) {
|
290
251
|
// if we receive a broken pipe anywhere
|
291
252
|
// then we know that's why cypress exited early
|
292
253
|
if (util.isBrokenGtkDisplay(str)) {
|
293
254
|
brokenGtkDisplay = true;
|
294
|
-
}
|
255
|
+
}
|
256
|
+
|
257
|
+
// we should attempt to always slurp up
|
295
258
|
// the stderr logs unless we've explicitly
|
296
259
|
// enabled the electron debug logging
|
297
|
-
|
298
|
-
|
299
260
|
if (!debugElectron.enabled) {
|
300
261
|
return false;
|
301
262
|
}
|
302
263
|
}
|
303
|
-
|
304
264
|
});
|
305
265
|
}
|
306
|
-
|
307
266
|
return spawn(overrides).then(code => {
|
308
267
|
if (code !== 0 && brokenGtkDisplay) {
|
309
268
|
util.logBrokenGtkDisplayWarning();
|
310
269
|
return spawnInXvfb();
|
311
270
|
}
|
312
|
-
|
313
271
|
return code;
|
314
|
-
})
|
272
|
+
})
|
273
|
+
// we can format and handle an error message from the code above
|
315
274
|
// prevent wrapping error again by using "known: undefined" filter
|
316
275
|
.catch({
|
317
276
|
known: undefined
|
318
277
|
}, errors.throwFormErrorText(errors.errors.unexpected));
|
319
278
|
};
|
320
|
-
|
321
279
|
if (needsXvfb) {
|
322
280
|
return spawnInXvfb();
|
323
|
-
}
|
281
|
+
}
|
282
|
+
|
283
|
+
// if we are on linux and there's already a DISPLAY
|
324
284
|
// set, then we may need to rerun cypress after
|
325
285
|
// spawning our own Xvfb server
|
326
|
-
|
327
|
-
|
328
286
|
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
329
287
|
return userFriendlySpawn(linuxWithDisplayEnv);
|
330
288
|
}
|
331
|
-
|
332
289
|
};
|
package/lib/exec/versions.js
CHANGED
@@ -1,20 +1,14 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
const Promise = require('bluebird');
|
4
|
-
|
5
4
|
const debug = require('debug')('cypress:cli');
|
6
|
-
|
7
5
|
const path = require('path');
|
8
|
-
|
9
6
|
const util = require('../util');
|
10
|
-
|
11
7
|
const state = require('../tasks/state');
|
12
|
-
|
13
8
|
const {
|
14
9
|
throwFormErrorText,
|
15
10
|
errors
|
16
11
|
} = require('../errors');
|
17
|
-
|
18
12
|
const getVersions = () => {
|
19
13
|
return Promise.try(() => {
|
20
14
|
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
@@ -23,7 +17,6 @@ const getVersions = () => {
|
|
23
17
|
if (!envBinaryDir) {
|
24
18
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
|
25
19
|
}
|
26
|
-
|
27
20
|
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
28
21
|
return envBinaryDir;
|
29
22
|
}).catch({
|
@@ -32,7 +25,6 @@ const getVersions = () => {
|
|
32
25
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
|
33
26
|
});
|
34
27
|
}
|
35
|
-
|
36
28
|
return state.getBinaryDir();
|
37
29
|
}).then(state.getBinaryPkgAsync).then(pkg => {
|
38
30
|
const versions = {
|
@@ -56,7 +48,6 @@ const getVersions = () => {
|
|
56
48
|
return versions;
|
57
49
|
});
|
58
50
|
};
|
59
|
-
|
60
51
|
module.exports = {
|
61
52
|
getVersions
|
62
53
|
};
|
package/lib/exec/xvfb.js
CHANGED
@@ -1,24 +1,17 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
const os = require('os');
|
4
|
-
|
5
4
|
const Promise = require('bluebird');
|
6
|
-
|
7
5
|
const Xvfb = require('@cypress/xvfb');
|
8
|
-
|
9
6
|
const {
|
10
7
|
stripIndent
|
11
8
|
} = require('common-tags');
|
12
|
-
|
13
9
|
const Debug = require('debug');
|
14
|
-
|
15
10
|
const {
|
16
11
|
throwFormErrorText,
|
17
12
|
errors
|
18
13
|
} = require('../errors');
|
19
|
-
|
20
14
|
const util = require('../util');
|
21
|
-
|
22
15
|
const debug = Debug('cypress:cli');
|
23
16
|
const debugXvfb = Debug('cypress:xvfb');
|
24
17
|
debug.Debug = debugXvfb.Debug = Debug;
|
@@ -29,23 +22,23 @@ const xvfbOptions = {
|
|
29
22
|
// need to explicitly define screen otherwise electron will crash
|
30
23
|
// https://github.com/cypress-io/cypress/issues/6184
|
31
24
|
xvfb_args: ['-screen', '0', '1280x1024x24'],
|
32
|
-
|
33
25
|
onStderrData(data) {
|
34
26
|
if (debugXvfb.enabled) {
|
35
27
|
debugXvfb(data.toString());
|
36
28
|
}
|
37
29
|
}
|
38
|
-
|
39
30
|
};
|
40
31
|
const xvfb = Promise.promisifyAll(new Xvfb(xvfbOptions));
|
41
32
|
module.exports = {
|
42
33
|
_debugXvfb: debugXvfb,
|
43
34
|
// expose for testing
|
35
|
+
|
44
36
|
_xvfb: xvfb,
|
45
37
|
// expose for testing
|
46
|
-
_xvfbOptions: xvfbOptions,
|
47
38
|
|
39
|
+
_xvfbOptions: xvfbOptions,
|
48
40
|
// expose for testing
|
41
|
+
|
49
42
|
start() {
|
50
43
|
debug('Starting Xvfb');
|
51
44
|
return xvfb.startAsync().return(null).catch({
|
@@ -54,17 +47,15 @@ module.exports = {
|
|
54
47
|
if (err.known) {
|
55
48
|
throw err;
|
56
49
|
}
|
57
|
-
|
58
50
|
return throwFormErrorText(errors.missingXvfb)(err);
|
59
51
|
});
|
60
52
|
},
|
61
|
-
|
62
53
|
stop() {
|
63
54
|
debug('Stopping Xvfb');
|
64
|
-
return xvfb.stopAsync().return(null).catch(() => {
|
55
|
+
return xvfb.stopAsync().return(null).catch(() => {
|
56
|
+
// noop
|
65
57
|
});
|
66
58
|
},
|
67
|
-
|
68
59
|
isNeeded() {
|
69
60
|
if (process.env.ELECTRON_RUN_AS_NODE) {
|
70
61
|
debug('Environment variable ELECTRON_RUN_AS_NODE detected, xvfb is not needed');
|
@@ -74,7 +65,6 @@ module.exports = {
|
|
74
65
|
if (os.platform() !== 'linux') {
|
75
66
|
return false;
|
76
67
|
}
|
77
|
-
|
78
68
|
if (process.env.DISPLAY) {
|
79
69
|
const issueUrl = util.getGitHubIssueUrl(4034);
|
80
70
|
const message = stripIndent`
|
@@ -90,12 +80,10 @@ module.exports = {
|
|
90
80
|
debug(message);
|
91
81
|
return false;
|
92
82
|
}
|
93
|
-
|
94
83
|
debug('undefined DISPLAY environment variable');
|
95
84
|
debug('Cypress will spawn its own Xvfb');
|
96
85
|
return true;
|
97
86
|
},
|
98
|
-
|
99
87
|
// async method, resolved with Boolean
|
100
88
|
verify() {
|
101
89
|
return xvfb.startAsync().return(true).catch(err => {
|
@@ -103,5 +91,4 @@ module.exports = {
|
|
103
91
|
return false;
|
104
92
|
}).finally(xvfb.stopAsync);
|
105
93
|
}
|
106
|
-
|
107
94
|
};
|
package/lib/fs.js
CHANGED
package/lib/logger.js
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
const chalk = require('chalk');
|
4
|
-
|
5
4
|
let logs = [];
|
6
|
-
|
7
5
|
const logLevel = () => {
|
8
6
|
return process.env.npm_config_loglevel || 'notice';
|
9
7
|
};
|
10
|
-
|
11
8
|
const error = (...messages) => {
|
12
9
|
logs.push(messages.join(' '));
|
13
10
|
console.log(chalk.red(...messages)); // eslint-disable-line no-console
|
@@ -28,26 +25,22 @@ const log = (...messages) => {
|
|
28
25
|
const always = (...messages) => {
|
29
26
|
logs.push(messages.join(' '));
|
30
27
|
console.log(...messages); // eslint-disable-line no-console
|
31
|
-
};
|
32
|
-
// on each one to allow easy unit testing for specific message
|
33
|
-
|
28
|
+
};
|
34
29
|
|
30
|
+
// splits long text into lines and calls log()
|
31
|
+
// on each one to allow easy unit testing for specific message
|
35
32
|
const logLines = text => {
|
36
33
|
const lines = text.split('\n');
|
37
|
-
|
38
34
|
for (const line of lines) {
|
39
35
|
log(line);
|
40
36
|
}
|
41
37
|
};
|
42
|
-
|
43
38
|
const print = () => {
|
44
39
|
return logs.join('\n');
|
45
40
|
};
|
46
|
-
|
47
41
|
const reset = () => {
|
48
42
|
logs = [];
|
49
43
|
};
|
50
|
-
|
51
44
|
module.exports = {
|
52
45
|
log,
|
53
46
|
warn,
|