cypress 3.3.0 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/cli.js +3 -0
- package/lib/errors.js +36 -35
- package/lib/exec/spawn.js +9 -4
- package/lib/exec/xvfb.js +4 -4
- package/lib/tasks/download.js +124 -15
- package/lib/tasks/install.js +10 -3
- package/lib/tasks/verify.js +19 -7
- package/lib/util.js +95 -15
- package/package.json +16 -17
- package/types/blob-util/package.json +51 -0
- package/types/bluebird/package.json +51 -0
- package/types/chai/package.json +81 -0
- package/types/chai-jquery/package.json +55 -0
- package/types/cy-chai.d.ts +5 -7
- package/types/index.d.ts +231 -13
- package/types/jquery/package.json +132 -0
- package/types/lodash/package.json +85 -0
- package/types/minimatch/package.json +56 -0
- package/types/mocha/README.md +5 -5
- package/types/mocha/index.d.ts +2986 -241
- package/types/mocha/package.json +73 -0
- package/types/sinon/package.json +88 -0
- package/types/sinon-chai/index.d.ts +1 -1
- package/types/sinon-chai/package.json +63 -0
package/lib/cli.js
CHANGED
@@ -38,6 +38,7 @@ var coerceFalse = function coerceFalse(arg) {
|
|
38
38
|
var spaceDelimitedSpecsMsg = function spaceDelimitedSpecsMsg(files) {
|
39
39
|
logger.log();
|
40
40
|
logger.warn(stripIndent(_templateObject, logSymbols.warning, files.join(' ')));
|
41
|
+
|
41
42
|
logger.log();
|
42
43
|
};
|
43
44
|
|
@@ -143,6 +144,8 @@ module.exports = {
|
|
143
144
|
// in usage help docs
|
144
145
|
program._name = 'cypress';
|
145
146
|
|
147
|
+
program.usage('<command> [options]');
|
148
|
+
|
146
149
|
program.command('help').description('Shows CLI help and exits').action(function () {
|
147
150
|
program.help();
|
148
151
|
});
|
package/lib/errors.js
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var _templateObject = _taggedTemplateLiteral(['\n
|
4
|
-
_templateObject2 = _taggedTemplateLiteral(['\n
|
5
|
-
_templateObject3 = _taggedTemplateLiteral(['\n
|
6
|
-
_templateObject4 = _taggedTemplateLiteral(['\n\n
|
7
|
-
_templateObject5 = _taggedTemplateLiteral(['\n
|
8
|
-
_templateObject6 = _taggedTemplateLiteral(['\n
|
9
|
-
_templateObject7 = _taggedTemplateLiteral(['\n
|
10
|
-
_templateObject8 = _taggedTemplateLiteral(['\n
|
11
|
-
_templateObject9 = _taggedTemplateLiteral(['\n
|
12
|
-
_templateObject10 = _taggedTemplateLiteral(['\n
|
13
|
-
_templateObject11 = _taggedTemplateLiteral(['\n
|
14
|
-
_templateObject12 = _taggedTemplateLiteral(['\n
|
15
|
-
_templateObject13 = _taggedTemplateLiteral(['\n
|
16
|
-
_templateObject14 = _taggedTemplateLiteral(['\n
|
17
|
-
_templateObject15 = _taggedTemplateLiteral(['\n
|
18
|
-
_templateObject16 = _taggedTemplateLiteral(['\n
|
3
|
+
var _templateObject = _taggedTemplateLiteral(['\n Does your workplace require a proxy to be used to access the Internet? If so, you must configure the HTTP_PROXY environment variable before downloading Cypress. Read more: https://on.cypress.io/proxy-configuration\n\n Otherwise, please check network connectivity and try again:'], ['\n Does your workplace require a proxy to be used to access the Internet? If so, you must configure the HTTP_PROXY environment variable before downloading Cypress. Read more: https://on.cypress.io/proxy-configuration\n\n Otherwise, please check network connectivity and try again:']),
|
4
|
+
_templateObject2 = _taggedTemplateLiteral(['\n Search for an existing issue or open a GitHub issue at\n\n ', '\n '], ['\n Search for an existing issue or open a GitHub issue at\n\n ', '\n ']),
|
5
|
+
_templateObject3 = _taggedTemplateLiteral(['\n \nPlease reinstall Cypress by running: ', '\n '], ['\n \\nPlease reinstall Cypress by running: ', '\n ']),
|
6
|
+
_templateObject4 = _taggedTemplateLiteral(['\n\n Reasons this may happen:\n\n - node was installed as \'root\' or with \'sudo\'\n - the cypress npm package as \'root\' or with \'sudo\'\n\n Please check that you have the appropriate user permissions.\n '], ['\\n\n Reasons this may happen:\n\n - node was installed as \'root\' or with \'sudo\'\n - the cypress npm package as \'root\' or with \'sudo\'\n\n Please check that you have the appropriate user permissions.\n ']),
|
7
|
+
_templateObject5 = _taggedTemplateLiteral(['\n\n We expected the binary to be installed here: ', '\n\n Reasons it may be missing:\n\n - You\'re caching \'node_modules\' but are not caching this path: ', '\n - You ran \'npm install\' at an earlier build step but did not persist: ', '\n\n Properly caching the binary will fix this error and avoid downloading and unzipping Cypress.\n\n Alternatively, you can run \'cypress install\' to download the binary again.\n\n ', '\n '], ['\\n\n We expected the binary to be installed here: ', '\n\n Reasons it may be missing:\n\n - You\'re caching \'node_modules\' but are not caching this path: ', '\n - You ran \'npm install\' at an earlier build step but did not persist: ', '\n\n Properly caching the binary will fix this error and avoid downloading and unzipping Cypress.\n\n Alternatively, you can run \'cypress install\' to download the binary again.\n\n ', '\n ']),
|
8
|
+
_templateObject6 = _taggedTemplateLiteral(['\n There was a problem spawning Xvfb.\n\n This is likely a problem with your system, permissions, or installation of Xvfb.\n '], ['\n There was a problem spawning Xvfb.\n\n This is likely a problem with your system, permissions, or installation of Xvfb.\n ']),
|
9
|
+
_templateObject7 = _taggedTemplateLiteral(['\n Install Xvfb and run Cypress again.\n\n Read our documentation on dependencies for more information:\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n '], ['\n Install Xvfb and run Cypress again.\n\n Read our documentation on dependencies for more information:\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n ']),
|
10
|
+
_templateObject8 = _taggedTemplateLiteral(['\n This command failed with the following output:\n\n ', '\n\n '], ['\n This command failed with the following output:\n\n ', '\n\n ']),
|
11
|
+
_templateObject9 = _taggedTemplateLiteral(['\n Cypress failed to start after spawning a new Xvfb server.\n\n The error logs we received were:\n\n ', '\n\n ', '\n\n ', '\n\n This is usually caused by a missing library or dependency.\n\n The error above should indicate which dependency is missing.\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n '], ['\n Cypress failed to start after spawning a new Xvfb server.\n\n The error logs we received were:\n\n ', '\n\n ', '\n\n ', '\n\n This is usually caused by a missing library or dependency.\n\n The error above should indicate which dependency is missing.\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n ']),
|
12
|
+
_templateObject10 = _taggedTemplateLiteral(['\n This is usually caused by a missing library or dependency.\n\n The error below should indicate which dependency is missing.\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n '], ['\n This is usually caused by a missing library or dependency.\n\n The error below should indicate which dependency is missing.\n\n ', '\n\n If you are using Docker, we provide containers with all required dependencies installed.\n ']),
|
13
|
+
_templateObject11 = _taggedTemplateLiteral(['\n See discussion and possible solutions at\n ', '\n '], ['\n See discussion and possible solutions at\n ', '\n ']),
|
14
|
+
_templateObject12 = _taggedTemplateLiteral(['\n Please search Cypress documentation for possible solutions:\n\n ', '\n\n Check if there is a GitHub issue describing this crash:\n\n ', '\n\n Consider opening a new issue.\n '], ['\n Please search Cypress documentation for possible solutions:\n\n ', '\n\n Check if there is a GitHub issue describing this crash:\n\n ', '\n\n Consider opening a new issue.\n ']),
|
15
|
+
_templateObject13 = _taggedTemplateLiteral(['\n The environment variable CYPRESS_BINARY_VERSION has been renamed to CYPRESS_INSTALL_BINARY as of version ', '\n '], ['\n The environment variable CYPRESS_BINARY_VERSION has been renamed to CYPRESS_INSTALL_BINARY as of version ', '\n ']),
|
16
|
+
_templateObject14 = _taggedTemplateLiteral(['\n You should set CYPRESS_INSTALL_BINARY instead.\n '], ['\n You should set CYPRESS_INSTALL_BINARY instead.\n ']),
|
17
|
+
_templateObject15 = _taggedTemplateLiteral(['\n The environment variable CYPRESS_SKIP_BINARY_INSTALL has been removed as of version ', '\n '], ['\n The environment variable CYPRESS_SKIP_BINARY_INSTALL has been removed as of version ', '\n ']),
|
18
|
+
_templateObject16 = _taggedTemplateLiteral(['\n To skip the binary install, set CYPRESS_INSTALL_BINARY=0\n '], ['\n To skip the binary install, set CYPRESS_INSTALL_BINARY=0\n ']),
|
19
|
+
_templateObject17 = _taggedTemplateLiteral(['\n Platform: ', ' (', ')\n Cypress Version: ', '\n '], ['\n Platform: ', ' (', ')\n Cypress Version: ', '\n ']);
|
19
20
|
|
20
21
|
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
21
22
|
|
@@ -46,49 +47,49 @@ var hr = '----------';
|
|
46
47
|
// common errors Cypress application can encounter
|
47
48
|
var failedDownload = {
|
48
49
|
description: 'The Cypress App could not be downloaded.',
|
49
|
-
solution:
|
50
|
+
solution: stripIndent(_templateObject)
|
50
51
|
};
|
51
52
|
|
52
53
|
var failedUnzip = {
|
53
54
|
description: 'The Cypress App could not be unzipped.',
|
54
|
-
solution: stripIndent(
|
55
|
+
solution: stripIndent(_templateObject2, chalk.blue(util.issuesUrl))
|
55
56
|
};
|
56
57
|
|
57
58
|
var missingApp = function missingApp(binaryDir) {
|
58
59
|
return {
|
59
60
|
description: 'No version of Cypress is installed in: ' + chalk.cyan(binaryDir),
|
60
|
-
solution: stripIndent(
|
61
|
+
solution: stripIndent(_templateObject3, chalk.cyan('cypress install'))
|
61
62
|
};
|
62
63
|
};
|
63
64
|
|
64
65
|
var binaryNotExecutable = function binaryNotExecutable(executable) {
|
65
66
|
return {
|
66
67
|
description: 'Cypress cannot run because this binary file does not have executable permissions here:\n\n' + executable,
|
67
|
-
solution: stripIndent(
|
68
|
+
solution: stripIndent(_templateObject4)
|
68
69
|
};
|
69
70
|
};
|
70
71
|
|
71
72
|
var notInstalledCI = function notInstalledCI(executable) {
|
72
73
|
return {
|
73
74
|
description: 'The cypress npm package is installed, but the Cypress binary is missing.',
|
74
|
-
solution: stripIndent(
|
75
|
+
solution: stripIndent(_templateObject5, chalk.cyan(executable), util.getCacheDir(), util.getCacheDir(), chalk.blue('https://on.cypress.io/not-installed-ci-error'))
|
75
76
|
};
|
76
77
|
};
|
77
78
|
|
78
79
|
var nonZeroExitCodeXvfb = {
|
79
|
-
description: '
|
80
|
-
solution: stripIndent(
|
80
|
+
description: 'Xvfb exited with a non zero exit code.',
|
81
|
+
solution: stripIndent(_templateObject6)
|
81
82
|
};
|
82
83
|
|
83
84
|
var missingXvfb = {
|
84
|
-
description: 'Your system is missing the dependency:
|
85
|
-
solution: stripIndent(
|
85
|
+
description: 'Your system is missing the dependency: Xvfb',
|
86
|
+
solution: stripIndent(_templateObject7, chalk.blue(requiredDependenciesUrl))
|
86
87
|
};
|
87
88
|
|
88
89
|
var smokeTestFailure = function smokeTestFailure(smokeTestCommand, timedOut) {
|
89
90
|
return {
|
90
91
|
description: 'Cypress verification ' + (timedOut ? 'timed out' : 'failed') + '.',
|
91
|
-
solution: stripIndent(
|
92
|
+
solution: stripIndent(_templateObject8, smokeTestCommand)
|
92
93
|
};
|
93
94
|
};
|
94
95
|
|
@@ -96,19 +97,19 @@ var invalidSmokeTestDisplayError = {
|
|
96
97
|
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR',
|
97
98
|
description: 'Cypress verification failed.',
|
98
99
|
solution: function solution(msg) {
|
99
|
-
return stripIndent(
|
100
|
+
return stripIndent(_templateObject9, hr, msg, hr, chalk.blue(requiredDependenciesUrl));
|
100
101
|
}
|
101
102
|
};
|
102
103
|
|
103
104
|
var missingDependency = {
|
104
105
|
description: 'Cypress failed to start.',
|
105
106
|
// this message is too Linux specific
|
106
|
-
solution: stripIndent(
|
107
|
+
solution: stripIndent(_templateObject10, chalk.blue(requiredDependenciesUrl))
|
107
108
|
};
|
108
109
|
|
109
110
|
var invalidCacheDirectory = {
|
110
111
|
description: 'Cypress cannot write to the cache directory due to file permissions',
|
111
|
-
solution: stripIndent(
|
112
|
+
solution: stripIndent(_templateObject11, chalk.blue(util.getGitHubIssueUrl(1281)))
|
112
113
|
};
|
113
114
|
|
114
115
|
var versionMismatch = {
|
@@ -118,17 +119,17 @@ var versionMismatch = {
|
|
118
119
|
|
119
120
|
var unexpected = {
|
120
121
|
description: 'An unexpected error occurred while verifying the Cypress executable.',
|
121
|
-
solution: stripIndent(
|
122
|
+
solution: stripIndent(_templateObject12, chalk.blue(docsUrl), chalk.blue(util.issuesUrl))
|
122
123
|
};
|
123
124
|
|
124
125
|
var removed = {
|
125
126
|
CYPRESS_BINARY_VERSION: {
|
126
|
-
description: stripIndent(
|
127
|
-
solution: stripIndent(
|
127
|
+
description: stripIndent(_templateObject13, chalk.green('3.0.0')),
|
128
|
+
solution: stripIndent(_templateObject14)
|
128
129
|
},
|
129
130
|
CYPRESS_SKIP_BINARY_INSTALL: {
|
130
|
-
description: stripIndent(
|
131
|
-
solution: stripIndent(
|
131
|
+
description: stripIndent(_templateObject15, chalk.green('3.0.0')),
|
132
|
+
solution: stripIndent(_templateObject16)
|
132
133
|
}
|
133
134
|
};
|
134
135
|
|
@@ -145,7 +146,7 @@ var CYPRESS_RUN_BINARY = {
|
|
145
146
|
|
146
147
|
function getPlatformInfo() {
|
147
148
|
return util.getOsVersionAsync().then(function (version) {
|
148
|
-
return stripIndent(
|
149
|
+
return stripIndent(_templateObject17, os.platform(), version, util.pkgVersion());
|
149
150
|
});
|
150
151
|
}
|
151
152
|
|
package/lib/exec/spawn.js
CHANGED
@@ -18,8 +18,9 @@ var _require = require('../errors'),
|
|
18
18
|
|
19
19
|
var isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
|
20
20
|
var isHighSierraWarningRe = /\*\*\* WARNING/;
|
21
|
+
var isRenderWorkerRe = /\.RenderWorker-/;
|
21
22
|
|
22
|
-
var GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe];
|
23
|
+
var GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe];
|
23
24
|
|
24
25
|
var isGarbageLineWarning = function isGarbageLineWarning(str) {
|
25
26
|
return _.some(GARBAGE_WARNINGS, function (re) {
|
@@ -50,7 +51,7 @@ function getStdio(needsXvfb) {
|
|
50
51
|
if (needsStderrPiped(needsXvfb)) {
|
51
52
|
// returning pipe here so we can massage stderr
|
52
53
|
// and remove garbage from Xlib and libuv
|
53
|
-
// due to starting the
|
54
|
+
// due to starting the Xvfb process on linux
|
54
55
|
return ['inherit', 'inherit', 'pipe'];
|
55
56
|
}
|
56
57
|
|
@@ -58,6 +59,8 @@ function getStdio(needsXvfb) {
|
|
58
59
|
}
|
59
60
|
|
60
61
|
module.exports = {
|
62
|
+
isGarbageLineWarning: isGarbageLineWarning,
|
63
|
+
|
61
64
|
start: function start(args) {
|
62
65
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
63
66
|
|
@@ -68,9 +71,11 @@ module.exports = {
|
|
68
71
|
executable = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
69
72
|
}
|
70
73
|
|
71
|
-
debug('needs to start own
|
74
|
+
debug('needs to start own Xvfb?', needsXvfb);
|
72
75
|
|
73
76
|
// always push cwd into the args
|
77
|
+
// which additionally acts as a signal to the
|
78
|
+
// binary that it was invoked through the NPM module
|
74
79
|
args = [].concat(args, '--cwd', process.cwd());
|
75
80
|
|
76
81
|
_.defaults(options, {
|
@@ -224,7 +229,7 @@ module.exports = {
|
|
224
229
|
|
225
230
|
// if we are on linux and there's already a DISPLAY
|
226
231
|
// set, then we may need to rerun cypress after
|
227
|
-
// spawning our own
|
232
|
+
// spawning our own Xvfb server
|
228
233
|
var linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
229
234
|
|
230
235
|
return userFriendlySpawn(linuxWithDisplayEnv);
|
package/lib/exec/xvfb.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var _templateObject = _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
|
3
|
+
var _templateObject = _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 '], ['\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 ']);
|
4
4
|
|
5
5
|
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
6
6
|
|
@@ -35,7 +35,7 @@ module.exports = {
|
|
35
35
|
_xvfb: xvfb, // expose for testing
|
36
36
|
|
37
37
|
start: function start() {
|
38
|
-
debug('Starting
|
38
|
+
debug('Starting Xvfb');
|
39
39
|
|
40
40
|
return xvfb.startAsync().return(null).catch({ nonZeroExitCode: true }, throwFormErrorText(errors.nonZeroExitCodeXvfb)).catch(function (err) {
|
41
41
|
if (err.known) {
|
@@ -46,7 +46,7 @@ module.exports = {
|
|
46
46
|
});
|
47
47
|
},
|
48
48
|
stop: function stop() {
|
49
|
-
debug('Stopping
|
49
|
+
debug('Stopping Xvfb');
|
50
50
|
|
51
51
|
return xvfb.stopAsync().return(null).catch(function () {
|
52
52
|
// noop
|
@@ -68,7 +68,7 @@ module.exports = {
|
|
68
68
|
}
|
69
69
|
|
70
70
|
debug('undefined DISPLAY environment variable');
|
71
|
-
debug('Cypress will spawn its own
|
71
|
+
debug('Cypress will spawn its own Xvfb');
|
72
72
|
|
73
73
|
return true;
|
74
74
|
},
|
package/lib/tasks/download.js
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var _arguments = arguments;
|
4
|
-
|
5
3
|
var _templateObject = _taggedTemplateLiteral(['\n URL: ', '\n ', '\n '], ['\n URL: ', '\n ', '\n ']),
|
6
|
-
_templateObject2 = _taggedTemplateLiteral(['\n
|
4
|
+
_templateObject2 = _taggedTemplateLiteral(['\n Corrupted download\n\n Expected downloaded file to have checksum: ', '\n Computed checksum: ', '\n\n Expected downloaded file to have size: ', '\n Computed size: ', '\n '], ['\n Corrupted download\n\n Expected downloaded file to have checksum: ', '\n Computed checksum: ', '\n\n Expected downloaded file to have size: ', '\n Computed size: ', '\n ']),
|
5
|
+
_templateObject3 = _taggedTemplateLiteral(['\n Corrupted download\n\n Expected downloaded file to have checksum: ', '\n Computed checksum: ', '\n '], ['\n Corrupted download\n\n Expected downloaded file to have checksum: ', '\n Computed checksum: ', '\n ']),
|
6
|
+
_templateObject4 = _taggedTemplateLiteral(['\n Corrupted download\n\n Expected downloaded file to have size: ', '\n Computed size: ', '\n '], ['\n Corrupted download\n\n Expected downloaded file to have size: ', '\n Computed size: ', '\n ']),
|
7
|
+
_templateObject5 = _taggedTemplateLiteral(['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n '], ['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n ']);
|
7
8
|
|
8
9
|
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
9
10
|
|
@@ -30,6 +31,10 @@ var util = require('../util');
|
|
30
31
|
|
31
32
|
var defaultBaseUrl = 'https://download.cypress.io/';
|
32
33
|
|
34
|
+
var getProxyUrl = function getProxyUrl() {
|
35
|
+
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.npm_config_https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || process.env.npm_config_proxy || null;
|
36
|
+
};
|
37
|
+
|
33
38
|
var getRealOsArch = function getRealOsArch() {
|
34
39
|
// os.arch() returns the arch for which this node was compiled
|
35
40
|
// we want the operating system's arch instead: x64 or x86
|
@@ -88,6 +93,71 @@ var prettyDownloadErr = function prettyDownloadErr(err, version) {
|
|
88
93
|
return throwFormErrorText(errors.failedDownload)(msg);
|
89
94
|
};
|
90
95
|
|
96
|
+
/**
|
97
|
+
* Checks checksum and file size for the given file. Allows both
|
98
|
+
* values or just one of them to be checked.
|
99
|
+
*/
|
100
|
+
var verifyDownloadedFile = function verifyDownloadedFile(filename, expectedSize, expectedChecksum) {
|
101
|
+
if (expectedSize && expectedChecksum) {
|
102
|
+
debug('verifying checksum and file size');
|
103
|
+
|
104
|
+
return Promise.join(util.getFileChecksum(filename), util.getFileSize(filename), function (checksum, filesize) {
|
105
|
+
if (checksum === expectedChecksum && filesize === expectedSize) {
|
106
|
+
debug('downloaded file has the expected checksum and size ✅');
|
107
|
+
|
108
|
+
return;
|
109
|
+
}
|
110
|
+
|
111
|
+
debug('raising error: checksum or file size mismatch');
|
112
|
+
var text = stripIndent(_templateObject2, expectedChecksum, checksum, expectedSize, filesize);
|
113
|
+
|
114
|
+
debug(text);
|
115
|
+
|
116
|
+
throw new Error(text);
|
117
|
+
});
|
118
|
+
}
|
119
|
+
|
120
|
+
if (expectedChecksum) {
|
121
|
+
debug('only checking expected file checksum %d', expectedChecksum);
|
122
|
+
|
123
|
+
return util.getFileChecksum(filename).then(function (checksum) {
|
124
|
+
if (checksum === expectedChecksum) {
|
125
|
+
debug('downloaded file has the expected checksum ✅');
|
126
|
+
|
127
|
+
return;
|
128
|
+
}
|
129
|
+
|
130
|
+
debug('raising error: file checksum mismatch');
|
131
|
+
var text = stripIndent(_templateObject3, expectedChecksum, checksum);
|
132
|
+
|
133
|
+
throw new Error(text);
|
134
|
+
});
|
135
|
+
}
|
136
|
+
|
137
|
+
if (expectedSize) {
|
138
|
+
// maybe we don't have a checksum, but at least CDN returns content length
|
139
|
+
// which we can check against the file size
|
140
|
+
debug('only checking expected file size %d', expectedSize);
|
141
|
+
|
142
|
+
return util.getFileSize(filename).then(function (filesize) {
|
143
|
+
if (filesize === expectedSize) {
|
144
|
+
debug('downloaded file has the expected size ✅');
|
145
|
+
|
146
|
+
return;
|
147
|
+
}
|
148
|
+
|
149
|
+
debug('raising error: file size mismatch');
|
150
|
+
var text = stripIndent(_templateObject4, expectedSize, filesize);
|
151
|
+
|
152
|
+
throw new Error(text);
|
153
|
+
});
|
154
|
+
}
|
155
|
+
|
156
|
+
debug('downloaded file lacks checksum or size to verify');
|
157
|
+
|
158
|
+
return Promise.resolve();
|
159
|
+
};
|
160
|
+
|
91
161
|
// downloads from given url
|
92
162
|
// return an object with
|
93
163
|
// {filename: ..., downloaded: true}
|
@@ -97,13 +167,19 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
97
167
|
progress = _ref.progress;
|
98
168
|
|
99
169
|
return new Promise(function (resolve, reject) {
|
100
|
-
|
101
|
-
|
170
|
+
var proxy = getProxyUrl();
|
171
|
+
|
172
|
+
debug('Downloading package', {
|
173
|
+
url: url,
|
174
|
+
proxy: proxy,
|
175
|
+
downloadDestination: downloadDestination
|
176
|
+
});
|
102
177
|
|
103
178
|
var redirectVersion = void 0;
|
104
179
|
|
105
180
|
var req = request({
|
106
181
|
url: url,
|
182
|
+
proxy: proxy,
|
107
183
|
followRedirect: function followRedirect(response) {
|
108
184
|
var version = response.headers['x-version'];
|
109
185
|
|
@@ -122,10 +198,30 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
122
198
|
|
123
199
|
// closure
|
124
200
|
var started = null;
|
201
|
+
var expectedSize = void 0;
|
202
|
+
var expectedChecksum = void 0;
|
125
203
|
|
126
204
|
requestProgress(req, {
|
127
205
|
throttle: progress.throttle
|
128
206
|
}).on('response', function (response) {
|
207
|
+
// we have computed checksum and filesize during test runner binary build
|
208
|
+
// and have set it on the S3 object as user meta data, available via
|
209
|
+
// these custom headers "x-amz-meta-..."
|
210
|
+
// see https://github.com/cypress-io/cypress/pull/4092
|
211
|
+
expectedSize = response.headers['x-amz-meta-size'] || response.headers['content-length'];
|
212
|
+
|
213
|
+
expectedChecksum = response.headers['x-amz-meta-checksum'];
|
214
|
+
|
215
|
+
if (expectedChecksum) {
|
216
|
+
debug('expected checksum %s', expectedChecksum);
|
217
|
+
}
|
218
|
+
|
219
|
+
if (expectedSize) {
|
220
|
+
// convert from string (all Amazon custom headers are strings)
|
221
|
+
expectedSize = Number(expectedSize);
|
222
|
+
debug('expected file size %d', expectedSize);
|
223
|
+
}
|
224
|
+
|
129
225
|
// start counting now once we've gotten
|
130
226
|
// response headers
|
131
227
|
started = new Date();
|
@@ -134,7 +230,7 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
134
230
|
if (!/^2/.test(response.statusCode)) {
|
135
231
|
debug('response code %d', response.statusCode);
|
136
232
|
|
137
|
-
var err = new Error(stripIndent(
|
233
|
+
var err = new Error(stripIndent(_templateObject5, response.statusCode, response.statusMessage));
|
138
234
|
|
139
235
|
reject(err);
|
140
236
|
}
|
@@ -143,27 +239,38 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
143
239
|
// starting on our first progress notification
|
144
240
|
var elapsed = new Date() - started;
|
145
241
|
|
146
|
-
|
242
|
+
// request-progress sends a value between 0 and 1
|
243
|
+
var percentage = util.convertPercentToPercentage(state.percent);
|
244
|
+
|
245
|
+
var eta = util.calculateEta(percentage, elapsed);
|
147
246
|
|
148
247
|
// send up our percent and seconds remaining
|
149
|
-
progress.onProgress(
|
248
|
+
progress.onProgress(percentage, util.secsRemaining(eta));
|
150
249
|
})
|
151
250
|
// save this download here
|
152
251
|
.pipe(fs.createWriteStream(downloadDestination)).on('finish', function () {
|
153
252
|
debug('downloading finished');
|
154
253
|
|
155
|
-
|
254
|
+
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(function () {
|
255
|
+
return resolve(redirectVersion);
|
256
|
+
}, reject);
|
156
257
|
});
|
157
258
|
});
|
158
259
|
};
|
159
260
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
261
|
+
/**
|
262
|
+
* Download Cypress.zip from external url to local file.
|
263
|
+
* @param [string] version Could be "3.3.0" or full URL
|
264
|
+
* @param [string] downloadDestination Local filename to save as
|
265
|
+
*/
|
266
|
+
var start = function start(opts) {
|
267
|
+
var version = opts.version,
|
268
|
+
downloadDestination = opts.downloadDestination,
|
269
|
+
progress = opts.progress;
|
270
|
+
|
164
271
|
|
165
272
|
if (!downloadDestination) {
|
166
|
-
la(is.unemptyString(downloadDestination), 'missing download dir',
|
273
|
+
la(is.unemptyString(downloadDestination), 'missing download dir', opts);
|
167
274
|
}
|
168
275
|
|
169
276
|
if (!progress) {
|
@@ -177,6 +284,7 @@ var start = function start(_ref2) {
|
|
177
284
|
progress.throttle = 100;
|
178
285
|
|
179
286
|
debug('needed Cypress version: %s', version);
|
287
|
+
debug('source url %s', url);
|
180
288
|
debug('downloading cypress.zip to "' + downloadDestination + '"');
|
181
289
|
|
182
290
|
// ensure download dir exists
|
@@ -189,5 +297,6 @@ var start = function start(_ref2) {
|
|
189
297
|
|
190
298
|
module.exports = {
|
191
299
|
start: start,
|
192
|
-
getUrl: getUrl
|
300
|
+
getUrl: getUrl,
|
301
|
+
getProxyUrl: getProxyUrl
|
193
302
|
};
|
package/lib/tasks/install.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var _templateObject = _taggedTemplateLiteral(['
|
3
|
+
var _templateObject = _taggedTemplateLiteral(['\n Skipping installation:\n\n Pass the ', ' option if you\'d like to reinstall anyway.\n '], ['\n Skipping installation:\n\n Pass the ', ' option if you\'d like to reinstall anyway.\n ']),
|
4
4
|
_templateObject2 = _taggedTemplateLiteral(['\n ', ' Warning: It looks like you\'ve installed Cypress globally.\n\n This will work, but it\'s not recommended.\n\n The recommended way to install Cypress is as a devDependency per project.\n\n You should probably run these commands:\n\n - ', '\n - ', '\n '], ['\n ', ' Warning: It looks like you\\\'ve installed Cypress globally.\n\n This will work, but it\'\\s not recommended.\n\n The recommended way to install Cypress is as a devDependency per project.\n\n You should probably run these commands:\n\n - ', '\n - ', '\n ']),
|
5
5
|
_templateObject3 = _taggedTemplateLiteral(['\n ', ' Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.'], ['\n ', ' Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.']),
|
6
6
|
_templateObject4 = _taggedTemplateLiteral(['\n ', ' Overriding Cypress cache directory to: ', '\n\n Previous installs of Cypress may not be found.\n '], ['\n ', ' Overriding Cypress cache directory to: ', '\n\n Previous installs of Cypress may not be found.\n ']),
|
@@ -144,13 +144,17 @@ var start = function start() {
|
|
144
144
|
// let this environment variable reset the binary version we need
|
145
145
|
if (util.getEnv('CYPRESS_INSTALL_BINARY')) {
|
146
146
|
|
147
|
-
|
147
|
+
// because passed file paths are often double quoted
|
148
|
+
// and might have extra whitespace around, be robust and trim the string
|
149
|
+
var trimAndRemoveDoubleQuotes = true;
|
150
|
+
var envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
|
148
151
|
|
149
|
-
debug('using environment variable CYPRESS_INSTALL_BINARY %s', envVarVersion);
|
152
|
+
debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
|
150
153
|
|
151
154
|
if (envVarVersion === '0') {
|
152
155
|
debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
|
153
156
|
logger.log(stripIndent(_templateObject3, chalk.yellow('Note:')));
|
157
|
+
|
154
158
|
logger.log();
|
155
159
|
|
156
160
|
return Promise.resolve();
|
@@ -169,6 +173,7 @@ var start = function start() {
|
|
169
173
|
var envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
|
170
174
|
|
171
175
|
logger.log(stripIndent(_templateObject4, chalk.yellow('Note:'), chalk.cyan(envCache)));
|
176
|
+
|
172
177
|
logger.log();
|
173
178
|
}
|
174
179
|
|
@@ -192,6 +197,7 @@ var start = function start() {
|
|
192
197
|
|
193
198
|
logger.log();
|
194
199
|
logger.log(stripIndent(_templateObject6, chalk.green(binaryVersion), chalk.cyan(installDir)));
|
200
|
+
|
195
201
|
logger.log();
|
196
202
|
|
197
203
|
if (options.force) {
|
@@ -218,6 +224,7 @@ var start = function start() {
|
|
218
224
|
|
219
225
|
if (needVersion !== pkgVersion) {
|
220
226
|
logger.log(chalk.yellow(stripIndent(_templateObject7, logSymbols.warning, chalk.green(pkgVersion), chalk.green(needVersion))));
|
227
|
+
|
221
228
|
logger.log();
|
222
229
|
}
|
223
230
|
|
package/lib/tasks/verify.js
CHANGED
@@ -30,6 +30,8 @@ var logger = require('../logger');
|
|
30
30
|
var xvfb = require('../exec/xvfb');
|
31
31
|
var state = require('./state');
|
32
32
|
|
33
|
+
var VERIFY_TEST_RUNNER_TIMEOUT_MS = 30000;
|
34
|
+
|
33
35
|
var checkExecutable = function checkExecutable(binaryDir) {
|
34
36
|
var executable = state.getPathToExecutable(binaryDir);
|
35
37
|
|
@@ -78,7 +80,7 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
78
80
|
|
79
81
|
var needsXvfb = xvfb.isNeeded();
|
80
82
|
|
81
|
-
debug('needs
|
83
|
+
debug('needs Xvfb?', needsXvfb);
|
82
84
|
|
83
85
|
/**
|
84
86
|
* Spawn Cypress running smoke test to check if all operating system
|
@@ -88,8 +90,6 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
88
90
|
var random = _.random(0, 1000);
|
89
91
|
var args = ['--smoke-test', '--ping=' + random];
|
90
92
|
|
91
|
-
process.env.ELECTRON_ENABLE_LOGGING = true;
|
92
|
-
|
93
93
|
if (options.dev) {
|
94
94
|
executable = 'node';
|
95
95
|
args.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
|
@@ -100,8 +100,18 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
100
100
|
debug('running smoke test');
|
101
101
|
debug('using Cypress executable %s', executable);
|
102
102
|
debug('smoke test command:', smokeTestCommand);
|
103
|
+
debug('smoke test timeout %d ms', options.smokeTestTimeout);
|
104
|
+
|
105
|
+
var env = _.extend({}, process.env, {
|
106
|
+
ELECTRON_ENABLE_LOGGING: true
|
107
|
+
});
|
103
108
|
|
104
|
-
|
109
|
+
var stdioOptions = _.extend({}, {
|
110
|
+
env: env,
|
111
|
+
timeout: options.smokeTestTimeout
|
112
|
+
});
|
113
|
+
|
114
|
+
return Promise.resolve(util.exec(executable, args, stdioOptions)).catch(onSmokeTestError(smokeTestCommand, linuxWithDisplayEnv)).then(function (result) {
|
105
115
|
// TODO: when execa > 1.1 is released
|
106
116
|
// change this to `result.all` for both stderr and stdout
|
107
117
|
var smokeTestReturned = result.stdout;
|
@@ -136,7 +146,7 @@ var runSmokeTest = function runSmokeTest(binaryDir, options) {
|
|
136
146
|
|
137
147
|
// if we are on linux and there's already a DISPLAY
|
138
148
|
// set, then we may need to rerun cypress after
|
139
|
-
// spawning our own
|
149
|
+
// spawning our own Xvfb server
|
140
150
|
var linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
141
151
|
|
142
152
|
return userFriendlySpawn(linuxWithDisplayEnv);
|
@@ -217,7 +227,7 @@ var start = function start() {
|
|
217
227
|
dev: false,
|
218
228
|
force: false,
|
219
229
|
welcomeMessage: true,
|
220
|
-
smokeTestTimeout:
|
230
|
+
smokeTestTimeout: VERIFY_TEST_RUNNER_TIMEOUT_MS
|
221
231
|
});
|
222
232
|
|
223
233
|
if (options.dev) {
|
@@ -229,6 +239,7 @@ var start = function start() {
|
|
229
239
|
|
230
240
|
debug('CYPRESS_RUN_BINARY exists, =', envBinaryPath);
|
231
241
|
logger.log(stripIndent(_templateObject3, chalk.yellow('Note:'), chalk.white('CYPRESS_RUN_BINARY='), chalk.cyan(envBinaryPath)));
|
242
|
+
|
232
243
|
logger.log();
|
233
244
|
|
234
245
|
return util.isExecutableAsync(envBinaryPath).then(function (isExecutable) {
|
@@ -293,5 +304,6 @@ var start = function start() {
|
|
293
304
|
};
|
294
305
|
|
295
306
|
module.exports = {
|
296
|
-
start: start
|
307
|
+
start: start,
|
308
|
+
VERIFY_TEST_RUNNER_TIMEOUT_MS: VERIFY_TEST_RUNNER_TIMEOUT_MS
|
297
309
|
};
|