cypress 12.1.0 → 12.2.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 +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 +7 -14
- package/react/package.json +1 -1
- package/react18/dist/cypress-react.cjs.js +6 -12
- package/react18/package.json +1 -1
- package/svelte/dist/cypress-svelte.cjs.js +0 -2
- package/types/cypress.d.ts +6 -6
- package/types/net-stubbing.d.ts +11 -0
- package/vue/dist/cypress-vue.cjs.js +3 -6
- package/vue/package.json +1 -1
- package/vue2/dist/cypress-vue2.cjs.js +18 -27
- package/vue2/dist/cypress-vue2.esm-bundler.js +0 -3
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,
|