cypress 6.7.1 → 7.0.0

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