cypress 7.3.0 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ // Vendored from @cypress/listr-verbose-renderer
4
+ const figures = require('figures');
5
+
6
+ const cliCursor = require('cli-cursor');
7
+
8
+ const chalk = require('chalk');
9
+
10
+ const dayjs = require('dayjs');
11
+
12
+ const formattedLog = (options, output) => {
13
+ const timestamp = dayjs().format(options.dateFormat); // eslint-disable-next-line no-console
14
+
15
+ console.log(`${chalk.dim(`[${timestamp}]`)} ${output}`);
16
+ };
17
+
18
+ const renderHelper = (task, event, options) => {
19
+ const log = formattedLog.bind(undefined, options);
20
+
21
+ if (event.type === 'STATE') {
22
+ const message = task.isPending() ? 'started' : task.state;
23
+ log(`${task.title} [${message}]`);
24
+
25
+ if (task.isSkipped() && task.output) {
26
+ log(`${figures.arrowRight} ${task.output}`);
27
+ }
28
+ } else if (event.type === 'TITLE') {
29
+ log(`${task.title} [title changed]`);
30
+ }
31
+ };
32
+
33
+ const render = (tasks, options) => {
34
+ for (const task of tasks) {
35
+ task.subscribe(event => {
36
+ if (event.type === 'SUBTASKS') {
37
+ render(task.subtasks, options);
38
+ return;
39
+ }
40
+
41
+ renderHelper(task, event, options);
42
+ }, err => {
43
+ // eslint-disable-next-line no-console
44
+ console.log(err);
45
+ });
46
+ }
47
+ };
48
+
49
+ class VerboseRenderer {
50
+ constructor(tasks, options) {
51
+ this._tasks = tasks;
52
+ this._options = Object.assign({
53
+ dateFormat: 'HH:mm:ss'
54
+ }, options);
55
+ }
56
+
57
+ static get nonTTY() {
58
+ return true;
59
+ }
60
+
61
+ render() {
62
+ cliCursor.hide();
63
+ render(this._tasks, this._options);
64
+ }
65
+
66
+ end() {
67
+ cliCursor.show();
68
+ }
69
+
70
+ }
71
+
72
+ module.exports = VerboseRenderer;
package/lib/errors.js CHANGED
@@ -151,13 +151,9 @@ const invalidSmokeTestDisplayError = {
151
151
 
152
152
  ${hr}
153
153
 
154
- This is usually caused by a missing library or dependency.
154
+ This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
155
155
 
156
- The error above should indicate which dependency is missing.
157
-
158
- ${chalk.blue(requiredDependenciesUrl)}
159
-
160
- If you are using Docker, we provide containers with all required dependencies installed.
156
+ Please refer to the error above for more detail.
161
157
  `;
162
158
  }
163
159
 
@@ -166,13 +162,9 @@ const missingDependency = {
166
162
  description: 'Cypress failed to start.',
167
163
  // this message is too Linux specific
168
164
  solution: stripIndent`
169
- This is usually caused by a missing library or dependency.
170
-
171
- The error below should indicate which dependency is missing.
165
+ This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
172
166
 
173
- ${chalk.blue(requiredDependenciesUrl)}
174
-
175
- If you are using Docker, we provide containers with all required dependencies installed.
167
+ Please refer to the error below for more details.
176
168
  `
177
169
  };
178
170
  const invalidCacheDirectory = {
@@ -12,9 +12,9 @@ const chalk = require('chalk');
12
12
 
13
13
  const debug = require('debug')('cypress:cli');
14
14
 
15
- const Listr = require('listr');
16
-
17
- const verbose = require('@cypress/listr-verbose-renderer');
15
+ const {
16
+ Listr
17
+ } = require('listr2');
18
18
 
19
19
  const Promise = require('bluebird');
20
20
 
@@ -41,6 +41,8 @@ const {
41
41
  errors
42
42
  } = require('../errors');
43
43
 
44
+ const verbose = require('../VerboseRenderer');
45
+
44
46
  const getNpmArgv = () => {
45
47
  const json = process.env.npm_config_argv;
46
48
 
@@ -179,7 +181,9 @@ const downloadAndUnzip = ({
179
181
  logger.log(`Installing Cypress ${chalk.gray(`(version: ${version})`)}`);
180
182
  logger.log();
181
183
  const tasks = new Listr([{
182
- title: util.titleize('Downloading Cypress'),
184
+ options: {
185
+ title: util.titleize('Downloading Cypress')
186
+ },
183
187
  task: (ctx, task) => {
184
188
  // as our download progresses indicate the status
185
189
  progress.onProgress = progessify(task, 'Downloading Cypress');
@@ -201,7 +205,9 @@ const downloadAndUnzip = ({
201
205
  installDir,
202
206
  rendererOptions
203
207
  }), {
204
- title: util.titleize('Finishing Installation'),
208
+ options: {
209
+ title: util.titleize('Finishing Installation')
210
+ },
205
211
  task: (ctx, task) => {
206
212
  const cleanup = () => {
207
213
  debug('removing zip file %s', downloadDestination);
@@ -213,7 +219,9 @@ const downloadAndUnzip = ({
213
219
  util.setTaskTitle(task, util.titleize(chalk.green('Finished Installation'), chalk.gray(installDir)), rendererOptions.renderer);
214
220
  });
215
221
  }
216
- }], rendererOptions); // start the tasks!
222
+ }], {
223
+ rendererOptions
224
+ }); // start the tasks!
217
225
 
218
226
  return Promise.resolve(tasks.run());
219
227
  };
@@ -361,7 +369,9 @@ const start = (options = {}) => {
361
369
  zipFilePath: absolutePath,
362
370
  installDir,
363
371
  rendererOptions
364
- })], rendererOptions).run();
372
+ })], {
373
+ rendererOptions
374
+ }).run();
365
375
  }
366
376
 
367
377
  if (options.force) {
@@ -396,7 +406,9 @@ const unzipTask = ({
396
406
  rendererOptions
397
407
  }) => {
398
408
  return {
399
- title: util.titleize('Unzipping Cypress'),
409
+ options: {
410
+ title: util.titleize('Unzipping Cypress')
411
+ },
400
412
  task: (ctx, task) => {
401
413
  // as our unzip progresses indicate the status
402
414
  progress.onProgress = progessify(task, 'Unzipping Cypress');
@@ -78,23 +78,20 @@ const unzip = ({
78
78
 
79
79
  const unzipWithNode = () => {
80
80
  debug('unzipping with node.js (slow)');
81
-
82
- const endFn = err => {
83
- if (err) {
84
- debug('error %s', err.message);
85
- return reject(err);
86
- }
87
-
88
- debug('node unzip finished');
89
- return resolve();
90
- };
91
-
92
81
  const opts = {
93
82
  dir: installDir,
94
83
  onEntry: tick
95
84
  };
96
85
  debug('calling Node extract tool %s %o', zipFilePath, opts);
97
- return unzipTools.extract(zipFilePath, opts, endFn);
86
+ return unzipTools.extract(zipFilePath, opts).then(() => {
87
+ debug('node unzip finished');
88
+ return resolve();
89
+ }).catch(err => {
90
+ if (err) {
91
+ debug('error %s', err.message);
92
+ return reject(err);
93
+ }
94
+ });
98
95
  };
99
96
 
100
97
  const unzipFallback = _.once(unzipWithNode);
@@ -4,12 +4,12 @@ const _ = require('lodash');
4
4
 
5
5
  const chalk = require('chalk');
6
6
 
7
- const Listr = require('listr');
7
+ const {
8
+ Listr
9
+ } = require('listr2');
8
10
 
9
11
  const debug = require('debug')('cypress:cli');
10
12
 
11
- const verbose = require('@cypress/listr-verbose-renderer');
12
-
13
13
  const {
14
14
  stripIndent
15
15
  } = require('common-tags');
@@ -22,6 +22,8 @@ const path = require('path');
22
22
 
23
23
  const os = require('os');
24
24
 
25
+ const verbose = require('../VerboseRenderer');
26
+
25
27
  const {
26
28
  throwFormErrorText,
27
29
  errors
@@ -184,7 +186,9 @@ function testBinary(version, binaryDir, options) {
184
186
  renderer
185
187
  };
186
188
  const tasks = new Listr([{
187
- title: util.titleize('Verifying Cypress can run', chalk.gray(binaryDir)),
189
+ options: {
190
+ title: util.titleize('Verifying Cypress can run', chalk.gray(binaryDir))
191
+ },
188
192
  task: (ctx, task) => {
189
193
  debug('clearing out the verified version');
190
194
  return state.clearBinaryStateAsync(binaryDir).then(() => {
@@ -197,7 +201,9 @@ function testBinary(version, binaryDir, options) {
197
201
  util.setTaskTitle(task, util.titleize(chalk.green('Verified Cypress!'), chalk.gray(binaryDir)), rendererOptions.renderer);
198
202
  });
199
203
  }
200
- }], rendererOptions);
204
+ }], {
205
+ rendererOptions
206
+ });
201
207
  return tasks.run();
202
208
  }
203
209
 
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "cypress",
3
- "version": "7.3.0",
3
+ "version": "7.7.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node index.js --exec install",
7
7
  "size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";"
8
8
  },
9
9
  "dependencies": {
10
- "@cypress/listr-verbose-renderer": "^0.4.1",
11
10
  "@cypress/request": "^2.88.5",
12
11
  "@cypress/xvfb": "^1.2.4",
13
12
  "@types/node": "^14.14.31",
@@ -19,21 +18,24 @@
19
18
  "cachedir": "^2.3.0",
20
19
  "chalk": "^4.1.0",
21
20
  "check-more-types": "^2.24.0",
21
+ "cli-cursor": "^3.1.0",
22
22
  "cli-table3": "~0.6.0",
23
23
  "commander": "^5.1.0",
24
24
  "common-tags": "^1.8.0",
25
25
  "dayjs": "^1.10.4",
26
- "debug": "4.3.2",
26
+ "debug": "^4.3.2",
27
+ "enquirer": "^2.3.6",
27
28
  "eventemitter2": "^6.4.3",
28
29
  "execa": "4.1.0",
29
30
  "executable": "^4.1.1",
30
- "extract-zip": "^1.7.0",
31
+ "extract-zip": "2.0.1",
32
+ "figures": "^3.2.0",
31
33
  "fs-extra": "^9.1.0",
32
34
  "getos": "^3.2.1",
33
35
  "is-ci": "^3.0.0",
34
36
  "is-installed-globally": "~0.4.0",
35
37
  "lazy-ass": "^1.6.0",
36
- "listr": "^0.14.3",
38
+ "listr2": "^3.8.3",
37
39
  "lodash": "^4.17.21",
38
40
  "log-symbols": "^4.0.0",
39
41
  "minimist": "^1.2.5",
@@ -62,7 +64,6 @@
62
64
  },
63
65
  "types": "types",
64
66
  "description": "Cypress.io end to end testing tool",
65
- "author": "Brian Mann",
66
67
  "homepage": "https://github.com/cypress-io/cypress",
67
68
  "license": "MIT",
68
69
  "bugs": {
@@ -1949,6 +1949,8 @@ declare module "chai" {
1949
1949
  export = chai;
1950
1950
  }
1951
1951
 
1952
- interface Object {
1953
- should: Chai.Assertion;
1954
- }
1952
+ // const a = 1; a.should(1); doesn't work with Cypress
1953
+ // https://github.com/cypress-io/cypress/issues/16548
1954
+ // interface Object {
1955
+ // should: Chai.Assertion;
1956
+ // }
@@ -160,7 +160,7 @@ declare namespace CypressCommandLine {
160
160
  * Specify the type of tests to execute.
161
161
  * @default "e2e"
162
162
  */
163
- testingType: 'e2e' | 'component'
163
+ testingType: Cypress.TestingType
164
164
  }
165
165
 
166
166
  // small utility types to better express meaning of other types
@@ -8,6 +8,7 @@ declare namespace Cypress {
8
8
  type RequestBody = string | object
9
9
  type ViewportOrientation = 'portrait' | 'landscape'
10
10
  type PrevSubject = 'optional' | 'element' | 'document' | 'window'
11
+ type TestingType = 'e2e' | 'component'
11
12
  type PluginConfig = (on: PluginEvents, config: PluginConfigOptions) => void | ConfigOptions | Promise<ConfigOptions>
12
13
 
13
14
  interface CommandOptions {
@@ -59,7 +60,7 @@ declare namespace Cypress {
59
60
  */
60
61
  displayName: string
61
62
  version: string
62
- majorVersion: number
63
+ majorVersion: number | string
63
64
  path: string
64
65
  isHeaded: boolean
65
66
  isHeadless: boolean
@@ -251,6 +252,11 @@ declare namespace Cypress {
251
252
  */
252
253
  LocalStorage: LocalStorage
253
254
 
255
+ /**
256
+ * Current testing type, determined by the Test Runner chosen to run.
257
+ */
258
+ testingType: TestingType
259
+
254
260
  /**
255
261
  * Fire automation:request event for internal use.
256
262
  */
@@ -484,6 +490,13 @@ declare namespace Cypress {
484
490
  getElementCoordinatesByPositionRelativeToXY(element: JQuery | HTMLElement, x: number, y: number): ElementPositioning
485
491
  }
486
492
 
493
+ /**
494
+ * @see https://on.cypress.io/keyboard-api
495
+ */
496
+ Keyboard: {
497
+ defaults(options: Partial<KeyboardDefaultsOptions>): void
498
+ }
499
+
487
500
  /**
488
501
  * @see https://on.cypress.io/api/api-server
489
502
  */
@@ -835,7 +848,7 @@ declare namespace Cypress {
835
848
  * // tries to find the given text for up to 1 second
836
849
  * cy.contains('my text to find', {timeout: 1000})
837
850
  */
838
- contains(content: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable>): Chainable<Subject>
851
+ contains(content: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable & Shadow>): Chainable<Subject>
839
852
  /**
840
853
  * Get the child DOM element that contains given text.
841
854
  *
@@ -853,7 +866,7 @@ declare namespace Cypress {
853
866
  * // yields <ul>...</ul>
854
867
  * cy.contains('ul', 'apples')
855
868
  */
856
- contains<K extends keyof HTMLElementTagNameMap>(selector: K, text: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
869
+ contains<K extends keyof HTMLElementTagNameMap>(selector: K, text: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable & Shadow>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
857
870
  /**
858
871
  * Get the DOM element using CSS "selector" containing the text or regular expression.
859
872
  *
@@ -862,7 +875,7 @@ declare namespace Cypress {
862
875
  * // yields <... class="foo">... apples ...</...>
863
876
  * cy.contains('.foo', 'apples')
864
877
  */
865
- contains<E extends Node = HTMLElement>(selector: string, text: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable>): Chainable<JQuery<E>>
878
+ contains<E extends Node = HTMLElement>(selector: string, text: string | number | RegExp, options?: Partial<Loggable & Timeoutable & CaseMatchable & Shadow>): Chainable<JQuery<E>>
866
879
 
867
880
  /**
868
881
  * Double-click a DOM element.
@@ -1464,7 +1477,7 @@ declare namespace Cypress {
1464
1477
  * @example
1465
1478
  * cy.request('http://dev.local/seed')
1466
1479
  */
1467
- request(url: string, body?: RequestBody): Chainable<Response>
1480
+ request<T = any>(url: string, body?: RequestBody): Chainable<Response<T>>
1468
1481
  /**
1469
1482
  * Make an HTTP request with specific method.
1470
1483
  *
@@ -1472,7 +1485,7 @@ declare namespace Cypress {
1472
1485
  * @example
1473
1486
  * cy.request('POST', 'http://localhost:8888/users', {name: 'Jane'})
1474
1487
  */
1475
- request(method: HttpMethod, url: string, body?: RequestBody): Chainable<Response>
1488
+ request<T = any>(method: HttpMethod, url: string, body?: RequestBody): Chainable<Response<T>>
1476
1489
  /**
1477
1490
  * Make an HTTP request with specific behavior.
1478
1491
  *
@@ -1483,7 +1496,7 @@ declare namespace Cypress {
1483
1496
  * followRedirect: false // turn off following redirects
1484
1497
  * })
1485
1498
  */
1486
- request(options: Partial<RequestOptions>): Chainable<Response>
1499
+ request<T = any>(options: Partial<RequestOptions>): Chainable<Response<T>>
1487
1500
 
1488
1501
  /**
1489
1502
  * Get the root DOM element.
@@ -2750,8 +2763,6 @@ declare namespace Cypress {
2750
2763
  clientRoute: string
2751
2764
  configFile: string
2752
2765
  cypressEnv: string
2753
- integrationExampleName: string
2754
- integrationExamplePath: string
2755
2766
  isNewProject: boolean
2756
2767
  isTextTerminal: boolean
2757
2768
  morgan: boolean
@@ -2780,6 +2791,7 @@ declare namespace Cypress {
2780
2791
 
2781
2792
  interface TestConfigOverrides extends Partial<Pick<ConfigOptions, 'animationDistanceThreshold' | 'baseUrl' | 'defaultCommandTimeout' | 'env' | 'execTimeout' | 'includeShadowDom' | 'requestTimeout' | 'responseTimeout' | 'retries' | 'scrollBehavior' | 'taskTimeout' | 'viewportHeight' | 'viewportWidth' | 'waitForAnimations'>> {
2782
2793
  browser?: IsBrowserMatcher | IsBrowserMatcher[]
2794
+ keystrokeDelay?: number
2783
2795
  }
2784
2796
 
2785
2797
  /**
@@ -2799,7 +2811,7 @@ declare namespace Cypress {
2799
2811
  /**
2800
2812
  * Type of test and associated runner that was launched.
2801
2813
  */
2802
- testingType: 'e2e' | 'component'
2814
+ testingType: TestingType
2803
2815
  /**
2804
2816
  * Cypress version.
2805
2817
  */
@@ -2830,6 +2842,18 @@ declare namespace Cypress {
2830
2842
  env: object
2831
2843
  }
2832
2844
 
2845
+ /**
2846
+ * Options for Cypress.Keyboard.defaults()
2847
+ */
2848
+ interface KeyboardDefaultsOptions {
2849
+ /**
2850
+ * Time, in milliseconds, between each keystroke when typing. (Pass 0 to disable)
2851
+ *
2852
+ * @default 10
2853
+ */
2854
+ keystrokeDelay: number
2855
+ }
2856
+
2833
2857
  /**
2834
2858
  * Full set of possible options for cy.request call
2835
2859
  */
@@ -5496,9 +5520,9 @@ declare namespace Cypress {
5496
5520
  consoleProps(): ObjectLike
5497
5521
  }
5498
5522
 
5499
- interface Response {
5523
+ interface Response<T> {
5500
5524
  allRequestResponses: any[]
5501
- body: any
5525
+ body: T
5502
5526
  duration: number
5503
5527
  headers: { [key: string]: string | string[] }
5504
5528
  isOkStatusCode: boolean
@@ -175,37 +175,27 @@ declare namespace M {
175
175
  matchOne(files: string[], pattern: string[], partial: boolean): boolean;
176
176
 
177
177
  /**
178
- * Deprecated. For internal use.
179
- *
180
- * @private
178
+ * @deprecated. For internal use.
181
179
  */
182
180
  debug(): void;
183
181
 
184
182
  /**
185
- * Deprecated. For internal use.
186
- *
187
- * @private
183
+ * @deprecated. For internal use.
188
184
  */
189
185
  make(): void;
190
186
 
191
187
  /**
192
- * Deprecated. For internal use.
193
- *
194
- * @private
188
+ * @deprecated. For internal use.
195
189
  */
196
190
  parseNegate(): void;
197
191
 
198
192
  /**
199
- * Deprecated. For internal use.
200
- *
201
- * @private
193
+ * @deprecated. For internal use.
202
194
  */
203
195
  braceExpand(pattern: string, options: IOptions): void;
204
196
 
205
197
  /**
206
- * Deprecated. For internal use.
207
- *
208
- * @private
198
+ * @deprecated. For internal use.
209
199
  */
210
200
  parse(pattern: string, isSub?: boolean): void;
211
201
  }
@@ -79,7 +79,7 @@ export namespace CyHttpMessages {
79
79
  /**
80
80
  * The headers of the HTTP message.
81
81
  */
82
- headers: { [key: string]: string }
82
+ headers: { [key: string]: string | string[] }
83
83
  }
84
84
 
85
85
  export type IncomingResponse = BaseMessage & {
@@ -131,6 +131,10 @@ export namespace CyHttpMessages {
131
131
  * Request URL.
132
132
  */
133
133
  url: string
134
+ /**
135
+ * URL query string as object.
136
+ */
137
+ query: Record<string, string|number>
134
138
  /**
135
139
  * The HTTP version used in the request. Read only.
136
140
  */
@@ -383,7 +387,7 @@ export type RouteHandler = string | StaticResponse | RouteHandlerController | ob
383
387
  /**
384
388
  * Describes a response that will be sent back to the browser to fulfill the request.
385
389
  */
386
- export type StaticResponse = GenericStaticResponse<string, string | object | boolean | null> & {
390
+ export type StaticResponse = GenericStaticResponse<string, string | object | boolean | ArrayBuffer | null> & {
387
391
  /**
388
392
  * Milliseconds to delay before the response is sent.
389
393
  * @deprecated Use `delay` instead of `delayMs`.