cypress 9.5.1 → 9.5.4

Sign up to get free protection for your applications and to get access to all the features.
package/lib/cli.js CHANGED
@@ -223,6 +223,10 @@ const createProgram = () => {
223
223
  const addCypressRunCommand = program => {
224
224
  return program.command('run').usage('[options]').description('Runs Cypress tests from the CLI without the GUI').option('-b, --browser <browser-name-or-path>', text('browserRunMode')).option('--ci-build-id <id>', text('ciBuildId')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse);
225
225
  };
226
+
227
+ const addCypressOpenCommand = program => {
228
+ return program.command('open').usage('[options]').description('Opens Cypress in the interactive GUI.').option('-b, --browser <browser-path>', text('browserOpenMode')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse);
229
+ };
226
230
  /**
227
231
  * Casts known command line options for "cypress run" to their intended type.
228
232
  * For example if the user passes "--port 5005" the ".port" property should be
@@ -322,10 +326,10 @@ module.exports = {
322
326
  program.option('-v, --version', text('version')).command('version').description(text('version')).action(() => {
323
327
  showVersions(args);
324
328
  });
325
- program.command('open').usage('[options]').description('Opens Cypress in the interactive GUI.').option('-b, --browser <browser-path>', text('browserOpenMode')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse).action(opts => {
329
+ addCypressOpenCommand(program).action(opts => {
326
330
  debug('opening Cypress');
327
331
 
328
- require('./exec/open').start(util.parseOpts(opts)).catch(util.logErrorExit1);
332
+ require('./exec/open').start(util.parseOpts(opts)).then(util.exit).catch(util.logErrorExit1);
329
333
  });
330
334
  addCypressRunCommand(program).action((...fnArgs) => {
331
335
  debug('running Cypress with args %o', fnArgs);
@@ -337,7 +341,7 @@ module.exports = {
337
341
 
338
342
  require('./exec/open').start({ ...util.parseOpts(opts),
339
343
  testingType: 'component'
340
- }).catch(util.logErrorExit1);
344
+ }).then(util.exit).catch(util.logErrorExit1);
341
345
  });
342
346
  program.command('run-ct').usage('[options]').description('Runs all Cypress Component Testing suites').option('-b, --browser <browser-name-or-path>', text('browserRunMode')).option('--ci-build-id <id>', text('ciBuildId')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse).action(opts => {
343
347
  debug('running Cypress run-ct');
package/lib/errors.js CHANGED
@@ -79,7 +79,7 @@ const binaryNotExecutable = executable => {
79
79
 
80
80
  Please check that you have the appropriate user permissions.
81
81
 
82
- You can also try clearing the cache with 'cypress cache clear' and reinstalling.
82
+ You can also try clearing the cache with 'cypress cache clear' and reinstalling.
83
83
  `
84
84
  };
85
85
  };
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;
package/lib/exec/open.js CHANGED
@@ -12,41 +12,48 @@ const {
12
12
  processTestingType
13
13
  } = require('./shared');
14
14
 
15
- module.exports = {
16
- start(options = {}) {
17
- if (!util.isInstalledGlobally() && !options.global && !options.project) {
18
- options.project = process.cwd();
19
- }
15
+ const processOpenOptions = options => {
16
+ if (!util.isInstalledGlobally() && !options.global && !options.project) {
17
+ options.project = process.cwd();
18
+ }
20
19
 
21
- const args = [];
20
+ const args = [];
22
21
 
23
- if (options.config) {
24
- args.push('--config', options.config);
25
- }
22
+ if (options.config) {
23
+ args.push('--config', options.config);
24
+ }
26
25
 
27
- if (options.configFile !== undefined) {
28
- args.push('--config-file', options.configFile);
29
- }
26
+ if (options.configFile !== undefined) {
27
+ args.push('--config-file', options.configFile);
28
+ }
30
29
 
31
- if (options.browser) {
32
- args.push('--browser', options.browser);
33
- }
30
+ if (options.browser) {
31
+ args.push('--browser', options.browser);
32
+ }
34
33
 
35
- if (options.env) {
36
- args.push('--env', options.env);
37
- }
34
+ if (options.env) {
35
+ args.push('--env', options.env);
36
+ }
38
37
 
39
- if (options.port) {
40
- args.push('--port', options.port);
41
- }
38
+ if (options.port) {
39
+ args.push('--port', options.port);
40
+ }
42
41
 
43
- if (options.project) {
44
- args.push('--project', options.project);
45
- }
42
+ if (options.project) {
43
+ args.push('--project', options.project);
44
+ }
45
+
46
+ args.push(...processTestingType(options.testingType));
47
+ debug('opening from options %j', options);
48
+ debug('command line arguments %j', args);
49
+ return args;
50
+ };
46
51
 
47
- args.push(...processTestingType(options.testingType));
48
- debug('opening from options %j', options);
49
- debug('command line arguments %j', args);
52
+ module.exports = {
53
+ processOpenOptions,
54
+
55
+ start(options = {}) {
56
+ const args = processOpenOptions(options);
50
57
 
51
58
  function open() {
52
59
  return spawn.start(args, {
package/lib/exec/spawn.js CHANGED
@@ -26,8 +26,18 @@ const errors = require('../errors');
26
26
 
27
27
  const isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
28
28
  const isHighSierraWarningRe = /\*\*\* WARNING/;
29
- const isRenderWorkerRe = /\.RenderWorker-/;
30
- const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe];
29
+ const isRenderWorkerRe = /\.RenderWorker-/; // Chromium (which Electron uses) always makes several attempts to connect to the system dbus.
30
+ // This works fine in most desktop environments, but in a docker container, there is no dbus service
31
+ // and Chromium emits several error lines, similar to these:
32
+ // [1957:0406/160550.146820:ERROR:bus.cc(392)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
33
+ // [1957:0406/160550.147994:ERROR:bus.cc(392)] Failed to connect to the bus: Address does not contain a colon
34
+ // These warnings are absolutely harmless. Failure to connect to dbus means that electron won't be able to access the user's
35
+ // credential wallet (none exists in a docker container) and won't show up in the system tray (again, none exists).
36
+ // Failure to connect is expected and normal here, but users frequently misidentify these errors as the cause of their problems.
37
+ // https://github.com/cypress-io/cypress/issues/19299
38
+
39
+ const isDbusWarning = /Failed to connect to the bus:/;
40
+ const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe, isDbusWarning];
31
41
 
32
42
  const isGarbageLineWarning = str => {
33
43
  return _.some(GARBAGE_WARNINGS, re => {
@@ -109,19 +119,23 @@ module.exports = {
109
119
  const envOverrides = util.getEnvOverrides(options);
110
120
  const electronArgs = [];
111
121
  const node11WindowsFix = isPlatform('win32');
122
+ let startScriptPath;
112
123
 
113
124
  if (options.dev) {
114
- // if we're in dev then reset
125
+ executable = 'node'; // if we're in dev then reset
115
126
  // the launch cmd to be 'npm run dev'
116
- executable = 'node';
117
- electronArgs.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
118
- debug('in dev mode the args became %o', args);
127
+
128
+ startScriptPath = path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'), debug('in dev mode the args became %o', args);
119
129
  }
120
130
 
121
131
  if (!options.dev && verify.needsSandbox()) {
122
132
  electronArgs.push('--no-sandbox');
123
133
  } // strip dev out of child process options
124
134
 
135
+ /**
136
+ * @type {import('child_process').ForkOptions}
137
+ */
138
+
125
139
 
126
140
  let stdioOptions = _.pick(options, 'env', 'detached', 'stdio'); // figure out if we're going to be force enabling or disabling colors.
127
141
  // also figure out whether we should force stdout and stderr into thinking
@@ -148,8 +162,7 @@ module.exports = {
148
162
 
149
163
  if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
150
164
  // Since we are running electron as node, we need to add an entry point file.
151
- const serverEntryPoint = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
152
- args = [serverEntryPoint, ...args];
165
+ startScriptPath = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
153
166
  } else {
154
167
  // Start arguments with "--" so Electron knows these are OUR
155
168
  // arguments and does not try to sanitize them. Otherwise on Windows
@@ -158,8 +171,12 @@ module.exports = {
158
171
  args = [...electronArgs, '--', ...args];
159
172
  }
160
173
 
161
- debug('spawning Cypress with executable: %s', executable);
174
+ if (startScriptPath) {
175
+ args.unshift(startScriptPath);
176
+ }
177
+
162
178
  debug('spawn args %o %o', args, _.omit(stdioOptions, 'env'));
179
+ debug('spawning Cypress with executable: %s', executable);
163
180
  const child = cp.spawn(executable, args, stdioOptions);
164
181
 
165
182
  function resolveOn(event) {
@@ -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'
@@ -79,8 +79,8 @@ const getCA = () => {
79
79
  const prepend = urlPath => {
80
80
  const endpoint = url.resolve(getBaseUrl(), urlPath);
81
81
  const platform = os.platform();
82
- const pathTemplate = util.getEnv('CYPRESS_DOWNLOAD_PATH_TEMPLATE');
83
- return pathTemplate ? pathTemplate.replace('${endpoint}', endpoint).replace('${platform}', platform).replace('${arch}', arch()) : `${endpoint}?platform=${platform}&arch=${arch()}`;
82
+ const pathTemplate = util.getEnv('CYPRESS_DOWNLOAD_PATH_TEMPLATE', true);
83
+ return pathTemplate ? pathTemplate.replace(/\\?\$\{endpoint\}/, endpoint).replace(/\\?\$\{platform\}/, platform).replace(/\\?\$\{arch\}/, arch()) : `${endpoint}?platform=${platform}&arch=${arch()}`;
84
84
  };
85
85
 
86
86
  const getUrl = version => {
@@ -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.slice(0, 8)].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.4",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node index.js --exec install",
@@ -39,7 +39,7 @@
39
39
  "listr2": "^3.8.3",
40
40
  "lodash": "^4.17.21",
41
41
  "log-symbols": "^4.0.0",
42
- "minimist": "^1.2.5",
42
+ "minimist": "^1.2.6",
43
43
  "ospath": "^1.2.2",
44
44
  "pretty-bytes": "^5.6.0",
45
45
  "proxy-from-env": "1.0.0",
@@ -64,6 +64,12 @@
64
64
  "node": ">=12.0.0"
65
65
  },
66
66
  "types": "types",
67
+ "buildInfo": {
68
+ "commitBranch": "develop",
69
+ "commitSha": "6934c0398fea92cc05714b18f21f7f06645a0b70",
70
+ "commitDate": "2022-04-11T17:25:33.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
+ }
@@ -30,4 +30,4 @@ interface NodeEventEmitter {
30
30
 
31
31
  // We use the Buffer class for dealing with binary data, especially around the
32
32
  // selectFile interface.
33
- type BufferType = import("buffer/").Buffer
33
+ type BufferType = typeof import("buffer/").Buffer
@@ -36,7 +36,7 @@ declare namespace CypressCommandLine {
36
36
  */
37
37
  interface CypressRunOptions extends CypressCommonOptions {
38
38
  /**
39
- * Specify different browser to run tests in, either by name or by filesystem path
39
+ * Specify browser to run tests in, either by name or by filesystem path
40
40
  */
41
41
  browser: string
42
42
  /**
@@ -118,7 +118,7 @@ declare namespace CypressCommandLine {
118
118
  */
119
119
  interface CypressOpenOptions extends CypressCommonOptions {
120
120
  /**
121
- * Specify a filesystem path to a custom browser
121
+ * Specify browser to run tests in, either by name or by filesystem path
122
122
  */
123
123
  browser: string
124
124
  /**
@@ -24,9 +24,15 @@ declare namespace Cypress {
24
24
  interface CommandFn<T extends keyof ChainableMethods> {
25
25
  (this: Mocha.Context, ...args: Parameters<ChainableMethods[T]>): ReturnType<ChainableMethods[T]> | void
26
26
  }
27
+ interface CommandFns {
28
+ [name: string]: (this: Mocha.Context, ...args: any) => any
29
+ }
27
30
  interface CommandFnWithSubject<T extends keyof ChainableMethods, S> {
28
31
  (this: Mocha.Context, prevSubject: S, ...args: Parameters<ChainableMethods[T]>): ReturnType<ChainableMethods[T]> | void
29
32
  }
33
+ interface CommandFnsWithSubject<S> {
34
+ [name: string]: (this: Mocha.Context, prevSubject: S, ...args: any) => any
35
+ }
30
36
  interface CommandOriginalFn<T extends keyof ChainableMethods> extends CallableFunction {
31
37
  (...args: Parameters<ChainableMethods[T]>): ReturnType<ChainableMethods[T]>
32
38
  }
@@ -467,6 +473,14 @@ declare namespace Cypress {
467
473
  add<T extends keyof Chainable, S extends PrevSubject>(
468
474
  name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject<T, PrevSubjectMap<void>[S]>,
469
475
  ): void
476
+ addAll<T extends keyof Chainable>(fns: CommandFns): void
477
+ addAll<T extends keyof Chainable>(options: CommandOptions & {prevSubject: false}, fns: CommandFns): void
478
+ addAll<T extends keyof Chainable, S extends PrevSubject>(
479
+ options: CommandOptions & { prevSubject: true | S | ['optional'] }, fns: CommandFnsWithSubject<PrevSubjectMap[S]>,
480
+ ): void
481
+ addAll<T extends keyof Chainable, S extends PrevSubject>(
482
+ options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject<PrevSubjectMap<void>[S]>,
483
+ ): void
470
484
  overwrite<T extends keyof Chainable>(name: T, fn: CommandFnWithOriginalFn<T>): void
471
485
  overwrite<T extends keyof Chainable, S extends PrevSubject>(name: T, fn: CommandFnWithOriginalFnAndSubject<T, PrevSubjectMap[S]>): void
472
486
  }
@@ -2341,7 +2355,7 @@ declare namespace Cypress {
2341
2355
  type Agent<T extends sinon.SinonSpy> = SinonSpyAgent<T> & T
2342
2356
 
2343
2357
  interface CookieDefaults {
2344
- preserve: string | string[] | RegExp | ((cookie: any) => boolean)
2358
+ preserve: string | string[] | RegExp | ((cookie: Cookie) => boolean)
2345
2359
  }
2346
2360
 
2347
2361
  interface Failable {
@@ -3347,7 +3361,7 @@ declare namespace Cypress {
3347
3361
  (chainer: 'be.a', type: string): Chainable<Subject>
3348
3362
  /**
3349
3363
  * Asserts that the target is a number or a date greater than the given number or date n respectively.
3350
- * However, its often best to assert that the target is equal to its expected value.
3364
+ * However, it's often best to assert that the target is equal to its expected value.
3351
3365
  * @example
3352
3366
  * cy.wrap(6).should('be.above', 5)
3353
3367
  * @see http://chaijs.com/api/bdd/#method_above
@@ -3367,7 +3381,7 @@ declare namespace Cypress {
3367
3381
  (chainer: 'be.an', value: string): Chainable<Subject>
3368
3382
  /**
3369
3383
  * Asserts that the target is a number or a `n` date greater than or equal to the given number or date n respectively.
3370
- * However, its often best to assert that the target is equal to its expected value.
3384
+ * However, it's often best to assert that the target is equal to its expected value.
3371
3385
  * @example
3372
3386
  * cy.wrap(6).should('be.at.least', 5)
3373
3387
  * @see http://chaijs.com/api/bdd/#method_least
@@ -3376,7 +3390,7 @@ declare namespace Cypress {
3376
3390
  (chainer: 'be.at.least', value: number | Date): Chainable<Subject>
3377
3391
  /**
3378
3392
  * Asserts that the target is a number or a `n` date less than or equal to the given number or date n respectively.
3379
- * However, its often best to assert that the target is equal to its expected value.
3393
+ * However, it's often best to assert that the target is equal to its expected value.
3380
3394
  * @example
3381
3395
  * cy.wrap(4).should('be.below', 5)
3382
3396
  * @see http://chaijs.com/api/bdd/#method_below
@@ -3392,7 +3406,7 @@ declare namespace Cypress {
3392
3406
  */
3393
3407
  (chainer: 'be.arguments'): Chainable<Subject>
3394
3408
  /**
3395
- * Asserts that the target is a number that’s within a given +/- `delta` range of the given number `expected`. However, its often best to assert that the target is equal to its expected value.
3409
+ * Asserts that the target is a number that’s within a given +/- `delta` range of the given number `expected`. However, it's often best to assert that the target is equal to its expected value.
3396
3410
  * @example
3397
3411
  * cy.wrap(5.1).should('be.approximately', 5, 0.5)
3398
3412
  * @alias closeTo
@@ -3401,7 +3415,7 @@ declare namespace Cypress {
3401
3415
  */
3402
3416
  (chainer: 'be.approximately', value: number, delta: number): Chainable<Subject>
3403
3417
  /**
3404
- * Asserts that the target is a number that’s within a given +/- `delta` range of the given number `expected`. However, its often best to assert that the target is equal to its expected value.
3418
+ * Asserts that the target is a number that’s within a given +/- `delta` range of the given number `expected`. However, it's often best to assert that the target is equal to its expected value.
3405
3419
  * @example
3406
3420
  * cy.wrap(5.1).should('be.closeTo', 5, 0.5)
3407
3421
  * @see http://chaijs.com/api/bdd/#method_closeto
@@ -3435,7 +3449,7 @@ declare namespace Cypress {
3435
3449
  (chainer: 'be.false'): Chainable<Subject>
3436
3450
  /**
3437
3451
  * Asserts that the target is a number or a date greater than the given number or date n respectively.
3438
- * However, its often best to assert that the target is equal to its expected value.
3452
+ * However, it's often best to assert that the target is equal to its expected value.
3439
3453
  * @example
3440
3454
  * cy.wrap(6).should('be.greaterThan', 5)
3441
3455
  * @alias above
@@ -3445,7 +3459,7 @@ declare namespace Cypress {
3445
3459
  (chainer: 'be.greaterThan', value: number): Chainable<Subject>
3446
3460
  /**
3447
3461
  * Asserts that the target is a number or a date greater than the given number or date n respectively.
3448
- * However, its often best to assert that the target is equal to its expected value.
3462
+ * However, it's often best to assert that the target is equal to its expected value.
3449
3463
  * @example
3450
3464
  * cy.wrap(6).should('be.gt', 5)
3451
3465
  * @alias above
@@ -3455,7 +3469,7 @@ declare namespace Cypress {
3455
3469
  (chainer: 'be.gt', value: number): Chainable<Subject>
3456
3470
  /**
3457
3471
  * Asserts that the target is a number or a `n` date greater than or equal to the given number or date n respectively.
3458
- * However, its often best to assert that the target is equal to its expected value.
3472
+ * However, it's often best to assert that the target is equal to its expected value.
3459
3473
  * @example
3460
3474
  * cy.wrap(6).should('be.gte', 5)
3461
3475
  * @alias least
@@ -3465,7 +3479,7 @@ declare namespace Cypress {
3465
3479
  (chainer: 'be.gte', value: number): Chainable<Subject>
3466
3480
  /**
3467
3481
  * Asserts that the target is a number or a `n` date less than or equal to the given number or date n respectively.
3468
- * However, its often best to assert that the target is equal to its expected value.
3482
+ * However, it's often best to assert that the target is equal to its expected value.
3469
3483
  * @example
3470
3484
  * cy.wrap(4).should('be.lessThan', 5)
3471
3485
  * @alias below
@@ -3475,7 +3489,7 @@ declare namespace Cypress {
3475
3489
  (chainer: 'be.lessThan', value: number): Chainable<Subject>
3476
3490
  /**
3477
3491
  * Asserts that the target is a number or a `n` date less than or equal to the given number or date n respectively.
3478
- * However, its often best to assert that the target is equal to its expected value.
3492
+ * However, it's often best to assert that the target is equal to its expected value.
3479
3493
  * @example
3480
3494
  * cy.wrap(4).should('be.lt', 5)
3481
3495
  * @alias below
@@ -3485,7 +3499,7 @@ declare namespace Cypress {
3485
3499
  (chainer: 'be.lt', value: number): Chainable<Subject>
3486
3500
  /**
3487
3501
  * Asserts that the target is a number or a date less than or equal to the given number or date n respectively.
3488
- * However, its often best to assert that the target is equal to its expected value.
3502
+ * However, it's often best to assert that the target is equal to its expected value.
3489
3503
  * @example
3490
3504
  * cy.wrap(4).should('be.lte', 5)
3491
3505
  * @alias most
@@ -3494,7 +3508,7 @@ declare namespace Cypress {
3494
3508
  */
3495
3509
  (chainer: 'be.lte', value: number): Chainable<Subject>
3496
3510
  /**
3497
- * Asserts that the target is loosely (`==`) equal to `true`. However, its often best to assert that the target is strictly (`===`) or deeply equal to its expected value.
3511
+ * Asserts that the target is loosely (`==`) equal to `true`. However, it's often best to assert that the target is strictly (`===`) or deeply equal to its expected value.
3498
3512
  * @example
3499
3513
  * cy.wrap(1).should('be.ok')
3500
3514
  * @see http://chaijs.com/api/bdd/#method_ok
@@ -3535,7 +3549,7 @@ declare namespace Cypress {
3535
3549
  (chainer: 'be.NaN'): Chainable<Subject>
3536
3550
  /**
3537
3551
  * Asserts that the target is a number or a date greater than or equal to the given number or date `start`, and less than or equal to the given number or date `finish` respectively.
3538
- * However, its often best to assert that the target is equal to its expected value.
3552
+ * However, it's often best to assert that the target is equal to its expected value.
3539
3553
  * @example
3540
3554
  * cy.wrap(6).should('be.within', 5, 10)
3541
3555
  * @see http://chaijs.com/api/bdd/#method_within
@@ -3544,8 +3558,8 @@ declare namespace Cypress {
3544
3558
  (chainer: 'be.within', start: number, end: number): Chainable<Subject>
3545
3559
  (chainer: 'be.within', start: Date, end: Date): Chainable<Subject>
3546
3560
  /**
3547
- * When one argument is provided, `.change` asserts that the given function `subject` returns a different value when its invoked before the target function compared to when its invoked afterward.
3548
- * However, its often best to assert that `subject` is equal to its expected value.
3561
+ * When one argument is provided, `.change` asserts that the given function `subject` returns a different value when it's invoked before the target function compared to when it's invoked afterward.
3562
+ * However, it's often best to assert that `subject` is equal to its expected value.
3549
3563
  * @example
3550
3564
  * let dots = ''
3551
3565
  * function addDot() { dots += '.' }
@@ -3575,8 +3589,8 @@ declare namespace Cypress {
3575
3589
  */
3576
3590
  (chainer: 'contain', value: any): Chainable<Subject>
3577
3591
  /**
3578
- * When one argument is provided, `.decrease` asserts that the given function `subject` returns a lesser number when its invoked after invoking the target function compared to when its invoked beforehand.
3579
- * `.decrease` also causes all `.by` assertions that follow in the chain to assert how much lesser of a number is returned. It’s often best to assert that the return value decreased by the expected amount, rather than asserting it decreased by any amount.
3592
+ * When one argument is provided, `.decrease` asserts that the given function `subject` returns a lesser number when it's invoked after invoking the target function compared to when it's invoked beforehand.
3593
+ * `.decrease` also causes all `.by` assertions that follow in the chain to assert how much lesser of a number is returned. it's often best to assert that the return value decreased by the expected amount, rather than asserting it decreased by any amount.
3580
3594
  * @example
3581
3595
  * let val = 1
3582
3596
  * function subtractTwo() { val -= 2 }
@@ -3606,7 +3620,7 @@ declare namespace Cypress {
3606
3620
  */
3607
3621
  (chainer: 'deep.equal', value: Subject): Chainable<Subject>
3608
3622
  /**
3609
- * Asserts that the target is not strictly (`===`) equal to either `null` or `undefined`. However, its often best to assert that the target is equal to its expected value.
3623
+ * Asserts that the target is not strictly (`===`) equal to either `null` or `undefined`. However, it's often best to assert that the target is equal to its expected value.
3610
3624
  * @example
3611
3625
  * cy.wrap(1).should('exist')
3612
3626
  * @see http://chaijs.com/api/bdd/#method_exist
@@ -3825,10 +3839,10 @@ declare namespace Cypress {
3825
3839
  */
3826
3840
  (chainer: 'include.members' | 'include.ordered.members' | 'include.deep.ordered.members', value: any[]): Chainable<Subject>
3827
3841
  /**
3828
- * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when its
3829
- * invoked after invoking the target function compared to when its invoked beforehand.
3842
+ * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when it's
3843
+ * invoked after invoking the target function compared to when it's invoked beforehand.
3830
3844
  * `.increase` also causes all `.by` assertions that follow in the chain to assert how much greater of a number is returned.
3831
- * It’s often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount.
3845
+ * it's often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount.
3832
3846
  *
3833
3847
  * When two arguments are provided, `.increase` asserts that the value of the given object `subject`’s `prop` property is greater after
3834
3848
  * invoking the target function compared to beforehand.
@@ -3875,7 +3889,7 @@ declare namespace Cypress {
3875
3889
  (chainer: 'satisfy', fn: (val: any) => boolean): Chainable<Subject>
3876
3890
  /**
3877
3891
  * When no arguments are provided, `.throw` invokes the target function and asserts that an error is thrown.
3878
- * When one argument is provided, and its a string, `.throw` invokes the target function and asserts that an error is thrown with a message that contains that string.
3892
+ * When one argument is provided, and it's a string, `.throw` invokes the target function and asserts that an error is thrown with a message that contains that string.
3879
3893
  * @example
3880
3894
  * function badFn() { throw new TypeError('Illegal salmon!') }
3881
3895
  * cy.wrap(badFn).should('throw')
@@ -3887,7 +3901,7 @@ declare namespace Cypress {
3887
3901
  (chainer: 'throw', value?: string | RegExp): Chainable<Subject>
3888
3902
  /**
3889
3903
  * When no arguments are provided, `.throw` invokes the target function and asserts that an error is thrown.
3890
- * When one argument is provided, and its a string, `.throw` invokes the target function and asserts that an error is thrown with a message that contains that string.
3904
+ * When one argument is provided, and it's a string, `.throw` invokes the target function and asserts that an error is thrown with a message that contains that string.
3891
3905
  * @example
3892
3906
  * function badFn() { throw new TypeError('Illegal salmon!') }
3893
3907
  * cy.wrap(badFn).should('throw')
@@ -3956,7 +3970,7 @@ declare namespace Cypress {
3956
3970
  (chainer: 'not.be.a', type: string): Chainable<Subject>
3957
3971
  /**
3958
3972
  * Asserts that the target is a not number or not a date greater than the given number or date n respectively.
3959
- * However, its often best to assert that the target is equal to its expected value.
3973
+ * However, it's often best to assert that the target is equal to its expected value.
3960
3974
  * @example
3961
3975
  * cy.wrap(6).should('not.be.above', 10)
3962
3976
  * @see http://chaijs.com/api/bdd/#method_above
@@ -3976,7 +3990,7 @@ declare namespace Cypress {
3976
3990
  (chainer: 'not.be.an', value: string): Chainable<Subject>
3977
3991
  /**
3978
3992
  * Asserts that the target is not a number or not a `n` date greater than or equal to the given number or date n respectively.
3979
- * However, its often best to assert that the target is equal to its expected value.
3993
+ * However, it's often best to assert that the target is equal to its expected value.
3980
3994
  * @example
3981
3995
  * cy.wrap(6).should('not.be.at.least', 10)
3982
3996
  * @see http://chaijs.com/api/bdd/#method_least
@@ -3985,7 +3999,7 @@ declare namespace Cypress {
3985
3999
  (chainer: 'not.be.at.least', value: number | Date): Chainable<Subject>
3986
4000
  /**
3987
4001
  * Asserts that the target is not a number or not a `n` date less than or equal to the given number or date n respectively.
3988
- * However, its often best to assert that the target is equal to its expected value.
4002
+ * However, it's often best to assert that the target is equal to its expected value.
3989
4003
  * @example
3990
4004
  * cy.wrap(4).should('not.be.below', 1)
3991
4005
  * @see http://chaijs.com/api/bdd/#method_below
@@ -4001,7 +4015,7 @@ declare namespace Cypress {
4001
4015
  */
4002
4016
  (chainer: 'not.be.arguments'): Chainable<Subject>
4003
4017
  /**
4004
- * Asserts that the target is a not number that’s within a given +/- `delta` range of the given number `expected`. However, its often best to assert that the target is equal to its expected value.
4018
+ * Asserts that the target is a not number that’s within a given +/- `delta` range of the given number `expected`. However, it's often best to assert that the target is equal to its expected value.
4005
4019
  * @example
4006
4020
  * cy.wrap(5.1).should('not.be.approximately', 6, 0.5)
4007
4021
  * @alias closeTo
@@ -4010,7 +4024,7 @@ declare namespace Cypress {
4010
4024
  */
4011
4025
  (chainer: 'not.be.approximately', value: number, delta: number): Chainable<Subject>
4012
4026
  /**
4013
- * Asserts that the target is not a number that’s within a given +/- `delta` range of the given number `expected`. However, its often best to assert that the target is equal to its expected value.
4027
+ * Asserts that the target is not a number that’s within a given +/- `delta` range of the given number `expected`. However, it's often best to assert that the target is equal to its expected value.
4014
4028
  * @example
4015
4029
  * cy.wrap(5.1).should('not.be.closeTo', 6, 0.5)
4016
4030
  * @see http://chaijs.com/api/bdd/#method_closeto
@@ -4044,7 +4058,7 @@ declare namespace Cypress {
4044
4058
  (chainer: 'not.be.false'): Chainable<Subject>
4045
4059
  /**
4046
4060
  * Asserts that the target is a not number or a date greater than the given number or date n respectively.
4047
- * However, its often best to assert that the target is equal to its expected value.
4061
+ * However, it's often best to assert that the target is equal to its expected value.
4048
4062
  * @example
4049
4063
  * cy.wrap(6).should('be.greaterThan', 7)
4050
4064
  * @alias above
@@ -4054,7 +4068,7 @@ declare namespace Cypress {
4054
4068
  (chainer: 'not.be.greaterThan', value: number): Chainable<Subject>
4055
4069
  /**
4056
4070
  * Asserts that the target is a not number or a date greater than the given number or date n respectively.
4057
- * However, its often best to assert that the target is equal to its expected value.
4071
+ * However, it's often best to assert that the target is equal to its expected value.
4058
4072
  * @example
4059
4073
  * cy.wrap(6).should('not.be.gt', 7)
4060
4074
  * @alias above
@@ -4064,7 +4078,7 @@ declare namespace Cypress {
4064
4078
  (chainer: 'not.be.gt', value: number): Chainable<Subject>
4065
4079
  /**
4066
4080
  * Asserts that the target is a not number or a `n` date greater than or equal to the given number or date n respectively.
4067
- * However, its often best to assert that the target is equal to its expected value.
4081
+ * However, it's often best to assert that the target is equal to its expected value.
4068
4082
  * @example
4069
4083
  * cy.wrap(6).should('not.be.gte', 7)
4070
4084
  * @alias least
@@ -4074,7 +4088,7 @@ declare namespace Cypress {
4074
4088
  (chainer: 'not.be.gte', value: number): Chainable<Subject>
4075
4089
  /**
4076
4090
  * Asserts that the target is not a number or a `n` date less than or equal to the given number or date n respectively.
4077
- * However, its often best to assert that the target is equal to its expected value.
4091
+ * However, it's often best to assert that the target is equal to its expected value.
4078
4092
  * @example
4079
4093
  * cy.wrap(4).should('not.be.lessThan', 3)
4080
4094
  * @alias below
@@ -4084,7 +4098,7 @@ declare namespace Cypress {
4084
4098
  (chainer: 'not.be.lessThan', value: number): Chainable<Subject>
4085
4099
  /**
4086
4100
  * Asserts that the target is not a number or a `n` date less than or equal to the given number or date n respectively.
4087
- * However, its often best to assert that the target is equal to its expected value.
4101
+ * However, it's often best to assert that the target is equal to its expected value.
4088
4102
  * @example
4089
4103
  * cy.wrap(4).should('not.be.lt', 3)
4090
4104
  * @alias below
@@ -4094,7 +4108,7 @@ declare namespace Cypress {
4094
4108
  (chainer: 'not.be.lt', value: number): Chainable<Subject>
4095
4109
  /**
4096
4110
  * Asserts that the target is not a number or a date less than or equal to the given number or date n respectively.
4097
- * However, its often best to assert that the target is equal to its expected value.
4111
+ * However, it's often best to assert that the target is equal to its expected value.
4098
4112
  * @example
4099
4113
  * cy.wrap(4).should('not.be.lte', 3)
4100
4114
  * @alias most
@@ -4103,7 +4117,7 @@ declare namespace Cypress {
4103
4117
  */
4104
4118
  (chainer: 'not.be.lte', value: number): Chainable<Subject>
4105
4119
  /**
4106
- * Asserts that the target is not loosely (`==`) equal to `true`. However, its often best to assert that the target is strictly (`===`) or deeply equal to its expected value.
4120
+ * Asserts that the target is not loosely (`==`) equal to `true`. However, it's often best to assert that the target is strictly (`===`) or deeply equal to its expected value.
4107
4121
  * @example
4108
4122
  * cy.wrap(0).should('not.be.ok')
4109
4123
  * @see http://chaijs.com/api/bdd/#method_ok
@@ -4144,7 +4158,7 @@ declare namespace Cypress {
4144
4158
  (chainer: 'not.be.NaN'): Chainable<Subject>
4145
4159
  /**
4146
4160
  * Asserts that the target is not a number or a date greater than or equal to the given number or date `start`, and less than or equal to the given number or date `finish` respectively.
4147
- * However, its often best to assert that the target is equal to its expected value.
4161
+ * However, it's often best to assert that the target is equal to its expected value.
4148
4162
  * @example
4149
4163
  * cy.wrap(3).should('not.be.within', 5, 10)
4150
4164
  * @see http://chaijs.com/api/bdd/#method_within
@@ -4153,8 +4167,8 @@ declare namespace Cypress {
4153
4167
  (chainer: 'not.be.within', start: number, end: number): Chainable<Subject>
4154
4168
  (chainer: 'not.be.within', start: Date, end: Date): Chainable<Subject>
4155
4169
  /**
4156
- * When one argument is provided, `.change` asserts that the given function `subject` returns a different value when its invoked before the target function compared to when its invoked afterward.
4157
- * However, its often best to assert that `subject` is equal to its expected value.
4170
+ * When one argument is provided, `.change` asserts that the given function `subject` returns a different value when it's invoked before the target function compared to when it's invoked afterward.
4171
+ * However, it's often best to assert that `subject` is equal to its expected value.
4158
4172
  * @example
4159
4173
  * let dots = ''
4160
4174
  * function addDot() { dots += '.' }
@@ -4184,8 +4198,8 @@ declare namespace Cypress {
4184
4198
  */
4185
4199
  (chainer: 'not.contain', value: any): Chainable<Subject>
4186
4200
  /**
4187
- * When one argument is provided, `.decrease` asserts that the given function `subject` does not returns a lesser number when its invoked after invoking the target function compared to when its invoked beforehand.
4188
- * `.decrease` also causes all `.by` assertions that follow in the chain to assert how much lesser of a number is returned. It’s often best to assert that the return value decreased by the expected amount, rather than asserting it decreased by any amount.
4201
+ * When one argument is provided, `.decrease` asserts that the given function `subject` does not returns a lesser number when it's invoked after invoking the target function compared to when it's invoked beforehand.
4202
+ * `.decrease` also causes all `.by` assertions that follow in the chain to assert how much lesser of a number is returned. it's often best to assert that the return value decreased by the expected amount, rather than asserting it decreased by any amount.
4189
4203
  * @example
4190
4204
  * let val = 1
4191
4205
  * function subtractTwo() { val -= 2 }
@@ -4214,7 +4228,7 @@ declare namespace Cypress {
4214
4228
  */
4215
4229
  (chainer: 'not.deep.equal', value: Subject): Chainable<Subject>
4216
4230
  /**
4217
- * Asserts that the target is not strictly (`===`) equal to either `null` or `undefined`. However, its often best to assert that the target is equal to its expected value.
4231
+ * Asserts that the target is not strictly (`===`) equal to either `null` or `undefined`. However, it's often best to assert that the target is equal to its expected value.
4218
4232
  * @example
4219
4233
  * cy.wrap(null).should('not.exist')
4220
4234
  * @see http://chaijs.com/api/bdd/#method_exist
@@ -4409,10 +4423,10 @@ declare namespace Cypress {
4409
4423
  */
4410
4424
  (chainer: 'not.include.members' | 'not.include.ordered.members' | 'not.include.deep.ordered.members', value: any[]): Chainable<Subject>
4411
4425
  /**
4412
- * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when its
4413
- * invoked after invoking the target function compared to when its invoked beforehand.
4426
+ * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when it's
4427
+ * invoked after invoking the target function compared to when it's invoked beforehand.
4414
4428
  * `.increase` also causes all `.by` assertions that follow in the chain to assert how much greater of a number is returned.
4415
- * It’s often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount.
4429
+ * it's often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount.
4416
4430
  *
4417
4431
  * When two arguments are provided, `.increase` asserts that the value of the given object `subject`’s `prop` property is greater after
4418
4432
  * invoking the target function compared to beforehand.
@@ -4459,7 +4473,7 @@ declare namespace Cypress {
4459
4473
  (chainer: 'not.satisfy', fn: (val: any) => boolean): Chainable<Subject>
4460
4474
  /**
4461
4475
  * When no arguments are provided, `.throw` invokes the target function and asserts that no error is thrown.
4462
- * When one argument is provided, and its a string, `.throw` invokes the target function and asserts that no error is thrown with a message that contains that string.
4476
+ * When one argument is provided, and it's a string, `.throw` invokes the target function and asserts that no error is thrown with a message that contains that string.
4463
4477
  * @example
4464
4478
  * function badFn() { console.log('Illegal salmon!') }
4465
4479
  * cy.wrap(badFn).should('not.throw')
@@ -4471,7 +4485,7 @@ declare namespace Cypress {
4471
4485
  (chainer: 'not.throw', value?: string | RegExp): Chainable<Subject>
4472
4486
  /**
4473
4487
  * When no arguments are provided, `.throw` invokes the target function and asserts that no error is thrown.
4474
- * When one argument is provided, and its a string, `.throw` invokes the target function and asserts that no error is thrown with a message that contains that string.
4488
+ * When one argument is provided, and it's a string, `.throw` invokes the target function and asserts that no error is thrown with a message that contains that string.
4475
4489
  * @example
4476
4490
  * function badFn() { console.log('Illegal salmon!') }
4477
4491
  * cy.wrap(badFn).should('not.throw')
@@ -5712,6 +5726,7 @@ declare namespace Cypress {
5712
5726
  name: string
5713
5727
  /** Override *name* for display purposes only */
5714
5728
  displayName: string
5729
+ /** additional information to include in the log */
5715
5730
  message: any
5716
5731
  /** Set to false if you want to control the finishing of the command in the log yourself */
5717
5732
  autoEnd: boolean