cypress 12.1.0 → 12.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,58 +1,39 @@
1
1
  "use strict";
2
2
 
3
3
  const _ = require('lodash');
4
-
5
4
  const os = require('os');
6
-
7
5
  const path = require('path');
8
-
9
6
  const chalk = require('chalk');
10
-
11
7
  const debug = require('debug')('cypress:cli');
12
-
13
8
  const {
14
9
  Listr
15
10
  } = require('listr2');
16
-
17
11
  const Promise = require('bluebird');
18
-
19
12
  const logSymbols = require('log-symbols');
20
-
21
13
  const {
22
14
  stripIndent
23
15
  } = require('common-tags');
24
-
25
16
  const fs = require('../fs');
26
-
27
17
  const download = require('./download');
28
-
29
18
  const util = require('../util');
30
-
31
19
  const state = require('./state');
32
-
33
20
  const unzip = require('./unzip');
34
-
35
21
  const logger = require('../logger');
36
-
37
22
  const {
38
23
  throwFormErrorText,
39
24
  errors
40
25
  } = require('../errors');
41
-
42
26
  const verbose = require('../VerboseRenderer');
43
-
44
27
  const {
45
28
  buildInfo,
46
29
  version
47
30
  } = require('../../package.json');
48
-
49
31
  function _getBinaryUrlFromBuildInfo(arch, {
50
32
  commitSha,
51
33
  commitBranch
52
34
  }) {
53
35
  return `https://cdn.cypress.io/beta/binary/${version}/${os.platform()}-${arch}/${commitBranch}-${commitSha}/cypress.zip`;
54
36
  }
55
-
56
37
  const alreadyInstalledMsg = () => {
57
38
  if (!util.isPostInstall()) {
58
39
  logger.log(stripIndent`
@@ -62,7 +43,6 @@ const alreadyInstalledMsg = () => {
62
43
  `);
63
44
  }
64
45
  };
