cypress 6.9.1 → 7.0.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.
package/lib/cli.js CHANGED
@@ -143,7 +143,7 @@ const descriptions = {
143
143
  tag: 'named tag(s) for recorded runs in the Cypress Dashboard',
144
144
  version: 'prints Cypress version'
145
145
  };
146
- const knownCommands = ['cache', 'help', '-h', '--help', 'install', 'open', 'open-ct', 'run', 'run-ct', 'verify', '-v', '--version', 'version', 'info'];
146
+ const knownCommands = ['cache', 'help', '-h', '--help', 'install', 'open', 'run', 'open-ct', 'run-ct', 'verify', '-v', '--version', 'version', 'info'];
147
147
 
148
148
  const text = description => {
149
149
  if (!descriptions[description]) {
@@ -317,36 +317,30 @@ module.exports = {
317
317
  program.option('-v, --version', text('version')).command('version').description(text('version')).action(() => {
318
318
  showVersions(args);
319
319
  });
320
+ 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 => {
321
+ debug('opening Cypress');
322
+
323
+ require('./exec/open').start(util.parseOpts(opts)).catch(util.logErrorExit1);
324
+ });
320
325
  addCypressRunCommand(program).action((...fnArgs) => {
321
326
  debug('running Cypress with args %o', fnArgs);
322
327
 
323
328
  require('./exec/run').start(parseVariableOpts(fnArgs, args)).then(util.exit).catch(util.logErrorExit1);
324
329
  });
325
- program // TODO make this command public once CT will be merged completely
326
- .command('open-ct', {
327
- hidden: true
328
- }).usage('[options]').description('Opens Cypress component testing interactive mode.').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 => {
330
+ program.command('open-ct').usage('[options]').description('Opens Cypress component testing interactive mode.').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
331
  debug('opening Cypress');
330
332
 
331
333
  require('./exec/open').start(util.parseOpts(opts), {
332
334
  isComponentTesting: true
333
335
  }).catch(util.logErrorExit1);
334
336
  });
335
- program // TODO make this command public once CT will be merged completely
336
- .command('run-ct', {
337
- hidden: true
338
- }).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 => {
337
+ 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 => {
339
338
  debug('running Cypress run-ct');
340
339
 
341
340
  require('./exec/run').start(util.parseOpts(opts), {
342
341
  isComponentTesting: true
343
342
  }).then(util.exit).catch(util.logErrorExit1);
344
343
  });
345
- 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 => {
346
- debug('opening Cypress');
347
-
348
- require('./exec/open').start(util.parseOpts(opts)).catch(util.logErrorExit1);
349
- });
350
344
  program.command('install').usage('[options]').description('Installs the Cypress executable matching this package\'s version').option('-f, --force', text('forceInstall')).action(opts => {
351
345
  require('./tasks/install').start(util.parseOpts(opts)).catch(util.logErrorExit1);
352
346
  });
package/lib/exec/open.js CHANGED
@@ -45,7 +45,7 @@ module.exports = {
45
45
  }
46
46
 
47
47
  if (isComponentTesting) {
48
- args.push('--componentTesting');
48
+ args.push('--testing-type', 'component');
49
49
  }
50
50
 
51
51
  debug('opening from options %j', options);
package/lib/exec/run.js CHANGED
@@ -201,7 +201,7 @@ module.exports = {
201
201
  }
202
202
 
203
203
  if (isComponentTesting) {
204
- args.push('--componentTesting');
204
+ args.push('--testing-type', 'component');
205
205
  }
206
206
 
207
207
  debug('run to spawn.start args %j', args);
package/lib/util.js CHANGED
@@ -212,7 +212,7 @@ const dequote = str => {
212
212
  };
213
213
 
