cypress 9.4.1 → 9.5.2

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/exec/info.js CHANGED
@@ -18,7 +18,8 @@ const _ = require('lodash'); // color for numbers and show values
18
18
 
19
19
  const g = chalk.green; // color for paths
20
20
 
21
- const p = chalk.cyan; // urls
21
+ const p = chalk.cyan;
22
+ const red = chalk.red; // urls
22
23
 
23
24
  const link = chalk.blue.underline; // to be exported
24
25
 
@@ -50,52 +51,63 @@ const formatCypressVariables = () => {
50
51
  return maskSensitiveVariables(vars);
51
52
  };
52
53
 
53
- methods.start = (options = {}) => {
54
+ methods.start = async (options = {}) => {
54
55
  const args = ['--mode=info'];
55
- return spawn.start(args, {
56
+ await spawn.start(args, {
56
57
  dev: options.dev
57
- }).then(() => {
58
- console.log();
59
- const proxyVars = methods.findProxyEnvironmentVariables();
60
-
61
- if (_.isEmpty(proxyVars)) {
62
- console.log('Proxy Settings: none detected');
63
- } else {
64
- console.log('Proxy Settings:');
65
-
66
- _.forEach(proxyVars, (value, key) => {
67
- console.log('%s: %s', key, g(value));
68
- });
69
-
70
- console.log();
71
- console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'));
72
- console.log();
73
- }
74
- }).then(() => {
75
- const cyVars = formatCypressVariables();
76
-
77
- if (_.isEmpty(cyVars)) {
78
- console.log('Environment Variables: none detected');
79
- } else {
80
- console.log('Environment Variables:');
81
-
82
- _.forEach(cyVars, (value, key) => {
83
- console.log('%s: %s', key, g(value));
84
- });
85
- }
86
- }).then(() => {
58
+ });
59
+ console.log();
60
+ const proxyVars = methods.findProxyEnvironmentVariables();
61
+
62
+ if (_.isEmpty(proxyVars)) {
63
+ console.log('Proxy Settings: none detected');
64
+ } else {
65
+ console.log('Proxy Settings:');
66
+
67
+ _.forEach(proxyVars, (value, key) => {
68
+ console.log('%s: %s', key, g(value));
69
+ });
70
+
87
71
  console.log();
88
- console.log('Application Data:', p(util.getApplicationDataFolder()));
89
- console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')));
90
- console.log('Binary Caches: %s', p(state.getCacheDir()));
91
- }).then(() => {
72
+ console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'));
92
73
  console.log();
93
- return util.getOsVersionAsync().then(osVersion => {
94
- console.log('Cypress Version: %s', g(util.pkgVersion()));
95
- console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion));
96
- console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())));
74
+ }
75
+
76
+ const cyVars = formatCypressVariables();
77
+
78
+ if (_.isEmpty(cyVars)) {
79
+ console.log('Environment Variables: none detected');
80
+ } else {
81
+ console.log('Environment Variables:');
82
+
83
+ _.forEach(cyVars, (value, key) => {
84
+ console.log('%s: %s', key, g(value));
97
85
  });
98
- });
86
+ }
87
+
88
+ console.log();
89
+ console.log('Application Data:', p(util.getApplicationDataFolder()));
90
+ console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')));
91
+ console.log('Binary Caches: %s', p(state.getCacheDir()));
92
+ console.log();
93
+ const osVersion = await util.getOsVersionAsync();
94
+ const buildInfo = util.pkgBuildInfo();
95
+ const isStable = buildInfo && buildInfo.stable;
96
+ console.log('Cypress Version: %s', g(util.pkgVersion()), isStable ? g('(stable)') : red('(pre-release)'));
97
+ console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion));
98
+ console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())));
99
+
100
+ if (!buildInfo) {
101
+ console.log();
102
+ console.log('This is the', red('development'), '(un-built) Cypress CLI.');
103
+ } else if (!isStable) {
104
+ console.log();
105
+ console.log('This is a', red('pre-release'), 'build of Cypress.');
106
+ console.log('Build info:');
107
+ console.log(' Commit SHA:', g(buildInfo.commitSha));
108
+ console.log(' Commit Branch:', g(buildInfo.commitBranch));
109
+ console.log(' Commit Date:', g(buildInfo.commitDate));
110
+ }
99
111
  };
100
112
 
101
113
  module.exports = methods;
