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 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 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 ']),
4
- _templateObject2 = _taggedTemplateLiteral(['\n \nPlease reinstall Cypress by running: ', '\n '], ['\n \\nPlease reinstall Cypress by running: ', '\n ']),
5
- _templateObject3 = _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 ']),
6
- _templateObject4 = _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 ']),
7
- _templateObject5 = _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 ']),
8
- _templateObject6 = _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 ']),
9
- _templateObject7 = _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 ']),
10
- _templateObject8 = _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 ']),
11
- _templateObject9 = _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 ']),
12
- _templateObject10 = _taggedTemplateLiteral(['\n See discussion and possible solutions at\n ', '\n '], ['\n See discussion and possible solutions at\n ', '\n ']),
13
- _templateObject11 = _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 ']),
14
- _templateObject12 = _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 ']),
15
- _templateObject13 = _taggedTemplateLiteral(['\n You should set CYPRESS_INSTALL_BINARY instead.\n '], ['\n You should set CYPRESS_INSTALL_BINARY instead.\n ']),
16
- _templateObject14 = _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 ']),
17
- _templateObject15 = _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 ']),
18
- _templateObject16 = _taggedTemplateLiteral(['\n Platform: ', ' (', ')\n Cypress Version: ', '\n '], ['\n Platform: ', ' (', ')\n Cypress Version: ', '\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: 'Please check network connectivity and try again:'
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(_templateObject, chalk.blue(util.issuesUrl))
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(_templateObject2, chalk.cyan('cypress install'))
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(_templateObject3)
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(_templateObject4, chalk.cyan(executable), util.getCacheDir(), util.getCacheDir(), chalk.blue('https://on.cypress.io/not-installed-ci-error'))
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: 'XVFB exited with a non zero exit code.',
80
- solution: stripIndent(_templateObject5)
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: XVFB',
85
- solution: stripIndent(_templateObject6, chalk.blue(requiredDependenciesUrl))
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(_templateObject7, smokeTestCommand)
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(_templateObject8, hr, msg, hr, chalk.blue(requiredDependenciesUrl));
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(_templateObject9, chalk.blue(requiredDependenciesUrl))
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(_templateObject10, chalk.blue(util.getGitHubIssueUrl(1281)))
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(_templateObject11, chalk.blue(docsUrl), chalk.blue(util.issuesUrl))
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(_templateObject12, chalk.green('3.0.0')),
127
- solution: stripIndent(_templateObject13)
127
+ description: stripIndent(_templateObject13, chalk.green('3.0.0')),
128
+ solution: stripIndent(_templateObject14)
128
129
  },
129
130
  CYPRESS_SKIP_BINARY_INSTALL: {
130
- description: stripIndent(_templateObject14, chalk.green('3.0.0')),
131
- solution: stripIndent(_templateObject15)
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(_templateObject16, os.platform(), version, util.pkgVersion());
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 XVFB process on linux
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 XVFB?', needsXvfb);
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 XVFB server
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 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 ']);
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 XVFB');
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 XVFB');
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 XVFB');
71
+ debug('Cypress will spawn its own Xvfb');
72
72
 
73
73
  return true;
74
74
  },
@@ -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 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 ']);
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
- debug('Downloading from', url);
101
- debug('Saving file to', downloadDestination);
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(_templateObject2, response.statusCode, response.statusMessage));
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
- var eta = util.calculateEta(state.percent, elapsed);
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(state.percent, util.secsRemaining(eta));
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
- resolve(redirectVersion);
254
+ verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(function () {
255
+ return resolve(redirectVersion);
256
+ }, reject);
156
257
  });
157
258
  });
158
259
  };
159
260
 
160
- var start = function start(_ref2) {
161
- var version = _ref2.version,
162
- downloadDestination = _ref2.downloadDestination,
163
- progress = _ref2.progress;
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', _arguments);
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
  };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
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 ']),
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
- var envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY');
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
 
@@ -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 XVFB?', needsXvfb);
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
- return Promise.resolve(util.exec(executable, args, { timeout: options.smokeTestTimeout })).catch(onSmokeTestError(smokeTestCommand, linuxWithDisplayEnv)).then(function (result) {
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 XVFB server
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: 10000
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
  };