cypress 9.4.1 → 9.5.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }