cypress 9.5.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'
@@ -6,8 +6,6 @@ const arch = require('arch');
6
6
 
7
7
  const os = require('os');
8
8
 
9
- const url = require('url');
10
-
11
9
  const path = require('path');
12
10
 
13
11
  const chalk = require('chalk');
@@ -45,95 +43,17 @@ const {
45
43
 
46
44
  const verbose = require('../VerboseRenderer');
47
45
 
48
- const getNpmArgv = () => {
49
- const json = process.env.npm_config_argv;
50
-
51
- if (!json) {
52
- return;
53
- }
54
-
55
- debug('found npm argv json %o', json);
56
-
57
- try {
58
- return JSON.parse(json).original || [];
59
- } catch (e) {
60
- return [];
61
- }
62
- }; // attempt to discover the version specifier used to install Cypress
63
- // for example: "^5.0.0", "https://cdn.cypress.io/...", ...
64
-
65
-
66
- const getVersionSpecifier = (startDir = path.resolve(__dirname, '../..')) => {
67
- const argv = getNpmArgv();
68
-
69
- if ((process.env.npm_package_resolved || '').endsWith('cypress.tgz')) {
70
- return process.env.npm_package_resolved;
71
- }
72
-
73
- if (argv) {
74
- const tgz = _.find(argv, t => t.endsWith('cypress.tgz'));
75
-
76
- if (tgz) {
77
- return tgz;
78
- }
79
- }
80
-
81
- const getVersionSpecifierFromPkg = dir => {
82
- debug('looking for versionSpecifier %o', {
83
- dir
84
- });
85
-
86
- const tryParent = () => {
87
- const parentPath = path.resolve(dir, '..');
88
-
89
- if (parentPath === dir) {
90
- debug('reached FS root with no versionSpecifier found');
91
- return;
92
- }
93
-
94
- return getVersionSpecifierFromPkg(parentPath);
95
- };
96
-
97
- return fs.readJSON(path.join(dir, 'package.json')).catch(() => ({})).then(pkg => {
98
- const specifier = _.chain(['dependencies', 'devDependencies', 'optionalDependencies']).map(prop => _.get(pkg, `${prop}.cypress`)).compact().first().value();
99
-
100
- return specifier || tryParent();
101
- });
102
- }; // recurse through parent directories until package.json with `cypress` is found
103
-
104
-
105
- return getVersionSpecifierFromPkg(startDir).then(versionSpecifier => {
106
- debug('finished looking for versionSpecifier', {
107
- versionSpecifier
108
- });
109
- return versionSpecifier;
110
- });
111
- };
112
-
113
- const betaNpmUrlRe = /^\/beta\/npm\/(?<version>[0-9.]+)\/(?<platformSlug>.+?)\/(?<artifactSlug>.+?)\/cypress\.tgz$/; // convert a prerelease NPM package .tgz URL to the corresponding binary .zip URL
114
-
115
- const getBinaryUrlFromPrereleaseNpmUrl = npmUrl => {
116
- let parsed;
117
-
118
- try {
119
- parsed = url.parse(npmUrl);
120
- } catch (e) {
121
- return;
122
- }
123
-
124
- const matches = betaNpmUrlRe.exec(parsed.pathname);
125
-
126
- if (parsed.hostname !== 'cdn.cypress.io' || !matches) {
127
- return;
128
- }
46
+ const {
47
+ buildInfo,
48
+ version
49
+ } = require('../../package.json');
129
50
 
130
- const {
131
- version,
132
- artifactSlug
133
- } = matches.groups;
134
- parsed.pathname = `/beta/binary/${version}/${os.platform()}-${arch()}/${artifactSlug}/cypress.zip`;
135
- return parsed.format();
136
- };
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
+ }
137
57
 
138
58
  const alreadyInstalledMsg = () => {
139
59
  if (!util.isPostInstall()) {
@@ -237,37 +157,64 @@ const validateOS = () => {
237
157
  return platformInfo.match(/(darwin|linux|win32)-x64/);
238
158
  });
239
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
+ }
240
174
 
241
- const start = (options = {}) => {
242
- 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.
243
178
 
244
- _.defaults(options, {
245
- force: false
246
- });
179
+ Bugs may be present which do not exist in production builds.
247
180
 
248
- const pkgVersion = util.pkgVersion();
249
- let needVersion = pkgVersion;
250
- let binaryUrlOverride;
251
- debug('version in package.json is', needVersion); // let this environment variable reset the binary version we need
252
-
253
- if (util.getEnv('CYPRESS_INSTALL_BINARY')) {
254
- // because passed file paths are often double quoted
255
- // and might have extra whitespace around, be robust and trim the string
256
- const trimAndRemoveDoubleQuotes = true;
257
- const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
258
- debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
259
-
260
- if (envVarVersion === '0') {
261
- debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
262
- logger.log(stripIndent`
263
- ${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`);
264
- logger.log();
265
- return Promise.resolve();
266
- }
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
+ }
190
+
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();
267
204
 
268
- binaryUrlOverride = envVarVersion;
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;
269
211
  }
270
212
 
213
+ _.defaults(options, {
214
+ force: false,
215
+ buildInfo
216
+ });
217
+
271
218
  if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
272
219
  const envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
273
220
  logger.log(stripIndent`
@@ -278,16 +225,22 @@ const start = (options = {}) => {
278
225
  logger.log();
279
226
  }
280
227
 
281
- 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);
282
236
  const cacheDir = state.getCacheDir();
283
237
  const binaryDir = state.getBinaryDir(pkgVersion);
284
- return validateOS().then(isValid => {
285
- if (!isValid) {
286
- return throwFormErrorText(errors.invalidOS)();
287
- }
288
- }).then(() => {
289
- return fs.ensureDirAsync(cacheDir);
290
- }).catch({
238
+
239
+ if (!(await validateOS())) {
240
+ return throwFormErrorText(errors.invalidOS)();
241
+ }
242
+
243
+ await fs.ensureDirAsync(cacheDir).catch({
291
244
  code: 'EACCES'
292
245
  }, err => {
293
246
  return throwFormErrorText(errors.invalidCacheDirectory)(stripIndent`
@@ -295,24 +248,11 @@ const start = (options = {}) => {
295
248
 
296
249
  ${err.message}
297
250
  `);
298
- }).then(() => {
299
- return Promise.all([state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion), getVersionSpecifier()]);
300
- }).then(([binaryVersion, versionSpecifier]) => {
301
- if (!binaryUrlOverride && versionSpecifier) {
302
- const computedBinaryUrl = getBinaryUrlFromPrereleaseNpmUrl(versionSpecifier);
303
-
304
- if (computedBinaryUrl) {
305
- debug('computed binary url from version specifier %o', {
306
- computedBinaryUrl,
307
- needVersion
308
- });
309
- binaryUrlOverride = computedBinaryUrl;
310
- }
311
- }
312
-
313
- needVersion = binaryUrlOverride || needVersion;
314
- debug('installed version is', binaryVersion, 'version needed is', needVersion);
251
+ });
252
+ const binaryPkg = await state.getBinaryPkgAsync(binaryDir);
253
+ const binaryVersion = await state.getBinaryPkgVersion(binaryPkg);
315
254
 
255
+ const shouldInstall = () => {
316
256
  if (!binaryVersion) {
317
257
  debug('no binary installed under cli version');
318
258
  return true;
@@ -329,92 +269,90 @@ const start = (options = {}) => {
329
269
  return true;
330
270
  }
331
271
 
332
- if (binaryVersion === needVersion || !util.isSemver(needVersion)) {
272
+ if (binaryVersion === versionToInstall || !util.isSemver(versionToInstall)) {
333
273
  // our version matches, tell the user this is a noop
334
274
  alreadyInstalledMsg();
335
275
  return false;
336
276
  }
337
277
 
338
278
  return true;
339
- }).then(shouldInstall => {
340
- // noop if we've been told not to download
341
- if (!shouldInstall) {
342
- debug('Not downloading or installing binary');
343
- return;
344
- }
279
+ }; // noop if we've been told not to download
345
280
 
346
- if (needVersion !== pkgVersion) {
347
- logger.log(chalk.yellow(stripIndent`
348
- ${logSymbols.warning} Warning: Forcing a binary version different than the default.
349
281
 
350
- The CLI expected to install version: ${chalk.green(pkgVersion)}
282
+ if (!shouldInstall()) {
283
+ return debug('Not downloading or installing binary');
284
+ }
351
285
 
352
- 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.
353
289
 
354
- These versions may not work properly together.
355
- `));
356
- logger.log();
357
- } // see if version supplied is a path to a binary
290
+ The CLI expected to install version: ${chalk.green(pkgVersion)}
358
291
 
292
+ Instead we will install version: ${chalk.green(versionToInstall)}
359
293
 
360
- return fs.pathExistsAsync(needVersion).then(exists => {
361
- if (exists) {
362
- return path.extname(needVersion) === '.zip' ? needVersion : false;
363
- }
294
+ These versions may not work properly together.
295
+ `));
296
+ logger.log();
297
+ }
364
298
 
365
- const possibleFile = util.formAbsolutePath(needVersion);
366
- debug('checking local file', possibleFile, 'cwd', process.cwd());
367
- return fs.pathExistsAsync(possibleFile).then(exists => {
368
- // if this exists return the path to it
369
- // else false
370
- if (exists && path.extname(possibleFile) === '.zip') {
371
- return possibleFile;
372
- }
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
+ }
373
304
 
374
- return false;
375
- });
376
- }).then(pathToLocalFile => {
377
- if (pathToLocalFile) {
378
- const absolutePath = path.resolve(needVersion);
379
- debug('found local file at', absolutePath);
380
- debug('skipping download');
381
- const rendererOptions = getRendererOptions();
382
- return new Listr([unzipTask({
383
- progress: {
384
- throttle: 100,
385
- onProgress: null
386
- },
387
- zipFilePath: absolutePath,
388
- installDir,
389
- rendererOptions
390
- })], {
391
- rendererOptions
392
- }).run();
393
- }
394
-
395
- if (options.force) {
396
- debug('Cypress already installed at', installDir);
397
- debug('but the installation was forced');
398
- }
399
-
400
- debug('preparing to download and unzip version ', needVersion, 'to path', installDir);
401
- const downloadDir = os.tmpdir();
402
- return downloadAndUnzip({
403
- version: needVersion,
404
- installDir,
405
- downloadDir
406
- });
407
- }) // delay 1 sec for UX, unless we are testing
408
- .then(() => {
409
- return Promise.delay(1000);
410
- }).then(displayCompletionMsg);
411
- });
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();
412
351
  };
413
352
 
414
353
  module.exports = {
415
354
  start,
416
- _getVersionSpecifier: getVersionSpecifier,
417
- _getBinaryUrlFromPrereleaseNpmUrl: getBinaryUrlFromPrereleaseNpmUrl
355
+ _getBinaryUrlFromBuildInfo
418
356
  };
419
357
 
420
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.5.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
+ }