65
-
66
46
  const displayCompletionMsg = () => {
67
47
  // check here to see if we are globally installed
68
48
  if (util.isInstalledGlobally()) {
@@ -82,14 +62,12 @@ const displayCompletionMsg = () => {
82
62
  `);
83
63
  return;
84
64
  }
85
-
86
65
  logger.log();
87
66
  logger.log('You can now open Cypress by running:', chalk.cyan(path.join('node_modules', '.bin', 'cypress'), 'open'));
88
67
  logger.log();
89
68
  logger.log(chalk.grey('https://on.cypress.io/installing-cypress'));
90
69
  logger.log();
91
70
  };
92
-
93
71
  const downloadAndUnzip = ({
94
72
  version,
95
73
  installDir,
@@ -100,8 +78,9 @@ const downloadAndUnzip = ({
100
78
  onProgress: null
101
79
  };
102
80
  const downloadDestination = path.join(downloadDir, `cypress-${process.pid}.zip`);
103
- const rendererOptions = getRendererOptions(); // let the user know what version of cypress we're downloading!
81
+ const rendererOptions = getRendererOptions();
104
82
 
83
+ // let the user know what version of cypress we're downloading!
105
84
  logger.log(`Installing Cypress ${chalk.gray(`(version: ${version})`)}`);
106
85
  logger.log();
107
86
  const tasks = new Listr([{
@@ -137,7 +116,6 @@ const downloadAndUnzip = ({
137
116
  debug('removing zip file %s', downloadDestination);
138
117
  return fs.removeAsync(downloadDestination);
139
118
  };
140
-
141
119
  return cleanup().then(() => {
142
120
  debug('finished installation in', installDir);
143
121
  util.setTaskTitle(task, util.titleize(chalk.green('Finished Installation'), chalk.gray(installDir)), rendererOptions.renderer);
@@ -145,22 +123,21 @@ const downloadAndUnzip = ({
145
123
  }
146
124
  }], {
147
125
  rendererOptions
148
- }); // start the tasks!
126
+ });
149
127
 
128
+ // start the tasks!
150
129
  return Promise.resolve(tasks.run());
151
130
  };
152
-
153
131
  const validateOS = () => {
154
132
  return util.getPlatformInfo().then(platformInfo => {
155
133
  return platformInfo.match(/(win32-x64|linux-x64|linux-arm64|darwin-x64|darwin-arm64)/);
156
134
  });
157
135
  };
136
+
158
137
  /**
159
138
  * Returns the version to install - either a string like `1.2.3` to be fetched
160
139
  * from the download server or a file path or HTTP URL.
161
140
  */
162
-
163
-
164
141
  function getVersionOverride({
165
142
  arch,
166
143
  envVarVersion,
@@ -170,7 +147,6 @@ function getVersionOverride({
170
147
  if (envVarVersion) {
171
148
  return envVarVersion;
172
149
  }
173
-
174
150
  if (buildInfo && !buildInfo.stable) {
175
151
  logger.log(chalk.yellow(stripIndent`
176
152
  ${logSymbols.warning} Warning: You are installing a pre-release build of Cypress.
@@ -186,21 +162,19 @@ function getVersionOverride({
186
162
  return _getBinaryUrlFromBuildInfo(arch, buildInfo);
187
163
  }
188
164
  }
189
-
190
165
  function getEnvVarVersion() {
191
- if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return; // because passed file paths are often double quoted
192
- // and might have extra whitespace around, be robust and trim the string
166
+ if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return;
193
167
 
168
+ // because passed file paths are often double quoted
169
+ // and might have extra whitespace around, be robust and trim the string
194
170
  const trimAndRemoveDoubleQuotes = true;
195
171
  const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
196
172
  debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
197
173
  return envVarVersion;
198
174
  }
199
-
200
175
  const start = async (options = {}) => {
201
176
  debug('installing with options %j', options);
202
177
  const envVarVersion = getEnvVarVersion();
203
-
204
178
  if (envVarVersion === '0') {
205
179
  debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
206
180
  logger.log(stripIndent`
@@ -208,12 +182,10 @@ const start = async (options = {}) => {
208
182
  logger.log();
209
183
  return;
210
184
  }
211
-
212
185
  _.defaults(options, {
213
186
  force: false,
214
187
  buildInfo
215
188
  });
216
-
217
189
  if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
218
190
  const envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
219
191
  logger.log(stripIndent`
@@ -223,7 +195,6 @@ const start = async (options = {}) => {
223
195
  `);
224
196
  logger.log();
225
197
  }
226
-
227
198
  const pkgVersion = util.pkgVersion();
228
199
  const arch = await util.getRealArch();
229
200
  const versionOverride = getVersionOverride({
@@ -236,11 +207,9 @@ const start = async (options = {}) => {
236
207
  const installDir = state.getVersionDir(pkgVersion, options.buildInfo);
237
208
  const cacheDir = state.getCacheDir();
238
209
  const binaryDir = state.getBinaryDir(pkgVersion);
239
-
240
210
  if (!(await validateOS())) {
241
211
  return throwFormErrorText(errors.invalidOS)();
242
212
  }
243
-
244
213
  await fs.ensureDirAsync(cacheDir).catch({
245
214
  code: 'EACCES'
246
215
  }, err => {
@@ -252,38 +221,32 @@ const start = async (options = {}) => {
252
221
  });
253
222
  const binaryPkg = await state.getBinaryPkgAsync(binaryDir);
254
223
  const binaryVersion = await state.getBinaryPkgVersion(binaryPkg);
255
-
256
224
  const shouldInstall = () => {
257
225
  if (!binaryVersion) {
258
226
  debug('no binary installed under cli version');
259
227
  return true;
260
228
  }
261
-
262
229
  logger.log();
263
230
  logger.log(stripIndent`
264
231
  Cypress ${chalk.green(binaryVersion)} is installed in ${chalk.cyan(installDir)}
265
232
  `);
266
233
  logger.log();
267
-
268
234
  if (options.force) {
269
235
  debug('performing force install over existing binary');
270
236
  return true;
271
237
  }
272
-
273
238
  if (binaryVersion === versionToInstall || !util.isSemver(versionToInstall)) {
274
239
  // our version matches, tell the user this is a noop
275
240
  alreadyInstalledMsg();
276
241
  return false;
277
242
  }
278
-
279
243
  return true;
280
- }; // noop if we've been told not to download
281
-
244
+ };
282
245
 
246
+ // noop if we've been told not to download
283
247
  if (!shouldInstall()) {
284
248
  return debug('Not downloading or installing binary');
285
249
  }
286
-
287
250
  if (envVarVersion) {
288
251
  logger.log(chalk.yellow(stripIndent`
289
252
  ${logSymbols.warning} Warning: Forcing a binary version different than the default.
@@ -296,26 +259,22 @@ const start = async (options = {}) => {
296
259
  `));
297
260
  logger.log();
298
261
  }
299
-
300
262
  const getLocalFilePath = async () => {
301
263
  // see if version supplied is a path to a binary
302
264
  if (await fs.pathExistsAsync(versionToInstall)) {
303
265
  return path.extname(versionToInstall) === '.zip' ? versionToInstall : false;
304
266
  }
305
-
306
267
  const possibleFile = util.formAbsolutePath(versionToInstall);
307
- debug('checking local file', possibleFile, 'cwd', process.cwd()); // if this exists return the path to it
308
- // else false
268
+ debug('checking local file', possibleFile, 'cwd', process.cwd());
309
269
 
270
+ // if this exists return the path to it
271
+ // else false
310
272
  if ((await fs.pathExistsAsync(possibleFile)) && path.extname(possibleFile) === '.zip') {
311
273
  return possibleFile;
312
274
  }
313
-
314
275
  return false;
315
276
  };
316
-
317
277
  const pathToLocalFile = await getLocalFilePath();
318
-
319
278
  if (pathToLocalFile) {
320
279
  const absolutePath = path.resolve(versionToInstall);
321
280
  debug('found local file at', absolutePath);
@@ -333,29 +292,26 @@ const start = async (options = {}) => {
333
292
  rendererOptions
334
293
  }).run();
335
294
  }
336
-
337
295
  if (options.force) {
338
296
  debug('Cypress already installed at', installDir);
339
297
  debug('but the installation was forced');
340
298
  }
341
-
342
299
  debug('preparing to download and unzip version ', versionToInstall, 'to path', installDir);
343
300
  const downloadDir = os.tmpdir();
344
301
  await downloadAndUnzip({
345
302
  version: versionToInstall,
346
303
  installDir,
347
304
  downloadDir
348
- }); // delay 1 sec for UX, unless we are testing
305
+ });
349
306
 
307
+ // delay 1 sec for UX, unless we are testing
350
308
  await Promise.delay(1000);
351
309
  displayCompletionMsg();
352
310
  };
353
-
354
311
  module.exports = {
355
312
  start,
356
313
  _getBinaryUrlFromBuildInfo
357
314
  };
358
-
359
315
  const unzipTask = ({
360
316
  zipFilePath,
361
317
  installDir,
@@ -379,27 +335,25 @@ const unzipTask = ({
379
335
  }
380
336
  };
381
337
  };
382
-
383
338
  const progessify = (task, title) => {
384
339
  // return higher order function
385
340
  return (percentComplete, remaining) => {
386
- percentComplete = chalk.white(` ${percentComplete}%`); // pluralize seconds remaining
341
+ percentComplete = chalk.white(` ${percentComplete}%`);
387
342
 
343
+ // pluralize seconds remaining
388
344
  remaining = chalk.gray(`${remaining}s`);
389
345
  util.setTaskTitle(task, util.titleize(title, percentComplete, remaining), getRendererOptions().renderer);
390
346
  };
391
- }; // if we are running in CI then use
347
+ };
348
+
349
+ // if we are running in CI then use
392
350
  // the verbose renderer else use
393
351
  // the default
394
-
395
-
396
352
  const getRendererOptions = () => {
397
353
  let renderer = util.isCi() ? verbose : 'default';
398
-
399
354
  if (logger.logLevel() === 'silent') {
400
355
  renderer = 'silent';
401
356
  }
402
-
403
357
  return {
404
358
  renderer
405
359
  };
@@ -1,111 +1,83 @@
1
1
  "use strict";
2
2
 
3
3
  const _ = require('lodash');
4
-
5
4
  const os = require('os');
6
-
7
5
  const path = require('path');
8
-
9
6
  const untildify = require('untildify');
10
-
11
7
  const debug = require('debug')('cypress:cli');
12
-
13
8
  const fs = require('../fs');
14
-
15
9
  const util = require('../util');
16
-
17
10
  const getPlatformExecutable = () => {
18
11
  const platform = os.platform();
19
-
20
12
  switch (platform) {
21
13
  case 'darwin':
22
14
  return 'Contents/MacOS/Cypress';
23
-
24
15
  case 'linux':
25
16
  return 'Cypress';
26
-
27
17
  case 'win32':
28
18
  return 'Cypress.exe';
29
19
  // TODO handle this error using our standard
30
-
31
20
  default:
32
21
  throw new Error(`Platform: "${platform}" is not supported.`);
33
22
  }
34
23
  };
35
-
36
24
  const getPlatFormBinaryFolder = () => {
37
25
  const platform = os.platform();
38
-
39
26
  switch (platform) {
40
27
  case 'darwin':
41
28
  return 'Cypress.app';
42
-
43
29
  case 'linux':
44
30
  return 'Cypress';
45
-
46
31
  case 'win32':
47
32
  return 'Cypress';
48
33
  // TODO handle this error using our standard
49
-
50
34
  default:
51
35
  throw new Error(`Platform: "${platform}" is not supported.`);
52
36
  }
53
37
  };
54
-
55
38
  const getBinaryPkgPath = binaryDir => {
56
39
  const platform = os.platform();
57
-
58
40
  switch (platform) {
59
41
  case 'darwin':
60
42
  return path.join(binaryDir, 'Contents', 'Resources', 'app', 'package.json');
61
-
62
43
  case 'linux':
63
44
  return path.join(binaryDir, 'resources', 'app', 'package.json');
64
-
65
45
  case 'win32':
66
46
  return path.join(binaryDir, 'resources', 'app', 'package.json');
67
47
  // TODO handle this error using our standard
68
-
69
48
  default:
70
49
  throw new Error(`Platform: "${platform}" is not supported.`);
71
50
  }
72
51
  };
52
+
73
53
  /**
74
54
  * Get path to binary directory
75
55
  */
76
-
77
-
78
56
  const getBinaryDir = (version = util.pkgVersion()) => {
79
57
  return path.join(getVersionDir(version), getPlatFormBinaryFolder());
80
58
  };
81
-
82
59
  const getVersionDir = (version = util.pkgVersion(), buildInfo = util.pkgBuildInfo()) => {
83
60
  if (buildInfo && !buildInfo.stable) {
84
61
  version = ['beta', version, buildInfo.commitBranch, buildInfo.commitSha.slice(0, 8)].join('-');
85
62
  }
86
-
87
63
  return path.join(getCacheDir(), version);
88
64
  };
65
+
89
66
  /**
90
67
  * When executing "npm postinstall" hook, the working directory is set to
91
68
  * "<current folder>/node_modules/cypress", which can be surprising when using relative paths.
92
69
  */
93
-
94
-
95
70
  const isInstallingFromPostinstallHook = () => {
96
71
  // individual folders
97
72
  const cwdFolders = process.cwd().split(path.sep);
98
73
  const length = cwdFolders.length;
99
74
  return cwdFolders[length - 2] === 'node_modules' && cwdFolders[length - 1] === 'cypress';
100
75
  };
101
-
102
76
  const getCacheDir = () => {
103
77
  let cache_directory = util.getCacheDir();
104
-
105
78
  if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
106
79
  const envVarCacheDir = untildify(util.getEnv('CYPRESS_CACHE_FOLDER'));
107
80
  debug('using environment variable CYPRESS_CACHE_FOLDER %s', envVarCacheDir);
108
-
109
81
  if (!path.isAbsolute(envVarCacheDir) && isInstallingFromPostinstallHook()) {
110
82
  const packageRootFolder = path.join('..', '..', envVarCacheDir);
111
83
  cache_directory = path.resolve(packageRootFolder);
@@ -115,40 +87,32 @@ const getCacheDir = () => {
115
87
  cache_directory = path.resolve(envVarCacheDir);
116
88
  }
117
89
  }
118
-
119
90
  return cache_directory;
120
91
  };
121
-
122
92
  const parseRealPlatformBinaryFolderAsync = binaryPath => {
123
93
  return fs.realpathAsync(binaryPath).then(realPath => {
124
94
  debug('CYPRESS_RUN_BINARY has realpath:', realPath);
125
-
126
95
  if (!realPath.toString().endsWith(getPlatformExecutable())) {
127
96
  return false;
128
97
  }
129
-
130
98
  if (os.platform() === 'darwin') {
131
99
  return path.resolve(realPath, '..', '..', '..');
132
100
  }
133
-
134
101
  return path.resolve(realPath, '..');
135
102
  });
136
103
  };
137
-
138
104
  const getDistDir = () => {
139
105
  return path.join(__dirname, '..', '..', 'dist');
140
106
  };
107
+
141
108
  /**
142
109
  * Returns full filename to the file that keeps the Test Runner verification state as JSON text.
143
110
  * Note: the binary state file will be stored one level up from the given binary folder.
144
111
  * @param {string} binaryDir - full path to the folder holding the binary.
145
112
  */
146
-
147
-
148
113
  const getBinaryStatePath = binaryDir => {
149
114
  return path.join(binaryDir, '..', 'binary_state.json');
150
115
  };
151
-
152
116
  const getBinaryStateContentsAsync = binaryDir => {
153
117
  const fullPath = getBinaryStatePath(binaryDir);
154
118
  return fs.readJsonAsync(fullPath).catch({
@@ -158,22 +122,19 @@ const getBinaryStateContentsAsync = binaryDir => {
158
122
  return {};
159
123
  });
160
124
  };
161
-
162
125
  const getBinaryVerifiedAsync = binaryDir => {
163
126
  return getBinaryStateContentsAsync(binaryDir).tap(debug).get('verified');
164
127
  };
165
-
166
128
  const clearBinaryStateAsync = binaryDir => {
167
129
  return fs.removeAsync(getBinaryStatePath(binaryDir));
168
130
  };
131
+
169
132
  /**
170
133
  * Writes the new binary status.
171
134
  * @param {boolean} verified The new test runner state after smoke test
172
135
  * @param {string} binaryDir Folder holding the binary
173
136
  * @returns {Promise<void>} returns a promise
174
137
  */
175
-
176
-
177
138
  const writeBinaryVerifiedAsync = (verified, binaryDir) => {
178
139
  return getBinaryStateContentsAsync(binaryDir).then(contents => {
179
140
  return fs.outputJsonAsync(getBinaryStatePath(binaryDir), _.extend(contents, {
@@ -183,16 +144,14 @@ const writeBinaryVerifiedAsync = (verified, binaryDir) => {
183
144
  });
184
145
  });
185
146
  };
186
-
187
147
  const getPathToExecutable = binaryDir => {
188
148
  return path.join(binaryDir, getPlatformExecutable());
189
149
  };
150
+
190
151
  /**
191
152
  * Resolves with an object read from the binary app package.json file.
192
153
  * If the file does not exist resolves with null
193
154
  */
194
-
195
-
196
155
  const getBinaryPkgAsync = binaryDir => {
197
156
  const pathToPackageJson = getBinaryPkgPath(binaryDir);
198
157
  debug('Reading binary package.json from:', pathToPackageJson);
@@ -200,17 +159,12 @@ const getBinaryPkgAsync = binaryDir => {
200
159
  if (!exists) {
201
160
  return null;
202
161
  }
203
-
204
162
  return fs.readJsonAsync(pathToPackageJson);
205
163
  });
206
164
  };
207
-
208
165
  const getBinaryPkgVersion = o => _.get(o, 'version', null);
209
-
210
166
  const getBinaryElectronVersion = o => _.get(o, 'electronVersion', null);
211
-
212
167
  const getBinaryElectronNodeVersion = o => _.get(o, 'electronNodeVersion', null);
213
-
214
168
  module.exports = {
215
169
  getPathToExecutable,
216
170
  getPlatformExecutable,