214
214
  const parseOpts = opts => {
215
- opts = _.pick(opts, 'browser', 'cachePath', 'cacheList', 'cacheClear', 'cachePrune', 'ciBuildId', 'componentTesting', 'config', 'configFile', 'cypressVersion', 'destination', 'detached', 'dev', 'exit', 'env', 'force', 'global', 'group', 'headed', 'headless', 'key', 'path', 'parallel', 'port', 'project', 'quiet', 'reporter', 'reporterOptions', 'record', 'runProject', 'spec', 'tag');
215
+ opts = _.pick(opts, 'browser', 'cachePath', 'cacheList', 'cacheClear', 'cachePrune', 'ciBuildId', 'config', 'configFile', 'cypressVersion', 'destination', 'detached', 'dev', 'exit', 'env', 'force', 'global', 'group', 'headed', 'headless', 'key', 'path', 'parallel', 'port', 'project', 'quiet', 'reporter', 'reporterOptions', 'record', 'runProject', 'spec', 'tag');
216
216
 
217
217
  if (opts.exit) {
218
218
  opts = _.omit(opts, 'exit');
@@ -263,33 +263,7 @@ const util = {
263
263
  .mapValues(value => {
264
264
  // stringify to 1 or 0
265
265
  return value ? '1' : '0';
266
- }).extend(util.getNodeOptions(options)).value();
267
- },
268
-
269
- getNodeOptions(options, nodeVersion) {
270
- if (!nodeVersion) {
271
- nodeVersion = Number(process.versions.node.split('.')[0]);
272
- }
273
-
274
- if (options.dev && nodeVersion < 12) {
275
- // `node` is used instead of Electron when --dev is passed, so this won't work if Node is too old
276
- debug('NODE_OPTIONS=--max-http-header-size could not be set because we\'re in dev mode and Node is < 12.0.0');
277
- return;
278
- } // https://github.com/cypress-io/cypress/issues/5431
279
-
280
-
281
- const NODE_OPTIONS = `--max-http-header-size=${1024 ** 2}`;
282
-
283
- if (_.isString(process.env.NODE_OPTIONS)) {
284
- return {
285
- NODE_OPTIONS: `${NODE_OPTIONS} ${process.env.NODE_OPTIONS}`,
286
- ORIGINAL_NODE_OPTIONS: process.env.NODE_OPTIONS || ''
287
- };
288
- }
289
-
290
- return {
291
- NODE_OPTIONS
292
- };
266
+ }).value();
293
267
  },
294
268
 
295
269
  getForceTty() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cypress",
3
- "version": "6.9.1",
3
+ "version": "7.0.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node index.js --exec install",
@@ -10,11 +10,11 @@
10
10
  "@cypress/listr-verbose-renderer": "^0.4.1",
11
11
  "@cypress/request": "^2.88.5",
12
12
  "@cypress/xvfb": "^1.2.4",
13
- "@types/node": "12.12.50",
14
- "@types/sinonjs__fake-timers": "^6.0.1",
13
+ "@types/node": "^14.14.31",
14
+ "@types/sinonjs__fake-timers": "^6.0.2",
15
15
  "@types/sizzle": "^2.3.2",
16
- "arch": "^2.1.2",
17
- "blob-util": "2.0.2",
16
+ "arch": "^2.2.0",
17
+ "blob-util": "^2.0.2",
18
18
  "bluebird": "^3.7.2",
19
19
  "cachedir": "^2.3.0",
20
20
  "chalk": "^4.1.0",
@@ -22,27 +22,26 @@
22
22
  "cli-table3": "~0.6.0",
23
23
  "commander": "^5.1.0",
24
24
  "common-tags": "^1.8.0",
25
- "dayjs": "^1.9.3",
25
+ "dayjs": "^1.10.4",
26
26
  "debug": "4.3.2",
27
- "eventemitter2": "^6.4.2",
28
- "execa": "^4.0.2",
27
+ "eventemitter2": "^6.4.3",
28
+ "execa": "4.1.0",
29
29
  "executable": "^4.1.1",
30
30
  "extract-zip": "^1.7.0",
31
- "fs-extra": "^9.0.1",
31
+ "fs-extra": "^9.1.0",
32
32
  "getos": "^3.2.1",
33
- "is-ci": "^2.0.0",
34
- "is-installed-globally": "^0.3.2",
33
+ "is-ci": "^3.0.0",
34
+ "is-installed-globally": "~0.4.0",
35
35
  "lazy-ass": "^1.6.0",
36
36
  "listr": "^0.14.3",
37
- "lodash": "^4.17.19",
37
+ "lodash": "^4.17.21",
38
38
  "log-symbols": "^4.0.0",
39
39
  "minimist": "^1.2.5",
40
- "moment": "^2.29.1",
41
40
  "ospath": "^1.2.2",
42
- "pretty-bytes": "^5.4.1",
41
+ "pretty-bytes": "^5.6.0",
43
42
  "ramda": "~0.27.1",
