cypress 5.1.0 → 5.5.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 +114 -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 +225 -161
- 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 +3 -3
- package/types/cypress-npm-api.d.ts +13 -5
- package/types/cypress.d.ts +51 -48
- package/types/mocha/index.d.ts +123 -308
- package/types/net-stubbing.ts +169 -19
package/lib/tasks/verify.js
CHANGED
@@ -1,119 +1,71 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
4
|
-
var data = _taggedTemplateLiteral(["\n\n\n ", " Warning: Binary version ", " does not match the expected package version ", "\n\n These versions may not work properly together.\n "]);
|
3
|
+
const _ = require('lodash');
|
5
4
|
|
6
|
-
|
7
|
-
return data;
|
8
|
-
};
|
5
|
+
const chalk = require('chalk');
|
9
6
|
|
10
|
-
|
11
|
-
}
|
7
|
+
const Listr = require('listr');
|
12
8
|
|
13
|
-
|
14
|
-
var data = _taggedTemplateLiteral(["\n The supplied binary path is not executable\n "]);
|
9
|
+
const debug = require('debug')('cypress:cli');
|
15
10
|
|
16
|
-
|
17
|
-
return data;
|
18
|
-
};
|
19
|
-
|
20
|
-
return data;
|
21
|
-
}
|
11
|
+
const verbose = require('@cypress/listr-verbose-renderer');
|
22
12
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
_templateObject3 = function _templateObject3() {
|
27
|
-
return data;
|
28
|
-
};
|
29
|
-
|
30
|
-
return data;
|
31
|
-
}
|
13
|
+
const {
|
14
|
+
stripIndent
|
15
|
+
} = require('common-tags');
|
32
16
|
|
33
|
-
|
34
|
-
var data = _taggedTemplateLiteral(["\n It looks like this is your first time using Cypress: ", "\n "]);
|
17
|
+
const Promise = require('bluebird');
|
35
18
|
|
36
|
-
|
37
|
-
return data;
|
38
|
-
};
|
39
|
-
|
40
|
-
return data;
|
41
|
-
}
|
42
|
-
|
43
|
-
function _templateObject() {
|
44
|
-
var data = _taggedTemplateLiteral(["\n Cypress executable not found at: ", "\n "]);
|
45
|
-
|
46
|
-
_templateObject = function _templateObject() {
|
47
|
-
return data;
|
48
|
-
};
|
49
|
-
|
50
|
-
return data;
|
51
|
-
}
|
19
|
+
const logSymbols = require('log-symbols');
|
52
20
|
|
53
|
-
|
21
|
+
const path = require('path');
|
54
22
|
|
55
|
-
|
23
|
+
const os = require('os');
|
56
24
|
|
57
|
-
|
25
|
+
const {
|
26
|
+
throwFormErrorText,
|
27
|
+
errors
|
28
|
+
} = require('../errors');
|
58
29
|
|
59
|
-
|
30
|
+
const util = require('../util');
|
60
31
|
|
61
|
-
|
32
|
+
const logger = require('../logger');
|
62
33
|
|
63
|
-
|
34
|
+
const xvfb = require('../exec/xvfb');
|
64
35
|
|
65
|
-
|
66
|
-
stripIndent = _require.stripIndent;
|
36
|
+
const state = require('./state');
|
67
37
|
|
68
|
-
|
38
|
+
const VERIFY_TEST_RUNNER_TIMEOUT_MS = 30000;
|
69
39
|
|
70
|
-
|
71
|
-
|
72
|
-
var path = require('path');
|
73
|
-
|
74
|
-
var os = require('os');
|
75
|
-
|
76
|
-
var _require2 = require('../errors'),
|
77
|
-
throwFormErrorText = _require2.throwFormErrorText,
|
78
|
-
errors = _require2.errors;
|
79
|
-
|
80
|
-
var util = require('../util');
|
81
|
-
|
82
|
-
var logger = require('../logger');
|
83
|
-
|
84
|
-
var xvfb = require('../exec/xvfb');
|
85
|
-
|
86
|
-
var state = require('./state');
|
87
|
-
|
88
|
-
var VERIFY_TEST_RUNNER_TIMEOUT_MS = 30000;
|
89
|
-
|
90
|
-
var checkExecutable = function checkExecutable(binaryDir) {
|
91
|
-
var executable = state.getPathToExecutable(binaryDir);
|
40
|
+
const checkExecutable = binaryDir => {
|
41
|
+
const executable = state.getPathToExecutable(binaryDir);
|
92
42
|
debug('checking if executable exists', executable);
|
93
|
-
return util.isExecutableAsync(executable).then(
|
43
|
+
return util.isExecutableAsync(executable).then(isExecutable => {
|
94
44
|
debug('Binary is executable? :', isExecutable);
|
95
45
|
|
96
46
|
if (!isExecutable) {
|
97
47
|
return throwFormErrorText(errors.binaryNotExecutable(executable))();
|
98
48
|
}
|
99
|
-
})
|
49
|
+
}).catch({
|
100
50
|
code: 'ENOENT'
|
101
|
-
},
|
51
|
+
}, () => {
|
102
52
|
if (util.isCi()) {
|
103
53
|
return throwFormErrorText(errors.notInstalledCI(executable))();
|
104
54
|
}
|
105
55
|
|
106
|
-
return throwFormErrorText(errors.missingApp(binaryDir))(stripIndent
|
56
|
+
return throwFormErrorText(errors.missingApp(binaryDir))(stripIndent`
|
57
|
+
Cypress executable not found at: ${chalk.cyan(executable)}
|
58
|
+
`);
|
107
59
|
});
|
108
60
|
};
|
109
61
|
|
110
|
-
|
111
|
-
|
62
|
+
const runSmokeTest = (binaryDir, options) => {
|
63
|
+
let executable = state.getPathToExecutable(binaryDir);
|
112
64
|
|
113
|
-
|
114
|
-
return
|
65
|
+
const onSmokeTestError = (smokeTestCommand, linuxWithDisplayEnv) => {
|
66
|
+
return err => {
|
115
67
|
debug('Smoke test failed:', err);
|
116
|
-
|
68
|
+
let errMessage = err.stderr || err.message;
|
117
69
|
debug('error message:', errMessage);
|
118
70
|
|
119
71
|
if (err.timedOut) {
|
@@ -130,17 +82,17 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
130
82
|
};
|
131
83
|
};
|
132
84
|
|
133
|
-
|
85
|
+
const needsXvfb = xvfb.isNeeded();
|
134
86
|
debug('needs Xvfb?', needsXvfb);
|
135
87
|
/**
|
136
88
|
* Spawn Cypress running smoke test to check if all operating system
|
137
89
|
* dependencies are good.
|
138
90
|
*/
|
139
91
|
|
140
|
-
|
141
|
-
|
92
|
+
const spawn = linuxWithDisplayEnv => {
|
93
|
+
const random = _.random(0, 1000);
|
142
94
|
|
143
|
-
|
95
|
+
const args = ['--smoke-test', `--ping=${random}`];
|
144
96
|
|
145
97
|
if (needsSandbox()) {
|
146
98
|
// electron requires --no-sandbox to run as root
|
@@ -153,51 +105,51 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
153
105
|
args.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
|
154
106
|
}
|
155
107
|
|
156
|
-
|
108
|
+
const smokeTestCommand = `${executable} ${args.join(' ')}`;
|
157
109
|
debug('running smoke test');
|
158
110
|
debug('using Cypress executable %s', executable);
|
159
111
|
debug('smoke test command:', smokeTestCommand);
|
160
112
|
debug('smoke test timeout %d ms', options.smokeTestTimeout);
|
161
113
|
|
162
|
-
|
114
|
+
const env = _.extend({}, process.env, {
|
163
115
|
ELECTRON_ENABLE_LOGGING: true
|
164
116
|
});
|
165
117
|
|
166
|
-
|
167
|
-
env
|
118
|
+
const stdioOptions = _.extend({}, {
|
119
|
+
env,
|
168
120
|
timeout: options.smokeTestTimeout
|
169
121
|
});
|
170
122
|
|
171
|
-
return Promise.resolve(util.exec(executable, args, stdioOptions))
|
123
|
+
return Promise.resolve(util.exec(executable, args, stdioOptions)).catch(onSmokeTestError(smokeTestCommand, linuxWithDisplayEnv)).then(result => {
|
172
124
|
// TODO: when execa > 1.1 is released
|
173
125
|
// change this to `result.all` for both stderr and stdout
|
174
126
|
// use lodash to be robust during tests against null result or missing stdout
|
175
|
-
|
127
|
+
const smokeTestStdout = _.get(result, 'stdout', '');
|
176
128
|
|
177
129
|
debug('smoke test stdout "%s"', smokeTestStdout);
|
178
130
|
|
179
131
|
if (!util.stdoutLineMatches(String(random), smokeTestStdout)) {
|
180
132
|
debug('Smoke test failed because could not find %d in:', random, result);
|
181
133
|
|
182
|
-
|
134
|
+
const smokeTestStderr = _.get(result, 'stderr', '');
|
183
135
|
|
184
|
-
|
136
|
+
const errorText = smokeTestStderr || smokeTestStdout;
|
185
137
|
return throwFormErrorText(errors.smokeTestFailure(smokeTestCommand, false))(errorText);
|
186
138
|
}
|
187
139
|
});
|
188
140
|
};
|
189
141
|
|
190
|
-
|
191
|
-
return xvfb.start().then(
|
142
|
+
const spawnInXvfb = linuxWithDisplayEnv => {
|
143
|
+
return xvfb.start().then(() => {
|
192
144
|
return spawn(linuxWithDisplayEnv);
|
193
|
-
})
|
145
|
+
}).finally(xvfb.stop);
|
194
146
|
};
|
195
147
|
|
196
|
-
|
148
|
+
const userFriendlySpawn = linuxWithDisplayEnv => {
|
197
149
|
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
|
198
|
-
return spawn(linuxWithDisplayEnv)
|
150
|
+
return spawn(linuxWithDisplayEnv).catch({
|
199
151
|
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR'
|
200
|
-
},
|
152
|
+
}, () => {
|
201
153
|
return spawnInXvfb(linuxWithDisplayEnv);
|
202
154
|
});
|
203
155
|
};
|
@@ -209,7 +161,7 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
209
161
|
// spawning our own Xvfb server
|
210
162
|
|
211
163
|
|
212
|
-
|
164
|
+
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
213
165
|
return userFriendlySpawn(linuxWithDisplayEnv);
|
214
166
|
};
|
215
167
|
|
@@ -217,40 +169,42 @@ function testBinary(version, binaryDir, options) {
|
|
217
169
|
debug('running binary verification check', version); // if running from 'cypress verify', don't print this message
|
218
170
|
|
219
171
|
if (!options.force) {
|
220
|
-
logger.log(stripIndent
|
172
|
+
logger.log(stripIndent`
|
173
|
+
It looks like this is your first time using Cypress: ${chalk.cyan(version)}
|
174
|
+
`);
|
221
175
|
}
|
222
176
|
|
223
177
|
logger.log(); // if we are running in CI then use
|
224
178
|
// the verbose renderer else use
|
225
179
|
// the default
|
226
180
|
|
227
|
-
|
181
|
+
let renderer = util.isCi() ? verbose : 'default';
|
228
182
|
if (logger.logLevel() === 'silent') renderer = 'silent';
|
229
|
-
|
230
|
-
renderer
|
183
|
+
const rendererOptions = {
|
184
|
+
renderer
|
231
185
|
};
|
232
|
-
|
186
|
+
const tasks = new Listr([{
|
233
187
|
title: util.titleize('Verifying Cypress can run', chalk.gray(binaryDir)),
|
234
|
-
task:
|
188
|
+
task: (ctx, task) => {
|
235
189
|
debug('clearing out the verified version');
|
236
|
-
return state.clearBinaryStateAsync(binaryDir).then(
|
190
|
+
return state.clearBinaryStateAsync(binaryDir).then(() => {
|
237
191
|
return Promise.all([runSmokeTest(binaryDir, options), Promise.resolve().delay(1500) // good user experience
|
238
192
|
]);
|
239
|
-
}).then(
|
193
|
+
}).then(() => {
|
240
194
|
debug('write verified: true');
|
241
195
|
return state.writeBinaryVerifiedAsync(true, binaryDir);
|
242
|
-
}).then(
|
243
|
-
util.setTaskTitle(
|
196
|
+
}).then(() => {
|
197
|
+
util.setTaskTitle(task, util.titleize(chalk.green('Verified Cypress!'), chalk.gray(binaryDir)), rendererOptions.renderer);
|
244
198
|
});
|
245
199
|
}
|
246
200
|
}], rendererOptions);
|
247
201
|
return tasks.run();
|
248
202
|
}
|
249
203
|
|
250
|
-
|
251
|
-
return state.getBinaryVerifiedAsync(binaryDir).then(
|
204
|
+
const maybeVerify = (installedVersion, binaryDir, options) => {
|
205
|
+
return state.getBinaryVerifiedAsync(binaryDir).then(isVerified => {
|
252
206
|
debug('is Verified ?', isVerified);
|
253
|
-
|
207
|
+
let shouldVerify = !isVerified; // force verify if options.force
|
254
208
|
|
255
209
|
if (options.force) {
|
256
210
|
debug('force verify');
|
@@ -258,7 +212,7 @@ var maybeVerify = function maybeVerify(installedVersion, binaryDir, options) {
|
|
258
212
|
}
|
259
213
|
|
260
214
|
if (shouldVerify) {
|
261
|
-
return testBinary(installedVersion, binaryDir, options).then(
|
215
|
+
return testBinary(installedVersion, binaryDir, options).then(() => {
|
262
216
|
if (options.welcomeMessage) {
|
263
217
|
logger.log();
|
264
218
|
logger.log('Opening Cypress...');
|
@@ -268,11 +222,10 @@ var maybeVerify = function maybeVerify(installedVersion, binaryDir, options) {
|
|
268
222
|
});
|
269
223
|
};
|
270
224
|
|
271
|
-
|
272
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
225
|
+
const start = (options = {}) => {
|
273
226
|
debug('verifying Cypress app');
|
274
|
-
|
275
|
-
|
227
|
+
const packageVersion = util.pkgVersion();
|
228
|
+
let binaryDir = state.getBinaryDir(packageVersion);
|
276
229
|
|
277
230
|
_.defaults(options, {
|
278
231
|
dev: false,
|
@@ -285,64 +238,80 @@ var start = function start() {
|
|
285
238
|
return runSmokeTest('', options);
|
286
239
|
}
|
287
240
|
|
288
|
-
|
289
|
-
|
241
|
+
const parseBinaryEnvVar = () => {
|
242
|
+
const envBinaryPath = util.getEnv('CYPRESS_RUN_BINARY');
|
290
243
|
debug('CYPRESS_RUN_BINARY exists, =', envBinaryPath);
|
291
|
-
logger.log(stripIndent
|
244
|
+
logger.log(stripIndent`
|
245
|
+
${chalk.yellow('Note:')} You have set the environment variable:
|
246
|
+
|
247
|
+
${chalk.white('CYPRESS_RUN_BINARY=')}${chalk.cyan(envBinaryPath)}
|
248
|
+
|
249
|
+
This overrides the default Cypress binary path used.
|
250
|
+
`);
|
292
251
|
logger.log();
|
293
|
-
return util.isExecutableAsync(envBinaryPath).then(
|
252
|
+
return util.isExecutableAsync(envBinaryPath).then(isExecutable => {
|
294
253
|
debug('CYPRESS_RUN_BINARY is executable? :', isExecutable);
|
295
254
|
|
296
255
|
if (!isExecutable) {
|
297
|
-
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(stripIndent
|
256
|
+
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(stripIndent`
|
257
|
+
The supplied binary path is not executable
|
258
|
+
`);
|
298
259
|
}
|
299
|
-
}).then(
|
260
|
+
}).then(() => {
|
300
261
|
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath);
|
301
|
-
}).then(
|
262
|
+
}).then(envBinaryDir => {
|
302
263
|
if (!envBinaryDir) {
|
303
264
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
|
304
265
|
}
|
305
266
|
|
306
267
|
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
307
268
|
binaryDir = envBinaryDir;
|
308
|
-
})
|
269
|
+
}).catch({
|
309
270
|
code: 'ENOENT'
|
310
|
-
},
|
271
|
+
}, err => {
|
311
272
|
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
|
312
273
|
});
|
313
274
|
};
|
314
275
|
|
315
|
-
return Promise
|
276
|
+
return Promise.try(() => {
|
316
277
|
debug('checking environment variables');
|
317
278
|
|
318
279
|
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
319
280
|
return parseBinaryEnvVar();
|
320
281
|
}
|
321
|
-
}).then(
|
282
|
+
}).then(() => {
|
322
283
|
return checkExecutable(binaryDir);
|
323
|
-
}).tap(
|
284
|
+
}).tap(() => {
|
324
285
|
return debug('binaryDir is ', binaryDir);
|
325
|
-
}).then(
|
286
|
+
}).then(() => {
|
326
287
|
return state.getBinaryPkgVersionAsync(binaryDir);
|
327
|
-
}).then(
|
288
|
+
}).then(binaryVersion => {
|
328
289
|
if (!binaryVersion) {
|
329
290
|
debug('no Cypress binary found for cli version ', packageVersion);
|
330
|
-
return throwFormErrorText(errors.missingApp(binaryDir))(
|
291
|
+
return throwFormErrorText(errors.missingApp(binaryDir))(`
|
292
|
+
Cannot read binary version from: ${chalk.cyan(state.getBinaryPkgPath(binaryDir))}
|
293
|
+
`);
|
331
294
|
}
|
332
295
|
|
333
|
-
debug(
|
296
|
+
debug(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
|
334
297
|
|
335
298
|
if (binaryVersion !== packageVersion) {
|
336
299
|
// warn if we installed with CYPRESS_INSTALL_BINARY or changed version
|
337
300
|
// in the package.json
|
338
|
-
logger.log(
|
301
|
+
logger.log(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
|
339
302
|
logger.log();
|
340
|
-
logger.warn(stripIndent
|
303
|
+
logger.warn(stripIndent`
|
304
|
+
|
305
|
+
|
306
|
+
${logSymbols.warning} Warning: Binary version ${chalk.green(binaryVersion)} does not match the expected package version ${chalk.green(packageVersion)}
|
307
|
+
|
308
|
+
These versions may not work properly together.
|
309
|
+
`);
|
341
310
|
logger.log();
|
342
311
|
}
|
343
312
|
|
344
313
|
return maybeVerify(binaryVersion, binaryDir, options);
|
345
|
-
})
|
314
|
+
}).catch(err => {
|
346
315
|
if (err.known) {
|
347
316
|
throw err;
|
348
317
|
}
|
@@ -351,9 +320,7 @@ var start = function start() {
|
|
351
320
|
});
|
352
321
|
};
|
353
322
|
|
354
|
-
|
355
|
-
return os.platform() !== 'win32';
|
356
|
-
};
|
323
|
+
const isLinuxLike = () => os.platform() !== 'win32';
|
357
324
|
/**
|
358
325
|
* Returns true if running on a system where Electron needs "--no-sandbox" flag.
|
359
326
|
* @see https://crbug.com/638180
|
@@ -365,12 +332,10 @@ var isLinuxLike = function isLinuxLike() {
|
|
365
332
|
*/
|
366
333
|
|
367
334
|
|
368
|
-
|
369
|
-
return isLinuxLike();
|
370
|
-
};
|
335
|
+
const needsSandbox = () => isLinuxLike();
|
371
336
|
|
372
337
|
module.exports = {
|
373
|
-
start
|
374
|
-
VERIFY_TEST_RUNNER_TIMEOUT_MS
|
375
|
-
needsSandbox
|
338
|
+
start,
|
339
|
+
VERIFY_TEST_RUNNER_TIMEOUT_MS,
|
340
|
+
needsSandbox
|
376
341
|
};
|