@@ -43,8 +43,11 @@ const getVersions = () => {
43
43
  debug('binary versions %o', versions);
44
44
  return versions;
45
45
  }).then(binaryVersions => {
46
+ const buildInfo = util.pkgBuildInfo();
47
+ let packageVersion = util.pkgVersion();
48
+ if (!buildInfo) packageVersion += ' (development)';else if (!buildInfo.stable) packageVersion += ' (pre-release)';
46
49
  const versions = {
47
- package: util.pkgVersion(),
50
+ package: packageVersion,
48
51
  binary: binaryVersions.binary || 'not installed',
49
52
  electronVersion: binaryVersions.electronVersion || 'not found',
50
53
  electronNodeVersion: binaryVersions.electronNodeVersion || 'not found'
@@ -2,9 +2,9 @@
2
2
 
3
3
  const _ = require('lodash');
4
4
 
5
- const os = require('os');
5
+ const arch = require('arch');
6
6
 
7
- const url = require('url');
7
+ const os = require('os');
8
8
 
9
9
  const path = require('path');
10
10
 
@@ -43,95 +43,17 @@ const {
43
43
 
44
44
  const verbose = require('../VerboseRenderer');
45
45
 
46
- const getNpmArgv = () => {
47
- const json = process.env.npm_config_argv;
48
-
49
- if (!json) {
50
- return;
51
- }
52
-
53
- debug('found npm argv json %o', json);
54
-
55
- try {
56
- return JSON.parse(json).original || [];
57
- } catch (e) {
58
- return [];
59
- }
60
- }; // attempt to discover the version specifier used to install Cypress
61
- // for example: "^5.0.0", "https://cdn.cypress.io/...", ...
62
-
63
-
64
- const getVersionSpecifier = (startDir = path.resolve(__dirname, '../..')) => {
65
- const argv = getNpmArgv();
66
-
67
- if ((process.env.npm_package_resolved || '').endsWith('cypress.tgz')) {
68
- return process.env.npm_package_resolved;
69
- }
70
-
71
- if (argv) {
72
- const tgz = _.find(argv, t => t.endsWith('cypress.tgz'));
73
-
74
- if (tgz) {
75
- return tgz;
76
- }
77
- }
78
-
79
- const getVersionSpecifierFromPkg = dir => {
80
- debug('looking for versionSpecifier %o', {
81
- dir
82
- });
83
-
84
- const tryParent = () => {
85
- const parentPath = path.resolve(dir, '..');
86
-
87
- if (parentPath === dir) {
88
- debug('reached FS root with no versionSpecifier found');
89
- return;
90
- }
91
-
92
- return getVersionSpecifierFromPkg(parentPath);
93
- };
94
-
95
- return fs.readJSON(path.join(dir, 'package.json')).catch(() => ({})).then(pkg => {
96
- const specifier = _.chain(['dependencies', 'devDependencies', 'optionalDependencies']).map(prop => _.get(pkg, `${prop}.cypress`)).compact().first().value();
97
-
98
- return specifier || tryParent();
99
- });
100
- }; // recurse through parent directories until package.json with `cypress` is found
101
-
102
-
103
- return getVersionSpecifierFromPkg(startDir).then(versionSpecifier => {
104
- debug('finished looking for versionSpecifier', {
105
- versionSpecifier
106
- });
107
- return versionSpecifier;
108
- });
109
- };
110
-
111
- const betaNpmUrlRe = /^\/beta\/npm\/(?<version>[0-9.]+)\/(?<artifactSlug>.+?)\/cypress\.tgz$/; // convert a prerelease NPM package .tgz URL to the corresponding binary .zip URL
112
-
113
- const getBinaryUrlFromPrereleaseNpmUrl = npmUrl => {
114
- let parsed;
115
-
116
- try {
117
- parsed = url.parse(npmUrl);
118
- } catch (e) {
119
- return;
120
- }
121
-
122
- const matches = betaNpmUrlRe.exec(parsed.pathname);
123
-
124
- if (parsed.hostname !== 'cdn.cypress.io' || !matches) {
125
- return;
126
- }
46
+ const {
47
+ buildInfo,
48
+ version
49
+ } = require('../../package.json');
127
50
 
128
- const {
129
- version,
130
- artifactSlug
131
- } = matches.groups;
132
- parsed.pathname = `/beta/binary/${version}/${os.platform()}-${os.arch()}/${artifactSlug}/cypress.zip`;
133
- return parsed.format();
134
- };
51
+ function _getBinaryUrlFromBuildInfo({
52
+ commitSha,
53
+ commitBranch
54
+ }) {
55
+ return `https://cdn.cypress.io/beta/binary/${version}/${os.platform()}-${arch()}/${commitBranch}-${commitSha}/cypress.zip`;
56
+ }
135
57
 
136
58
  const alreadyInstalledMsg = () => {
137
59
  if (!util.isPostInstall()) {
@@ -235,37 +157,64 @@ const validateOS = () => {
235
157
  return platformInfo.match(/(darwin|linux|win32)-x64/);
236
158
  });
237
159
  };
160
+ /**
161
+ * Returns the version to install - either a string like `1.2.3` to be fetched
162
+ * from the download server or a file path or HTTP URL.
163
+ */
164
+
165
+
166
+ function getVersionOverride({
167
+ envVarVersion,
168
+ buildInfo
169
+ }) {
170
+ // let this environment variable reset the binary version we need
171
+ if (envVarVersion) {
172
+ return envVarVersion;
173
+ }
238
174
 
239
- const start = (options = {}) => {
240
- debug('installing with options %j', options);
175
+ if (buildInfo && !buildInfo.stable) {
176
+ logger.log(chalk.yellow(stripIndent`
177
+ ${logSymbols.warning} Warning: You are installing a pre-release build of Cypress.
241
178
 
242
- _.defaults(options, {
243
- force: false
244
- });
179
+ Bugs may be present which do not exist in production builds.
245
180
 
246
- const pkgVersion = util.pkgVersion();
247
- let needVersion = pkgVersion;
248
- let binaryUrlOverride;
249
- debug('version in package.json is', needVersion); // let this environment variable reset the binary version we need
250
-
251
- if (util.getEnv('CYPRESS_INSTALL_BINARY')) {
252
- // because passed file paths are often double quoted
253
- // and might have extra whitespace around, be robust and trim the string
254
- const trimAndRemoveDoubleQuotes = true;
255
- const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
256
- debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
257
-
258
- if (envVarVersion === '0') {
259
- debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
260
- logger.log(stripIndent`
261
- ${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`);
262
- logger.log();
263
- return Promise.resolve();
264
- }
181
+ This build was created from:
182
+ * Commit SHA: ${buildInfo.commitSha}
183
+ * Commit Branch: ${buildInfo.commitBranch}
184
+ * Commit Timestamp: ${buildInfo.commitDate}
185
+ `));
186
+ logger.log();
187
+ return _getBinaryUrlFromBuildInfo(buildInfo);
188
+ }
189
+ }
265
190
 
266
- binaryUrlOverride = envVarVersion;
191
+ function getEnvVarVersion() {
192
+ if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return; // because passed file paths are often double quoted
193
+ // and might have extra whitespace around, be robust and trim the string
194
+
195
+ const trimAndRemoveDoubleQuotes = true;
196
+ const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
197
+ debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
198
+ return envVarVersion;
199
+ }
200
+
201
+ const start = async (options = {}) => {
202
+ debug('installing with options %j', options);
203
+ const envVarVersion = getEnvVarVersion();
204
+
205
+ if (envVarVersion === '0') {
206
+ debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
207
+ logger.log(stripIndent`
208
+ ${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`);
209
+ logger.log();
210
+ return;
267
211
  }
268
212
 
213
+ _.defaults(options, {
214
+ force: false,
215
+ buildInfo
216
+ });
217
+
269
218
  if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
270
219
  const envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
271
220
  logger.log(stripIndent`
@@ -276,16 +225,22 @@ const start = (options = {}) => {
276
225
  logger.log();
277
226
  }
278
227
 
279
- const installDir = state.getVersionDir(pkgVersion);
228
+ const pkgVersion = util.pkgVersion();
229
+ const versionOverride = getVersionOverride({
230
+ envVarVersion,
231
+ buildInfo: options.buildInfo
232
+ });
233
+ const versionToInstall = versionOverride || pkgVersion;
234
+ debug('version in package.json is %s, version to install is %s', pkgVersion, versionToInstall);
235
+ const installDir = state.getVersionDir(pkgVersion, options.buildInfo);
280
236
  const cacheDir = state.getCacheDir();
281
237
  const binaryDir = state.getBinaryDir(pkgVersion);
282
- return validateOS().then(isValid => {
283
- if (!isValid) {
284
- return throwFormErrorText(errors.invalidOS)();
285
- }
286
- }).then(() => {
287
- return fs.ensureDirAsync(cacheDir);
288
- }).catch({
238
+
239
+ if (!(await validateOS())) {
240
+ return throwFormErrorText(errors.invalidOS)();
241
+ }
242
+
243
+ await fs.ensureDirAsync(cacheDir).catch({
289
244
  code: 'EACCES'
290
245
  }, err => {
291
246
  return throwFormErrorText(errors.invalidCacheDirectory)(stripIndent`
@@ -293,24 +248,11 @@ const start = (options = {}) => {
293
248
 
294
249
  ${err.message}
295
250
  `);
296
- }).then(() => {
297
- return Promise.all([state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion), getVersionSpecifier()]);
298
- }).then(([binaryVersion, versionSpecifier]) => {
299
- if (!binaryUrlOverride && versionSpecifier) {
300
- const computedBinaryUrl = getBinaryUrlFromPrereleaseNpmUrl(versionSpecifier);
301
-
302
- if (computedBinaryUrl) {
303
- debug('computed binary url from version specifier %o', {
304
- computedBinaryUrl,
305
- needVersion
306
- });
307
- binaryUrlOverride = computedBinaryUrl;
308
- }
309
- }
310
-
311
- needVersion = binaryUrlOverride || needVersion;
312
- debug('installed version is', binaryVersion, 'version needed is', needVersion);
251
+ });
252
+ const binaryPkg = await state.getBinaryPkgAsync(binaryDir);
253
+ const binaryVersion = await state.getBinaryPkgVersion(binaryPkg);
313
254
 
255
+ const shouldInstall = () => {
314
256
  if (!binaryVersion) {
315
257
  debug('no binary installed under cli version');
316
258
  return true;
@@ -327,92 +269,90 @@ const start = (options = {}) => {
327
269
  return true;
328
270
  }
329
271
 
330
- if (binaryVersion === needVersion || !util.isSemver(needVersion)) {
272
+ if (binaryVersion === versionToInstall || !util.isSemver(versionToInstall)) {
331
273
  // our version matches, tell the user this is a noop
332
274
  alreadyInstalledMsg();
333
275
  return false;
334
276
  }
335
277
 
336
278
  return true;
337
- }).then(shouldInstall => {
338
- // noop if we've been told not to download
339
- if (!shouldInstall) {
340
- debug('Not downloading or installing binary');
341
- return;
342
- }
279
+ }; // noop if we've been told not to download
343
280
 
344
- if (needVersion !== pkgVersion) {
345
- logger.log(chalk.yellow(stripIndent`
346
- ${logSymbols.warning} Warning: Forcing a binary version different than the default.
347
281
 
348
- The CLI expected to install version: ${chalk.green(pkgVersion)}
282
+ if (!shouldInstall()) {
283
+ return debug('Not downloading or installing binary');
284
+ }
349
285
 
350
- Instead we will install version: ${chalk.green(needVersion)}
286
+ if (envVarVersion) {
287
+ logger.log(chalk.yellow(stripIndent`
288
+ ${logSymbols.warning} Warning: Forcing a binary version different than the default.
351
289
 
352
- These versions may not work properly together.
353
- `));
354
- logger.log();
355
- } // see if version supplied is a path to a binary
290
+ The CLI expected to install version: ${chalk.green(pkgVersion)}
356
291
 
292
+ Instead we will install version: ${chalk.green(versionToInstall)}
357
293
 
358
- return fs.pathExistsAsync(needVersion).then(exists => {
359
- if (exists) {
360
- return path.extname(needVersion) === '.zip' ? needVersion : false;
361
- }
294
+ These versions may not work properly together.
295
+ `));
296
+ logger.log();
297
+ }
362
298
 
363
- const possibleFile = util.formAbsolutePath(needVersion);
364
- debug('checking local file', possibleFile, 'cwd', process.cwd());
365
- return fs.pathExistsAsync(possibleFile).then(exists => {
366
- // if this exists return the path to it
367
- // else false
368
- if (exists && path.extname(possibleFile) === '.zip') {
369
- return possibleFile;
370
- }
299
+ const getLocalFilePath = async () => {
300
+ // see if version supplied is a path to a binary
301
+ if (await fs.pathExistsAsync(versionToInstall)) {
302
+ return path.extname(versionToInstall) === '.zip' ? versionToInstall : false;
303
+ }
371
304
 
372
- return false;
373
- });
374
- }).then(pathToLocalFile => {
375
- if (pathToLocalFile) {
376
- const absolutePath = path.resolve(needVersion);
377
- debug('found local file at', absolutePath);
378
- debug('skipping download');
379
- const rendererOptions = getRendererOptions();
380
- return new Listr([unzipTask({
381
- progress: {
382
- throttle: 100,
383
- onProgress: null
384
- },
385
- zipFilePath: absolutePath,
386
- installDir,
387
- rendererOptions
388
- })], {
389
- rendererOptions
390
- }).run();
391
- }
392
-
393
- if (options.force) {
394
- debug('Cypress already installed at', installDir);
395
- debug('but the installation was forced');
396
- }
397
-
398
- debug('preparing to download and unzip version ', needVersion, 'to path', installDir);
399
- const downloadDir = os.tmpdir();
400
- return downloadAndUnzip({
401
- version: needVersion,
402
- installDir,
403
- downloadDir
404
- });
405
- }) // delay 1 sec for UX, unless we are testing
406
- .then(() => {
407
- return Promise.delay(1000);
408
- }).then(displayCompletionMsg);
409
- });
305
+ const possibleFile = util.formAbsolutePath(versionToInstall);
306
+ debug('checking local file', possibleFile, 'cwd', process.cwd()); // if this exists return the path to it
307
+ // else false
308
+
309
+ if ((await fs.pathExistsAsync(possibleFile)) && path.extname(possibleFile) === '.zip') {
310
+ return possibleFile;
311
+ }
312
+
313
+ return false;
314
+ };
315
+
316
+ const pathToLocalFile = await getLocalFilePath();
317
+
318
+ if (pathToLocalFile) {
319
+ const absolutePath = path.resolve(versionToInstall);
320
+ debug('found local file at', absolutePath);
321
+ debug('skipping download');
322
+ const rendererOptions = getRendererOptions();
323
+ return new Listr([unzipTask({
324
+ progress: {
325
+ throttle: 100,
326
+ onProgress: null
327
+ },
328
+ zipFilePath: absolutePath,
329
+ installDir,
330
+ rendererOptions
331
+ })], {
332
+ rendererOptions
333
+ }).run();
334
+ }
335
+
336
+ if (options.force) {
337
+ debug('Cypress already installed at', installDir);
338
+ debug('but the installation was forced');
339
+ }
340
+
341
+ debug('preparing to download and unzip version ', versionToInstall, 'to path', installDir);
342
+ const downloadDir = os.tmpdir();
343
+ await downloadAndUnzip({
344
+ version: versionToInstall,
345
+ installDir,
346
+ downloadDir
347
+ }); // delay 1 sec for UX, unless we are testing
348
+
349
+ await Promise.delay(1000);
350
+ displayCompletionMsg();
410
351
  };
411
352
 
412
353
  module.exports = {
413
354
  start,
414
- _getVersionSpecifier: getVersionSpecifier,
415
- _getBinaryUrlFromPrereleaseNpmUrl: getBinaryUrlFromPrereleaseNpmUrl
355
+ _getBinaryUrlFromBuildInfo
416
356
  };
417
357
 
418
358
  const unzipTask = ({
@@ -79,7 +79,11 @@ const getBinaryDir = (version = util.pkgVersion()) => {
79
79
  return path.join(getVersionDir(version), getPlatFormBinaryFolder());
80
80
  };
81
81
 
82
- const getVersionDir = (version = util.pkgVersion()) => {
82
+ const getVersionDir = (version = util.pkgVersion(), buildInfo = util.pkgBuildInfo()) => {
83
+ if (buildInfo && !buildInfo.stable) {
84
+ version = ['beta', version, buildInfo.commitBranch, buildInfo.commitSha].join('-');
85
+ }
86
+
83
87
  return path.join(getCacheDir(), version);
84
88
  };
85
89
  /**
package/lib/util.js CHANGED
@@ -338,6 +338,10 @@ const util = {
338
338
  return process.cwd();
339
339
  },
340
340
 
341
+ pkgBuildInfo() {
342
+ return pkg.buildInfo;
343
+ },
344
+
341
345
  pkgVersion() {
342
346
  return pkg.version;
343
347
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cypress",
3
- "version": "9.4.1",
3
+ "version": "9.5.2",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node index.js --exec install",
@@ -64,6 +64,12 @@
64
64
  "node": ">=12.0.0"
65
65
  },
66
66
  "types": "types",
67
+ "buildInfo": {
68
+ "commitBranch": "develop",
69
+ "commitSha": "5db2cd996834043b3c825625cf0100957e14a663",
70
+ "commitDate": "2022-03-14T18:42:32.000Z",
71
+ "stable": true
72
+ },
67
73
  "description": "Cypress.io end to end testing tool",
68
74
  "homepage": "https://github.com/cypress-io/cypress",
69
75
  "license": "MIT",
@@ -89,4 +95,4 @@
89
95
  "test",
90
96
  "testing"
91
97
  ]
92
- }
98
+ }