44
43
  "request-progress": "^3.0.0",
45
- "supports-color": "^7.2.0",
44
+ "supports-color": "^8.1.1",
46
45
  "tmp": "~0.2.1",
47
46
  "untildify": "^4.0.0",
48
47
  "url": "^0.11.0",
@@ -59,7 +58,7 @@
59
58
  "cypress": "bin/cypress"
60
59
  },
61
60
  "engines": {
62
- "node": ">=10.0.0"
61
+ "node": ">=12.0.0"
63
62
  },
64
63
  "types": "types",
65
64
  "description": "Cypress.io end to end testing tool",
@@ -466,7 +466,7 @@ declare namespace Chai {
466
466
  equal<T>(actual: T, expected: T, message?: string): void;
467
467
 
468
468
  /**
469
- * Asserts non-strict inequality (==) of actual and expected.
469
+ * Asserts non-strict inequality (!=) of actual and expected.
470
470
  *
471
471
  * @type T Type of the objects.
472
472
  * @param actual Actual value.
@@ -486,7 +486,7 @@ declare namespace Chai {
486
486
  strictEqual<T>(actual: T, expected: T, message?: string): void;
487
487
 
488
488
  /**
489
- * Asserts strict inequality (==) of actual and expected.
489
+ * Asserts strict inequality (!==) of actual and expected.
490
490
  *
491
491
  * @type T Type of the objects.
492
492
  * @param actual Actual value.
@@ -113,7 +113,7 @@ declare namespace Cypress {
113
113
 
114
114
  /**
115
115
  * Spec type for the given test. "integration" is the default, but
116
- * tests run using experimentalComponentTesting will be "component"
116
+ * tests run using `open-ct` will be "component"
117
117
  *
118
118
  * @see https://on.cypress.io/experiments
119
119
  */
@@ -177,18 +177,6 @@ declare namespace Cypress {
177
177
  * @see https://on.cypress.io/minimatch
178
178
  */
179
179
  minimatch: typeof Minimatch.minimatch
180
- /**
181
- * @deprecated Will be removed in a future version.
182
- * Consider including your own datetime formatter in your tests.
183
- *
184
- * Cypress automatically includes moment.js and exposes it as Cypress.moment.
185
- *
186
- * @see https://on.cypress.io/moment
187
- * @see http://momentjs.com/
188
- * @example
189
- * const todaysDate = Cypress.moment().format("MMM DD, YYYY")
190
- */
191
- moment: Moment.MomentStatic
192
180
  /**
193
181
  * Cypress automatically includes Bluebird and exposes it as Cypress.Promise.
194
182
  *
@@ -527,6 +515,18 @@ declare namespace Cypress {
527
515
  * @see https://on.cypress.io/catalog-of-events#App-Events
528
516
  */
529
517
  off: Actions
518
+
519
+ /**
520
+ * Trigger action
521
+ * @private
522
+ */
523
+ action: (action: string, ...args: any[]) => void
524
+
525
+ /**
526
+ * Load files
527
+ * @private
528
+ */
529
+ onSpecWindow: (window: Window, specList: string[] | Array<() => Promise<void>>) => void
530
530
  }
531
531
 
532
532
  type CanReturnChainable = void | Chainable | Promise<unknown>
@@ -1784,7 +1784,7 @@ declare namespace Cypress {
1784
1784
  /**
1785
1785
  * Run a task in Node via the plugins file.
1786
1786
  *
1787
- * @see https://on.cypress.io/task
1787
+ * @see https://on.cypress.io/api/task
1788
1788
  */
1789
1789
  task<S = unknown>(event: string, arg?: any, options?: Partial<Loggable & Timeoutable>): Chainable<S>
1790
1790
 
@@ -1812,6 +1812,12 @@ declare namespace Cypress {
1812
1812
  * @see https://on.cypress.io/then
1813
1813
  */
1814
1814
  then<S>(options: Partial<Timeoutable>, fn: (this: ObjectLike, currentSubject: Subject) => PromiseLike<S>): Chainable<S>
1815
+ /**
1816
+ * Enables you to work with the subject yielded from the previous command / promise.
1817
+ *
1818
+ * @see https://on.cypress.io/then
1819
+ */
1820
+ then<S extends HTMLElement>(fn: (this: ObjectLike, currentSubject: Subject) => S): Chainable<JQuery<S>>
1815
1821
  /**
1816
1822
  * Enables you to work with the subject yielded from the previous command / promise.
1817
1823
  *
@@ -1824,6 +1830,12 @@ declare namespace Cypress {
1824
1830
  * @see https://on.cypress.io/then
1825
1831
  */
1826
1832
  then<S>(fn: (this: ObjectLike, currentSubject: Subject) => S): ThenReturn<Subject, S>
1833
+ /**
1834
+ * Enables you to work with the subject yielded from the previous command / promise.
1835
+ *
1836
+ * @see https://on.cypress.io/then
1837
+ */
1838
+ then<S extends HTMLElement>(options: Partial<Timeoutable>, fn: (this: ObjectLike, currentSubject: Subject) => S): Chainable<JQuery<S>>
1827
1839
  /**
1828
1840
  * Enables you to work with the subject yielded from the previous command / promise.
1829
1841
  *
@@ -1872,7 +1884,7 @@ declare namespace Cypress {
1872
1884
  * // or use this shortcut
1873
1885
  * cy.tick(5000).invoke('restore')
1874
1886
  */
1875
- tick(milliseconds: number): Chainable<Clock>
1887
+ tick(milliseconds: number, options?: Partial<Loggable>): Chainable<Clock>
1876
1888
 
1877
1889
  /**
1878
1890
  * Get the `document.title` property of the page that is currently active.
@@ -2138,6 +2150,21 @@ declare namespace Cypress {
2138
2150
  ```
2139
2151
  */
2140
2152
  writeFile<C extends FileContents>(filePath: string, contents: C, options?: Partial<WriteFileOptions>): Chainable<C>
2153
+ /**
2154
+ * Write to a file with the specified encoding and contents.
2155
+ *
2156
+ * An `encoding` option in `options` will override the `encoding` argument.
2157
+ *
2158
+ * @see https://on.cypress.io/writefile
2159
+ ```
2160
+ cy.writeFile('path/to/ascii.txt', 'Hello World', 'utf8', {
2161
+ flag: 'a+',
2162
+ }).then((text) => {
2163
+ expect(text).to.equal('Hello World') // true
2164
+ })
2165
+ ```
2166
+ */
2167
+ writeFile<C extends FileContents>(filePath: string, contents: C, encoding: Encodings, options?: Partial<WriteFileOptions>): Chainable<C>
2141
2168
 
2142
2169
  /**
2143
2170
  * jQuery library bound to the AUT
@@ -2495,6 +2522,11 @@ declare namespace Cypress {
2495
2522
  * @default "cypress/plugins/index.js"
2496
2523
  */
2497
2524
  pluginsFile: string | false
2525
+ /**
2526
+ * The application under test cannot redirect more than this limit.
2527
+ * @default 20
2528
+ */
2529
+ redirectionLimit: number
2498
2530
  /**
2499
2531
  * If `nodeVersion === 'system'` and a `node` executable is found, this will be the full filesystem path to that executable.
2500
2532
  * @default null
@@ -2608,6 +2640,18 @@ declare namespace Cypress {
2608
2640
  * @default false
2609
2641
  */
2610
2642
  includeShadowDom: boolean
2643
+
2644
+ /**
2645
+ * Override default config options for Component Testing runner.
2646
+ * @default {}
2647
+ */
2648
+ component: ResolvedConfigOptions
2649
+
2650
+ /**
2651
+ * Override default config options for E2E Testing runner.
2652
+ * @default {}
2653
+ */
2654
+ e2e: ResolvedConfigOptions
2611
2655
  }
2612
2656
 
2613
2657
  /**
@@ -2636,10 +2680,6 @@ declare namespace Cypress {
2636
2680
  * Path to folder containing component test files.
2637
2681
  */
2638
2682
  componentFolder: string
2639
- /**
2640
- * Whether component testing is enabled.
2641
- */
2642
- experimentalComponentTesting: boolean
2643
2683
  /**
2644
2684
  * Hosts mappings to IP addresses.
2645
2685
  */
@@ -2732,6 +2772,10 @@ declare namespace Cypress {
2732
2772
  * Absolute path to the root of the project
2733
2773
  */
2734
2774
  projectRoot: string
2775
+ /**
2776
+ * Type of test and associated runner that was launched.
2777
+ */
2778
+ testingType: 'e2e' | 'component'
2735
2779
  /**
2736
2780
  * Cypress version.
2737
2781
  */
@@ -5160,7 +5204,7 @@ declare namespace Cypress {
5160
5204
  */
5161
5205
  interface Actions {
5162
5206
  /**
5163
- * Fires when an uncaught exception occurs in your application.
5207
+ * Fires when an uncaught exception or unhandled rejection occurs in your application. If it's an unhandled rejection, the rejected promise will be the 3rd argument.
5164
5208
  * Cypress will fail the test when this fires.
5165
5209
  * Return `false` from this event and Cypress will not fail the test. Also useful for debugging purposes because the actual `error` instance is provided to you.
5166
5210
  * @see https://on.cypress.io/catalog-of-events#App-Events
@@ -5186,7 +5230,7 @@ declare namespace Cypress {
5186
5230
  })
5187
5231
  ```
5188
5232
  */
5189
- (action: 'uncaught:exception', fn: (error: Error, runnable: Mocha.Runnable) => false | void): Cypress
5233
+ (action: 'uncaught:exception', fn: (error: Error, runnable: Mocha.Runnable, promise?: Promise<any>) => false | void): Cypress
5190
5234
  /**
5191
5235
  * Fires when your app calls the global `window.confirm()` method.
5192
5236
  * Cypress will auto accept confirmations. Return `false` from this event and the confirmation will be canceled.
@@ -5425,7 +5469,7 @@ declare namespace Cypress {
5425
5469
  allRequestResponses: any[]
5426
5470
  body: any
5427
5471
  duration: number
5428
- headers: { [key: string]: string }
5472
+ headers: { [key: string]: string | string[] }
5429
5473
  isOkStatusCode: boolean
5430
5474
  redirects?: string[]
5431
5475
  redirectedToUrl?: string
package/types/index.d.ts CHANGED
@@ -9,7 +9,6 @@
9
9
 
10
10
  /// <reference path="./cy-blob-util.d.ts" />
11
11
  /// <reference path="./cy-bluebird.d.ts" />
12
- /// <reference path="./cy-moment.d.ts" />
13
12
  /// <reference path="./cy-minimatch.d.ts" />
14
13
  /// <reference path="./cy-chai.d.ts" />
15
14
  /// <reference path="./lodash/index.d.ts" />
@@ -68,19 +68,37 @@ type Method =
68
68
  | 'unlink'
69
69
  | 'unlock'
70
70
  | 'unsubscribe'
71
-
72
71
  export namespace CyHttpMessages {
73
72
  export interface BaseMessage {
74
- body?: any
73
+ /**
74
+ * The body of the HTTP message.
75
+ * If a JSON Content-Type was used and the body was valid JSON, this will be an object.
76
+ * If the body was binary content, this will be a buffer.
77
+ */
78
+ body: any
79
+ /**
80
+ * The headers of the HTTP message.
81
+ */
75
82
  headers: { [key: string]: string }
76
- url: string
77
- method?: Method
78
- httpVersion?: string
79
83
  }
80
84
 
81
85
  export type IncomingResponse = BaseMessage & {
86
+ /**
87
+ * The HTTP status code of the response.
88
+ */
82
89
  statusCode: number
90
+ /**
91
+ * The HTTP status message.
92
+ */
83
93
  statusMessage: string
94
+ /**
95
+ * Kilobits per second to send 'body'.
96
+ */
97
+ throttleKbps?: number
98
+ /**
99
+ * Milliseconds to delay before the response is sent.
100
+ */
101
+ delay?: number
84
102
  }
85
103
 
86
104
  export type IncomingHttpResponse = IncomingResponse & {
@@ -97,14 +115,30 @@ export namespace CyHttpMessages {
97
115
  /**
98
116
  * Wait for `delay` milliseconds before sending the response to the client.
99
117
  */
100
- delay: (delay: number) => IncomingHttpResponse
118
+ setDelay: (delay: number) => IncomingHttpResponse
101
119
  /**
102
120
  * Serve the response at `throttleKbps` kilobytes per second.
103
121
  */
104
- throttle: (throttleKbps: number) => IncomingHttpResponse
122
+ setThrottle: (throttleKbps: number) => IncomingHttpResponse
105
123
  }
106
124
 
107
125
  export type IncomingRequest = BaseMessage & {
126
+ /**
127
+ * Request HTTP method (GET, POST, ...).
128
+ */
129
+ method: string
130
+ /**
131
+ * Request URL.
132
+ */
133
+ url: string
134
+ /**
135
+ * The HTTP version used in the request. Read only.
136
+ */
137
+ httpVersion: string
138
+ /**
139
+ * If provided, the number of milliseconds before an upstream response to this request
140
+ * will time out and cause an error. By default, `responseTimeout` from config is used.
141
+ */
108
142
  responseTimeout?: number
109
143
  /**
110
144
  * Set if redirects should be followed when this request is made. By default, requests will
@@ -118,11 +152,17 @@ export namespace CyHttpMessages {
118
152
  alias?: string
119
153
  }
120
154
 
121
- export interface IncomingHttpRequest extends IncomingRequest {
155
+ export interface IncomingHttpRequest extends IncomingRequest, InterceptionEvents {
122
156
  /**
123
157
  * Destroy the request and respond with a network error.
124
158
  */
125
159
  destroy(): void
160
+ /**
161
+ * Send the request outgoing, skipping any other request handlers.
162
+ * If a function is passed, the request will be sent outgoing, and the function will be called
163
+ * with the response from the upstream server.
164
+ */
165
+ continue(interceptor?: HttpResponseInterceptor): void
126
166
  /**
127
167
  * Control the response to this request.
128
168
  * If a function is passed, the request will be sent outgoing, and the function will be called
@@ -145,6 +185,14 @@ export namespace CyHttpMessages {
145
185
  */
146
186
  redirect(location: string, statusCode?: number): void
147
187
  }
188
+
189
+ export interface ResponseComplete {
190
+ finalResBody?: BaseMessage['body']
191
+ }
192
+
193
+ export interface NetworkError {
194
+ error: any
195
+ }
148
196
  }
149
197
 
150
198
  export interface DictMatcher<T> {
@@ -175,14 +223,49 @@ export type HttpResponseInterceptor = (res: CyHttpMessages.IncomingHttpResponse)
175
223
  */
176
224
  export type NumberMatcher = number | number[]
177
225
 
226
+ /**
227
+ * Metadata for a subscription for an interception event.
228
+ */
229
+ export interface Subscription {
230
+ /**
231
+ * If not defined, this is a default subscription.
232
+ */
233
+ id?: string
234
+ routeId: string
235
+ eventName: string
236
+ await: boolean
237
+ skip?: boolean
238
+ }
239
+
240
+ interface InterceptionEvents {
241
+ /**
242
+ * Emitted before `response` and before any `req.continue` handlers.
243
+ * Modifications to `res` will be applied to the incoming response.
244
+ * If a promise is returned from `cb`, it will be awaited before processing other event handlers.
245
+ */
246
+ on(eventName: 'before:response', cb: HttpResponseInterceptor): Interception
247
+ /**
248
+ * Emitted after `before:response` and after any `req.continue` handlers - before the response is sent to the browser.
249
+ * Modifications to `res` will be applied to the incoming response.
250
+ * If a promise is returned from `cb`, it will be awaited before processing other event handlers.
251
+ */
252
+ on(eventName: 'response', cb: HttpResponseInterceptor): Interception
253
+ /**
254
+ * Emitted once the response to a request has finished sending to the browser.
255
+ * Modifications to `res` have no impact.
256
+ * If a promise is returned from `cb`, it will be awaited before processing other event handlers.
257
+ */
258
+ on(eventName: 'after:response', cb: (res: CyHttpMessages.IncomingResponse) => void | Promise<void>): Interception
259
+ }
260
+
178
261
  /**
179
262
  * Request/response cycle.
180
263
  */
181
- export interface Interception {
264
+ export interface Interception extends InterceptionEvents {
182
265
  id: string
183
- routeHandlerId: string
266
+ routeId: string
184
267
  /* @internal */
185
- log: any
268
+ log?: any
186
269
  request: CyHttpMessages.IncomingRequest
187
270
  /**
188
271
  * Was `cy.wait()` used to wait on this request?
@@ -190,8 +273,6 @@ export interface Interception {
190
273
  */
191
274
  requestWaited: boolean
192
275
  response?: CyHttpMessages.IncomingResponse
193
- /* @internal */
194
- responseHandler?: HttpResponseInterceptor
195
276
  /**
196
277
  * The error that occurred during this request.
197
278
  */
@@ -203,6 +284,11 @@ export interface Interception {
203
284
  responseWaited: boolean
204
285
  /* @internal */
205
286
  state: InterceptionState
287
+ /* @internal */
288
+ subscriptions: Array<{
289
+ subscription: Subscription
290
+ handler: (data: any) => Promise<void> | void
291
+ }>
206
292
  }
207
293
 
208
294
  export type InterceptionState =
@@ -250,16 +336,17 @@ export interface RouteMatcherOptionsGeneric<S> {
250
336
  * If 'false', only HTTP requests will be matched.
251
337
  */
252
338
  https?: boolean
253
- /**
254
- * If `true`, will match the supplied `url` against incoming `path`s.
255
- * Requires a `url` argument. Cannot be used with a `path` argument.
256
- */
257
- matchUrlAgainstPath?: boolean
258
339
  /**
259
340
  * Match against the request's HTTP method.
260
341
  * @default '*'
261
342
  */
262
343
  method?: S
344
+ /**
345
+ * If `true`, this will pass the request on to the next `RouteMatcher` after the request handler completes.
346
+ * Can only be used with a dynamic request handler.
347
+ * @default false
348
+ */
349
+ middleware?: boolean
263
350
  /**
264
351
  * Match on request path after the hostname, including query params.
265
352
  */
@@ -292,7 +379,7 @@ export type RouteHandler = string | StaticResponse | RouteHandlerController | ob
292
379
  /**
293
380
  * Describes a response that will be sent back to the browser to fulfill the request.
294
381
  */
295
- export type StaticResponse = GenericStaticResponse<string, string | object> & {
382
+ export type StaticResponse = GenericStaticResponse<string, string | object | boolean | null> & {
296
383
  /**
297
384
  * Milliseconds to delay before the response is sent.
298
385
  * @deprecated Use `delay` instead of `delayMs`.
@@ -332,7 +419,7 @@ export interface GenericStaticResponse<Fixture, Body> {
332
419
  /**
333
420
  * Milliseconds to delay before the response is sent.
334
421
  */
335
- delay?: number
422
+ delay?: number
336
423
  }
337
424
 
338
425
  /**
@@ -372,6 +459,8 @@ interface WaitOptions {
372
459
 
373
460
  declare global {
374
461
  namespace Cypress {
462
+ // TODO: Why is Subject unused?
463
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
375
464
  interface Chainable<Subject = any> {
376
465
  /**
377
466
  * Use `cy.intercept()` to stub and intercept HTTP requests and responses.
@@ -385,7 +474,7 @@ declare global {
385
474
  * })
386
475
  * @example
387
476
  * cy.intercept('https://localhost:7777/some-response', (req) => {
388
- * req.reply(res => {
477
+ * req.continue(res => {
389
478
  * res.body = 'some new body'
390
479
  * })
391
480
  * })
@@ -400,13 +489,16 @@ declare global {
400
489
  */
401
490
  intercept(method: Method, url: RouteMatcher, response?: RouteHandler): Chainable<null>
402
491
  /**
403
- * @deprecated Use `cy.intercept()` instead.
404
- */
405
- route2(url: RouteMatcher, response?: RouteHandler): Chainable<null>
406
- /**
407
- * @deprecated Use `cy.intercept()` instead.
492
+ * Use `cy.intercept()` to stub and intercept HTTP requests and responses.
493
+ *
494
+ * @see https://on.cypress.io/intercept
495
+ *
496
+ * @example
497
+ * cy.intercept('/fruits', { middleware: true }, (req) => { ... })
498
+ *
499
+ * @param mergeRouteMatcher Additional route matcher options to merge with `url`. Typically used for middleware.
408
500
  */
409
- route2(method: Method, url: RouteMatcher, response?: RouteHandler): Chainable<null>
501
+ intercept(url: string, mergeRouteMatcher: Omit<RouteMatcherOptions, 'url'>, response: RouteHandler): Chainable<null>
410
502
  /**
411
503
  * Wait for a specific request to complete.
412
504
  *
@@ -1,7 +0,0 @@
1
- import moment = require('moment')
2
- export = Moment
3
- export as namespace Moment
4
-
5
- declare namespace Moment {
6
- type MomentStatic = typeof moment
7
- }