cypress 3.3.0 → 3.4.1
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/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
|
};
|