cypress 5.6.0 → 6.2.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/README.md +1 -1
- package/lib/cli.js +55 -5
- package/lib/errors.js +0 -19
- package/lib/exec/run.js +2 -9
- package/lib/exec/versions.js +15 -3
- package/lib/tasks/install.js +1 -10
- package/lib/tasks/state.js +17 -3
- package/lib/tasks/verify.js +3 -1
- package/package.json +1 -1
- package/types/cypress-eventemitter.d.ts +21 -0
- package/types/cypress.d.ts +106 -83
- package/types/net-stubbing.ts +103 -25
package/README.md
CHANGED
package/lib/cli.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
+
// @ts-check
|
3
4
|
const _ = require('lodash');
|
4
5
|
|
5
6
|
const R = require('ramda');
|
@@ -156,11 +157,58 @@ function includesVersion(args) {
|
|
156
157
|
return _.includes(args, 'version') || _.includes(args, '--version') || _.includes(args, '-v');
|
157
158
|
}
|
158
159
|
|
159
|
-
function showVersions() {
|
160
|
+
function showVersions(args) {
|
160
161
|
debug('printing Cypress version');
|
161
|
-
|
162
|
+
debug('additional arguments %o', args);
|
163
|
+
const versionParser = commander.option('--component <package|binary|electron|node>', 'component to report version for').allowUnknownOption(true);
|
164
|
+
const parsed = versionParser.parse(args);
|
165
|
+
const parsedOptions = {
|
166
|
+
component: parsed.component
|
167
|
+
};
|
168
|
+
debug('parsed version arguments %o', parsedOptions);
|
169
|
+
|
170
|
+
const reportAllVersions = versions => {
|
162
171
|
logger.always('Cypress package version:', versions.package);
|
163
172
|
logger.always('Cypress binary version:', versions.binary);
|
173
|
+
logger.always('Electron version:', versions.electronVersion);
|
174
|
+
logger.always('Bundled Node version:', versions.electronNodeVersion);
|
175
|
+
};
|
176
|
+
|
177
|
+
const reportComponentVersion = (componentName, versions) => {
|
178
|
+
const names = {
|
179
|
+
package: 'package',
|
180
|
+
binary: 'binary',
|
181
|
+
electron: 'electronVersion',
|
182
|
+
node: 'electronNodeVersion'
|
183
|
+
};
|
184
|
+
|
185
|
+
if (!names[componentName]) {
|
186
|
+
throw new Error(`Unknown component name "${componentName}"`);
|
187
|
+
}
|
188
|
+
|
189
|
+
const name = names[componentName];
|
190
|
+
|
191
|
+
if (!versions[name]) {
|
192
|
+
throw new Error(`Cannot find version for component "${componentName}" under property "${name}"`);
|
193
|
+
}
|
194
|
+
|
195
|
+
const version = versions[name];
|
196
|
+
logger.always(version);
|
197
|
+
};
|
198
|
+
|
199
|
+
const defaultVersions = {
|
200
|
+
package: undefined,
|
201
|
+
binary: undefined,
|
202
|
+
electronVersion: undefined,
|
203
|
+
electronNodeVersion: undefined
|
204
|
+
};
|
205
|
+
return require('./exec/versions').getVersions().then((versions = defaultVersions) => {
|
206
|
+
if (parsedOptions.component) {
|
207
|
+
reportComponentVersion(parsedOptions.component, versions);
|
208
|
+
} else {
|
209
|
+
reportAllVersions(versions);
|
210
|
+
}
|
211
|
+
|
164
212
|
process.exit(0);
|
165
213
|
}).catch(util.logErrorExit1);
|
166
214
|
}
|
@@ -266,7 +314,9 @@ module.exports = {
|
|
266
314
|
program.command('help').description('Shows CLI help and exits').action(() => {
|
267
315
|
program.help();
|
268
316
|
});
|
269
|
-
program.option('-v, --version', text('version')).command('version').description(text('version')).action(
|
317
|
+
program.option('-v, --version', text('version')).command('version').description(text('version')).action(() => {
|
318
|
+
showVersions(args);
|
319
|
+
});
|
270
320
|
addCypressRunCommand(program).action((...fnArgs) => {
|
271
321
|
debug('running Cypress with args %o', fnArgs);
|
272
322
|
|
@@ -346,14 +396,14 @@ module.exports = {
|
|
346
396
|
// and now does not understand top level options
|
347
397
|
// .option('-v, --version').command('version')
|
348
398
|
// so we have to manually catch '-v, --version'
|
349
|
-
return showVersions();
|
399
|
+
return showVersions(args);
|
350
400
|
}
|
351
401
|
|
352
402
|
debug('program parsing arguments');
|
353
403
|
return program.parse(args);
|
354
404
|
}
|
355
405
|
|
356
|
-
};
|
406
|
+
}; // @ts-ignore
|
357
407
|
|
358
408
|
if (!module.parent) {
|
359
409
|
logger.error('This CLI module should be required from another Node module');
|
package/lib/errors.js
CHANGED
@@ -225,24 +225,6 @@ const childProcessKilled = (eventName, signal) => {
|
|
225
225
|
};
|
226
226
|
};
|
227
227
|
|
228
|
-
const removed = {
|
229
|
-
CYPRESS_BINARY_VERSION: {
|
230
|
-
description: stripIndent`
|
231
|
-
The environment variable CYPRESS_BINARY_VERSION has been renamed to CYPRESS_INSTALL_BINARY as of version ${chalk.green('3.0.0')}
|
232
|
-
`,
|
233
|
-
solution: stripIndent`
|
234
|
-
You should set CYPRESS_INSTALL_BINARY instead.
|
235
|
-
`
|
236
|
-
},
|
237
|
-
CYPRESS_SKIP_BINARY_INSTALL: {
|
238
|
-
description: stripIndent`
|
239
|
-
The environment variable CYPRESS_SKIP_BINARY_INSTALL has been removed as of version ${chalk.green('3.0.0')}
|
240
|
-
`,
|
241
|
-
solution: stripIndent`
|
242
|
-
To skip the binary install, set CYPRESS_INSTALL_BINARY=0
|
243
|
-
`
|
244
|
-
}
|
245
|
-
};
|
246
228
|
const CYPRESS_RUN_BINARY = {
|
247
229
|
notValid: value => {
|
248
230
|
const properFormat = `**/${state.getPlatformExecutable()}`;
|
@@ -404,7 +386,6 @@ module.exports = {
|
|
404
386
|
failedUnzip,
|
405
387
|
invalidCypressEnv,
|
406
388
|
invalidCacheDirectory,
|
407
|
-
removed,
|
408
389
|
CYPRESS_RUN_BINARY,
|
409
390
|
smokeTestFailure,
|
410
391
|
childProcessKilled,
|
package/lib/exec/run.js
CHANGED
@@ -78,13 +78,6 @@ const processRunOptions = (options = {}) => {
|
|
78
78
|
args.push('--browser', options.browser);
|
79
79
|
}
|
80
80
|
|
81
|
-
if (options.ci) {
|
82
|
-
// push to display the deprecation message
|
83
|
-
args.push('--ci'); // also automatically record
|
84
|
-
|
85
|
-
args.push('--record', true);
|
86
|
-
}
|
87
|
-
|
88
81
|
if (options.ciBuildId) {
|
89
82
|
args.push('--ci-build-id', options.ciBuildId);
|
90
83
|
}
|
@@ -124,7 +117,7 @@ const processRunOptions = (options = {}) => {
|
|
124
117
|
|
125
118
|
if (options.key == null) {
|
126
119
|
debug('--key is not set, looking up environment variable CYPRESS_RECORD_KEY');
|
127
|
-
options.key = util.getEnv('CYPRESS_RECORD_KEY')
|
120
|
+
options.key = util.getEnv('CYPRESS_RECORD_KEY');
|
128
121
|
} // if we have a key assume we're in record mode
|
129
122
|
|
130
123
|
|
@@ -150,7 +143,7 @@ const processRunOptions = (options = {}) => {
|
|
150
143
|
// already in ci mode, then send it up
|
151
144
|
|
152
145
|
|
153
|
-
if (options.record != null
|
146
|
+
if (options.record != null) {
|
154
147
|
args.push('--record', options.record);
|
155
148
|
} // if we have a specific reporter push that into the args
|
156
149
|
|
package/lib/exec/versions.js
CHANGED
@@ -34,11 +34,23 @@ const getVersions = () => {
|
|
34
34
|
}
|
35
35
|
|
36
36
|
return state.getBinaryDir();
|
37
|
-
}).then(state.
|
38
|
-
|
37
|
+
}).then(state.getBinaryPkgAsync).then(pkg => {
|
38
|
+
const versions = {
|
39
|
+
binary: state.getBinaryPkgVersion(pkg),
|
40
|
+
electronVersion: state.getBinaryElectronVersion(pkg),
|
41
|
+
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg)
|
42
|
+
};
|
43
|
+
debug('binary versions %o', versions);
|
44
|
+
return versions;
|
45
|
+
}).then(binaryVersions => {
|
46
|
+
const versions = {
|
39
47
|
package: util.pkgVersion(),
|
40
|
-
binary:
|
48
|
+
binary: binaryVersions.binary || 'not installed',
|
49
|
+
electronVersion: binaryVersions.electronVersion || 'not found',
|
50
|
+
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found'
|
41
51
|
};
|
52
|
+
debug('combined versions %o', versions);
|
53
|
+
return versions;
|
42
54
|
});
|
43
55
|
};
|
44
56
|
|
package/lib/tasks/install.js
CHANGED
@@ -219,15 +219,6 @@ const downloadAndUnzip = ({
|
|
219
219
|
};
|
220
220
|
|
221
221
|
const start = (options = {}) => {
|
222
|
-
// handle deprecated / removed
|
223
|
-
if (util.getEnv('CYPRESS_BINARY_VERSION')) {
|
224
|
-
return throwFormErrorText(errors.removed.CYPRESS_BINARY_VERSION)();
|
225
|
-
}
|
226
|
-
|
227
|
-
if (util.getEnv('CYPRESS_SKIP_BINARY_INSTALL')) {
|
228
|
-
return throwFormErrorText(errors.removed.CYPRESS_SKIP_BINARY_INSTALL)();
|
229
|
-
}
|
230
|
-
|
231
222
|
debug('installing with options %j', options);
|
232
223
|
|
233
224
|
_.defaults(options, {
|
@@ -279,7 +270,7 @@ const start = (options = {}) => {
|
|
279
270
|
${err.message}
|
280
271
|
`);
|
281
272
|
}).then(() => {
|
282
|
-
return Promise.all([state.
|
273
|
+
return Promise.all([state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion), getVersionSpecifier()]);
|
283
274
|
}).then(([binaryVersion, versionSpecifier]) => {
|
284
275
|
if (!binaryUrlOverride && versionSpecifier) {
|
285
276
|
const computedBinaryUrl = getBinaryUrlFromPrereleaseNpmUrl(versionSpecifier);
|
package/lib/tasks/state.js
CHANGED
@@ -8,6 +8,8 @@ const path = require('path');
|
|
8
8
|
|
9
9
|
const untildify = require('untildify');
|
10
10
|
|
11
|
+
const R = require('ramda');
|
12
|
+
|
11
13
|
const debug = require('debug')('cypress:cli');
|
12
14
|
|
13
15
|
const fs = require('../fs');
|
@@ -183,8 +185,13 @@ const writeBinaryVerifiedAsync = (verified, binaryDir) => {
|
|
183
185
|
const getPathToExecutable = binaryDir => {
|
184
186
|
return path.join(binaryDir, getPlatformExecutable());
|
185
187
|
};
|
188
|
+
/**
|
189
|
+
* Resolves with an object read from the binary app package.json file.
|
190
|
+
* If the file does not exist resolves with null
|
191
|
+
*/
|
192
|
+
|
186
193
|
|
187
|
-
const
|
194
|
+
const getBinaryPkgAsync = binaryDir => {
|
188
195
|
const pathToPackageJson = getBinaryPkgPath(binaryDir);
|
189
196
|
debug('Reading binary package.json from:', pathToPackageJson);
|
190
197
|
return fs.pathExistsAsync(pathToPackageJson).then(exists => {
|
@@ -192,15 +199,22 @@ const getBinaryPkgVersionAsync = binaryDir => {
|
|
192
199
|
return null;
|
193
200
|
}
|
194
201
|
|
195
|
-
return fs.readJsonAsync(pathToPackageJson)
|
202
|
+
return fs.readJsonAsync(pathToPackageJson);
|
196
203
|
});
|
197
204
|
};
|
198
205
|
|
206
|
+
const getBinaryPkgVersion = R.propOr(null, 'version');
|
207
|
+
const getBinaryElectronVersion = R.propOr(null, 'electronVersion');
|
208
|
+
const getBinaryElectronNodeVersion = R.propOr(null, 'electronNodeVersion');
|
199
209
|
module.exports = {
|
200
210
|
getPathToExecutable,
|
201
211
|
getPlatformExecutable,
|
202
|
-
|
212
|
+
// those names start to sound like Java
|
213
|
+
getBinaryElectronNodeVersion,
|
214
|
+
getBinaryElectronVersion,
|
215
|
+
getBinaryPkgVersion,
|
203
216
|
getBinaryVerifiedAsync,
|
217
|
+
getBinaryPkgAsync,
|
204
218
|
getBinaryPkgPath,
|
205
219
|
getBinaryDir,
|
206
220
|
getCacheDir,
|
package/lib/tasks/verify.js
CHANGED
@@ -284,7 +284,9 @@ const start = (options = {}) => {
|
|
284
284
|
}).tap(() => {
|
285
285
|
return debug('binaryDir is ', binaryDir);
|
286
286
|
}).then(() => {
|
287
|
-
return state.
|
287
|
+
return state.getBinaryPkgAsync(binaryDir);
|
288
|
+
}).then(pkg => {
|
289
|
+
return state.getBinaryPkgVersion(pkg);
|
288
290
|
}).then(binaryVersion => {
|
289
291
|
if (!binaryVersion) {
|
290
292
|
debug('no Cypress binary found for cli version ', packageVersion);
|
package/package.json
CHANGED
@@ -6,3 +6,24 @@ interface EventEmitter extends EventEmitter2 {
|
|
6
6
|
emitMap: (eventName: string, args: any[]) => Array<(...args: any[]) => any>
|
7
7
|
emitThen: (eventName: string, args: any[]) => Bluebird.BluebirdStatic
|
8
8
|
}
|
9
|
+
|
10
|
+
// Copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/events.d.ts
|
11
|
+
// to avoid type conflict.
|
12
|
+
interface NodeEventEmitter {
|
13
|
+
addListener(event: string | symbol, listener: (...args: any[]) => void): this
|
14
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this
|
15
|
+
once(event: string | symbol, listener: (...args: any[]) => void): this
|
16
|
+
removeListener(event: string | symbol, listener: (...args: any[]) => void): this
|
17
|
+
off(event: string | symbol, listener: (...args: any[]) => void): this
|
18
|
+
removeAllListeners(event?: string | symbol): this
|
19
|
+
setMaxListeners(n: number): this
|
20
|
+
getMaxListeners(): number
|
21
|
+
listeners(event: string | symbol): Array<(...args: any[]) => void>
|
22
|
+
rawListeners(event: string | symbol): Array<(...args: any[]) => void>
|
23
|
+
emit(event: string | symbol, ...args: any[]): boolean
|
24
|
+
listenerCount(type: string | symbol): number
|
25
|
+
// Added in Node 6...
|
26
|
+
prependListener(event: string | symbol, listener: (...args: any[]) => void): this
|
27
|
+
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this
|
28
|
+
eventNames(): Array<string | symbol>
|
29
|
+
}
|
package/types/cypress.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
/// <reference path="./cypress-npm-api.d.ts" />
|
2
|
+
|
1
3
|
declare namespace Cypress {
|
2
4
|
type FileContents = string | any[] | object
|
3
5
|
type HistoryDirection = 'back' | 'forward'
|
@@ -116,6 +118,17 @@ declare namespace Cypress {
|
|
116
118
|
*/
|
117
119
|
type CypressSpecType = 'integration' | 'component'
|
118
120
|
|
121
|
+
/**
|
122
|
+
* A Cypress spec.
|
123
|
+
*/
|
124
|
+
interface Spec {
|
125
|
+
name: string // "config_passing_spec.js"
|
126
|
+
relative: string // "cypress/integration/config_passing_spec.js" or "__all" if clicked all specs button
|
127
|
+
absolute: string // "/Users/janelane/app/cypress/integration/config_passing_spec.js"
|
128
|
+
specFilter?: string // optional spec filter used by the user
|
129
|
+
specType?: CypressSpecType
|
130
|
+
}
|
131
|
+
|
119
132
|
/**
|
120
133
|
* Window type for Application Under Test(AUT)
|
121
134
|
*/
|
@@ -164,6 +177,9 @@ declare namespace Cypress {
|
|
164
177
|
*/
|
165
178
|
minimatch: typeof Minimatch.minimatch
|
166
179
|
/**
|
180
|
+
* @deprecated Will be removed in a future version.
|
181
|
+
* Consider including your own datetime formatter in your tests.
|
182
|
+
*
|
167
183
|
* Cypress automatically includes moment.js and exposes it as Cypress.moment.
|
168
184
|
*
|
169
185
|
* @see https://on.cypress.io/moment
|
@@ -224,23 +240,17 @@ declare namespace Cypress {
|
|
224
240
|
/**
|
225
241
|
* Currently executing spec file.
|
226
242
|
* @example
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
243
|
+
* ```
|
244
|
+
* Cypress.spec
|
245
|
+
* // {
|
246
|
+
* // name: "config_passing_spec.coffee",
|
247
|
+
* // relative: "cypress/integration/config_passing_spec.coffee",
|
248
|
+
* // absolute: "/users/smith/projects/web/cypress/integration/config_passing_spec.coffee"
|
249
|
+
* // specType: "integration"
|
250
|
+
* // }
|
251
|
+
* ```
|
236
252
|
*/
|
237
|
-
spec:
|
238
|
-
name: string // "config_passing_spec.coffee"
|
239
|
-
relative: string // "cypress/integration/config_passing_spec.coffee" or "__all" if clicked all specs button
|
240
|
-
absolute: string
|
241
|
-
specFilter?: string // optional spec filter used by the user
|
242
|
-
specType?: CypressSpecType
|
243
|
-
}
|
253
|
+
spec: Spec
|
244
254
|
|
245
255
|
/**
|
246
256
|
* Information about the browser currently running the tests
|
@@ -421,7 +431,7 @@ declare namespace Cypress {
|
|
421
431
|
/**
|
422
432
|
* Returns a boolean indicating whether an element is hidden.
|
423
433
|
*/
|
424
|
-
isHidden(element: JQuery | HTMLElement): boolean
|
434
|
+
isHidden(element: JQuery | HTMLElement, methodName?: string, options?: object): boolean
|
425
435
|
/**
|
426
436
|
* Returns a boolean indicating whether an element can receive focus.
|
427
437
|
*/
|
@@ -474,7 +484,7 @@ declare namespace Cypress {
|
|
474
484
|
getContainsSelector(text: string, filter?: string): JQuery.Selector
|
475
485
|
getFirstDeepestElement(elements: HTMLElement[], index?: number): HTMLElement
|
476
486
|
getWindowByElement(element: JQuery | HTMLElement): JQuery | HTMLElement
|
477
|
-
getReasonIsHidden(element: JQuery | HTMLElement): string
|
487
|
+
getReasonIsHidden(element: JQuery | HTMLElement, options?: object): string
|
478
488
|
getFirstScrollableParent(element: JQuery | HTMLElement): JQuery | HTMLElement
|
479
489
|
getFirstFixedOrStickyPositionParent(element: JQuery | HTMLElement): JQuery | HTMLElement
|
480
490
|
getFirstStickyPositionParent(element: JQuery | HTMLElement): JQuery | HTMLElement
|
@@ -1477,8 +1487,9 @@ declare namespace Cypress {
|
|
1477
1487
|
root<E extends Node = HTMLHtmlElement>(options?: Partial<Loggable>): Chainable<JQuery<E>> // can't do better typing unless we ignore the `.within()` case
|
1478
1488
|
|
1479
1489
|
/**
|
1480
|
-
* Use `cy.
|
1490
|
+
* @deprecated Use `cy.intercept()` instead.
|
1481
1491
|
*
|
1492
|
+
* Use `cy.route()` to manage the behavior of network requests.
|
1482
1493
|
* @see https://on.cypress.io/route
|
1483
1494
|
* @example
|
1484
1495
|
* cy.server()
|
@@ -1486,6 +1497,8 @@ declare namespace Cypress {
|
|
1486
1497
|
*/
|
1487
1498
|
route(url: string | RegExp, response?: string | object): Chainable<null>
|
1488
1499
|
/**
|
1500
|
+
* @deprecated Use `cy.intercept()` instead.
|
1501
|
+
*
|
1489
1502
|
* Spy or stub request with specific method and url.
|
1490
1503
|
*
|
1491
1504
|
* @see https://on.cypress.io/route
|
@@ -1496,6 +1509,8 @@ declare namespace Cypress {
|
|
1496
1509
|
*/
|
1497
1510
|
route(method: string, url: string | RegExp, response?: string | object): Chainable<null>
|
1498
1511
|
/**
|
1512
|
+
* @deprecated Use `cy.intercept()` instead.
|
1513
|
+
*
|
1499
1514
|
* Set a route by returning an object literal from a callback function.
|
1500
1515
|
* Functions that return a Promise will automatically be awaited.
|
1501
1516
|
*
|
@@ -1514,6 +1529,8 @@ declare namespace Cypress {
|
|
1514
1529
|
*/
|
1515
1530
|
route(fn: () => RouteOptions): Chainable<null>
|
1516
1531
|
/**
|
1532
|
+
* @deprecated Use `cy.intercept()` instead.
|
1533
|
+
*
|
1517
1534
|
* Spy or stub a given route.
|
1518
1535
|
*
|
1519
1536
|
* @see https://on.cypress.io/route
|
@@ -1581,6 +1598,8 @@ declare namespace Cypress {
|
|
1581
1598
|
select(value: string | string[], options?: Partial<SelectOptions>): Chainable<Subject>
|
1582
1599
|
|
1583
1600
|
/**
|
1601
|
+
* @deprecated Use `cy.intercept()` instead.
|
1602
|
+
*
|
1584
1603
|
* Start a server to begin routing responses to `cy.route()` and `cy.request()`.
|
1585
1604
|
*
|
1586
1605
|
* @example
|
@@ -2013,50 +2032,6 @@ declare namespace Cypress {
|
|
2013
2032
|
* cy.wait(1000) // wait for 1 second
|
2014
2033
|
*/
|
2015
2034
|
wait(ms: number, options?: Partial<Loggable & Timeoutable>): Chainable<Subject>
|
2016
|
-
/**
|
2017
|
-
* Wait for a specific XHR to respond.
|
2018
|
-
*
|
2019
|
-
* @see https://on.cypress.io/wait
|
2020
|
-
* @param {string} alias - Name of the alias to wait for.
|
2021
|
-
*
|
2022
|
-
```
|
2023
|
-
// Wait for the route aliased as 'getAccount' to respond
|
2024
|
-
// without changing or stubbing its response
|
2025
|
-
cy.server()
|
2026
|
-
cy.route('/accounts/*').as('getAccount')
|
2027
|
-
cy.visit('/accounts/123')
|
2028
|
-
cy.wait('@getAccount').then((xhr) => {
|
2029
|
-
// we can now access the low level xhr
|
2030
|
-
// that contains the request body,
|
2031
|
-
// response body, status, etc
|
2032
|
-
})
|
2033
|
-
```
|
2034
|
-
*/
|
2035
|
-
wait(alias: string, options?: Partial<Loggable & Timeoutable & TimeoutableXHR>): Chainable<WaitXHR>
|
2036
|
-
/**
|
2037
|
-
* Wait for list of XHR requests to complete.
|
2038
|
-
*
|
2039
|
-
* @see https://on.cypress.io/wait
|
2040
|
-
* @param {string[]} aliases - An array of aliased routes as defined using the `.as()` command.
|
2041
|
-
*
|
2042
|
-
```
|
2043
|
-
// wait for 3 XHR requests to complete
|
2044
|
-
cy.server()
|
2045
|
-
cy.route('users/*').as('getUsers')
|
2046
|
-
cy.route('activities/*').as('getActivities')
|
2047
|
-
cy.route('comments/*').as('getComments')
|
2048
|
-
cy.visit('/dashboard')
|
2049
|
-
|
2050
|
-
cy.wait(['@getUsers', '@getActivities', '@getComments'])
|
2051
|
-
.then((xhrs) => {
|
2052
|
-
// xhrs will now be an array of matching XHR's
|
2053
|
-
// xhrs[0] <-- getUsers
|
2054
|
-
// xhrs[1] <-- getActivities
|
2055
|
-
// xhrs[2] <-- getComments
|
2056
|
-
})
|
2057
|
-
```
|
2058
|
-
*/
|
2059
|
-
wait(alias: string[], options?: Partial<Loggable & Timeoutable & TimeoutableXHR>): Chainable<WaitXHR[]>
|
2060
2035
|
|
2061
2036
|
/**
|
2062
2037
|
* Get the window object of the page that is currently active.
|
@@ -2322,20 +2297,46 @@ declare namespace Cypress {
|
|
2322
2297
|
force: boolean
|
2323
2298
|
}
|
2324
2299
|
|
2300
|
+
type scrollBehaviorOptions = false | 'center' | 'top' | 'bottom' | 'nearest'
|
2301
|
+
|
2302
|
+
/**
|
2303
|
+
* Options to affect Actionability checks
|
2304
|
+
* @see https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Actionability
|
2305
|
+
*/
|
2306
|
+
interface ActionableOptions extends Forceable {
|
2307
|
+
/**
|
2308
|
+
* Whether to wait for elements to finish animating before executing commands
|
2309
|
+
*
|
2310
|
+
* @default true
|
2311
|
+
*/
|
2312
|
+
waitForAnimations: boolean
|
2313
|
+
/**
|
2314
|
+
* The distance in pixels an element must exceed over time to be considered animating
|
2315
|
+
* @default 5
|
2316
|
+
*/
|
2317
|
+
animationDistanceThreshold: number
|
2318
|
+
/**
|
2319
|
+
* Viewport position to which an element should be scrolled prior to action commands. Setting `false` disables scrolling.
|
2320
|
+
*
|
2321
|
+
* @default 'top'
|
2322
|
+
*/
|
2323
|
+
scrollBehavior: scrollBehaviorOptions
|
2324
|
+
}
|
2325
|
+
|
2325
2326
|
interface BlurOptions extends Loggable, Forceable { }
|
2326
2327
|
|
2327
|
-
interface CheckOptions extends Loggable, Timeoutable,
|
2328
|
+
interface CheckOptions extends Loggable, Timeoutable, ActionableOptions {
|
2328
2329
|
interval: number
|
2329
2330
|
}
|
2330
2331
|
|
2331
|
-
interface ClearOptions extends Loggable, Timeoutable,
|
2332
|
+
interface ClearOptions extends Loggable, Timeoutable, ActionableOptions {
|
2332
2333
|
interval: number
|
2333
2334
|
}
|
2334
2335
|
|
2335
2336
|
/**
|
2336
2337
|
* Object to change the default behavior of .click().
|
2337
2338
|
*/
|
2338
|
-
interface ClickOptions extends Loggable, Timeoutable,
|
2339
|
+
interface ClickOptions extends Loggable, Timeoutable, ActionableOptions {
|
2339
2340
|
/**
|
2340
2341
|
* Serially click multiple elements
|
2341
2342
|
*
|
@@ -2563,6 +2564,11 @@ declare namespace Cypress {
|
|
2563
2564
|
* @default true
|
2564
2565
|
*/
|
2565
2566
|
waitForAnimations: boolean
|
2567
|
+
/**
|
2568
|
+
* Viewport position to which an element should be scrolled prior to action commands. Setting `false` disables scrolling.
|
2569
|
+
* @default 'top'
|
2570
|
+
*/
|
2571
|
+
scrollBehavior: scrollBehaviorOptions
|
2566
2572
|
/**
|
2567
2573
|
* Firefox version 79 and below only: The number of tests that will run between forced garbage collections.
|
2568
2574
|
* If a number is supplied, it will apply to `run` mode and `open` mode.
|
@@ -2571,16 +2577,16 @@ declare namespace Cypress {
|
|
2571
2577
|
*/
|
2572
2578
|
firefoxGcInterval: Nullable<number | { runMode: Nullable<number>, openMode: Nullable<number> }>
|
2573
2579
|
/**
|
2574
|
-
*
|
2575
|
-
* algorithm.
|
2580
|
+
* Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file.
|
2576
2581
|
* @default false
|
2577
2582
|
*/
|
2578
|
-
|
2583
|
+
experimentalRunEvents: boolean
|
2579
2584
|
/**
|
2580
|
-
* Enables
|
2585
|
+
* Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement
|
2586
|
+
* algorithm.
|
2581
2587
|
* @default false
|
2582
2588
|
*/
|
2583
|
-
|
2589
|
+
experimentalSourceRewriting: boolean
|
2584
2590
|
/**
|
2585
2591
|
* Number of times to retry a failed test.
|
2586
2592
|
* If a number is set, tests will retry in both runMode and openMode.
|
@@ -2598,7 +2604,7 @@ declare namespace Cypress {
|
|
2598
2604
|
includeShadowDom: boolean
|
2599
2605
|
}
|
2600
2606
|
|
2601
|
-
interface TestConfigOverrides extends Partial<Pick<ConfigOptions, 'baseUrl' | 'defaultCommandTimeout' | '
|
2607
|
+
interface TestConfigOverrides extends Partial<Pick<ConfigOptions, 'animationDistanceThreshold' | 'baseUrl' | 'defaultCommandTimeout' | 'env' | 'execTimeout' | 'includeShadowDom' | 'requestTimeout' | 'responseTimeout' | 'retries' | 'scrollBehavior' | 'taskTimeout' | 'viewportHeight' | 'viewportWidth' | 'waitForAnimations'>> {
|
2602
2608
|
browser?: IsBrowserMatcher | IsBrowserMatcher[]
|
2603
2609
|
}
|
2604
2610
|
|
@@ -2794,7 +2800,7 @@ declare namespace Cypress {
|
|
2794
2800
|
*
|
2795
2801
|
* @see https://on.cypress.io/type
|
2796
2802
|
*/
|
2797
|
-
interface TypeOptions extends Loggable, Timeoutable {
|
2803
|
+
interface TypeOptions extends Loggable, Timeoutable, ActionableOptions {
|
2798
2804
|
/**
|
2799
2805
|
* Delay after each keypress (ms)
|
2800
2806
|
*
|
@@ -2808,12 +2814,6 @@ declare namespace Cypress {
|
|
2808
2814
|
* @default true
|
2809
2815
|
*/
|
2810
2816
|
parseSpecialCharSequences: boolean
|
2811
|
-
/**
|
2812
|
-
* Forces the action, disables waiting for actionability
|
2813
|
-
*
|
2814
|
-
* @default false
|
2815
|
-
*/
|
2816
|
-
force: boolean
|
2817
2817
|
/**
|
2818
2818
|
* Keep a modifier activated between commands
|
2819
2819
|
*
|
@@ -2906,7 +2906,7 @@ declare namespace Cypress {
|
|
2906
2906
|
/**
|
2907
2907
|
* Options to change the default behavior of .trigger()
|
2908
2908
|
*/
|
2909
|
-
interface TriggerOptions extends Loggable, Timeoutable,
|
2909
|
+
interface TriggerOptions extends Loggable, Timeoutable, ActionableOptions {
|
2910
2910
|
/**
|
2911
2911
|
* Whether the event bubbles
|
2912
2912
|
*
|
@@ -4982,7 +4982,7 @@ declare namespace Cypress {
|
|
4982
4982
|
dimensions?: Dimensions
|
4983
4983
|
}
|
4984
4984
|
|
4985
|
-
interface FileObject {
|
4985
|
+
interface FileObject extends NodeEventEmitter {
|
4986
4986
|
filePath: string
|
4987
4987
|
outputPath: string
|
4988
4988
|
shouldWatch: boolean
|
@@ -4999,9 +4999,31 @@ declare namespace Cypress {
|
|
4999
4999
|
[key: string]: Task
|
5000
5000
|
}
|
5001
5001
|
|
5002
|
+
interface SystemDetails {
|
5003
|
+
osName: string
|
5004
|
+
osVersion: string
|
5005
|
+
}
|
5006
|
+
|
5007
|
+
interface BeforeRunDetails {
|
5008
|
+
browser: Browser
|
5009
|
+
config: ConfigOptions
|
5010
|
+
cypressVersion: string
|
5011
|
+
group?: string
|
5012
|
+
parallel: boolean
|
5013
|
+
runUrl?: string
|
5014
|
+
specs: Spec[]
|
5015
|
+
specPattern: string[]
|
5016
|
+
system: SystemDetails
|
5017
|
+
tag?: string
|
5018
|
+
}
|
5019
|
+
|
5002
5020
|
interface PluginEvents {
|
5003
|
-
(action: '
|
5021
|
+
(action: 'after:run', fn: (results: CypressCommandLine.CypressRunResult | CypressCommandLine.CypressFailedRunResult) => void | Promise<void>): void
|
5004
5022
|
(action: 'after:screenshot', fn: (details: ScreenshotDetails) => void | AfterScreenshotReturnObject | Promise<AfterScreenshotReturnObject>): void
|
5023
|
+
(action: 'after:spec', fn: (spec: Spec, results: CypressCommandLine.RunResult) => void | Promise<void>): void
|
5024
|
+
(action: 'before:run', fn: (runDetails: BeforeRunDetails) => void | Promise<void>): void
|
5025
|
+
(action: 'before:spec', fn: (spec: Spec) => void | Promise<void>): void
|
5026
|
+
(action: 'before:browser:launch', fn: (browser: Browser, browserLaunchOptions: BrowserLaunchOptions) => void | BrowserLaunchOptions | Promise<BrowserLaunchOptions>): void
|
5005
5027
|
(action: 'file:preprocessor', fn: (file: FileObject) => string | Promise<string>): void
|
5006
5028
|
(action: 'task', tasks: Tasks): void
|
5007
5029
|
}
|
@@ -5255,7 +5277,8 @@ declare namespace Cypress {
|
|
5255
5277
|
duration: number
|
5256
5278
|
headers: { [key: string]: string }
|
5257
5279
|
isOkStatusCode: boolean
|
5258
|
-
|
5280
|
+
redirects?: string[]
|
5281
|
+
redirectedToUrl?: string
|
5259
5282
|
requestHeaders: { [key: string]: string }
|
5260
5283
|
status: number
|
5261
5284
|
statusText: string
|
package/types/net-stubbing.ts
CHANGED
@@ -70,7 +70,7 @@ type Method =
|
|
70
70
|
| 'unsubscribe'
|
71
71
|
|
72
72
|
export namespace CyHttpMessages {
|
73
|
-
interface BaseMessage {
|
73
|
+
export interface BaseMessage {
|
74
74
|
body?: any
|
75
75
|
headers: { [key: string]: string }
|
76
76
|
url: string
|
@@ -178,8 +178,9 @@ export type NumberMatcher = number | number[]
|
|
178
178
|
/**
|
179
179
|
* Request/response cycle.
|
180
180
|
*/
|
181
|
-
export interface
|
181
|
+
export interface Interception {
|
182
182
|
id: string
|
183
|
+
routeHandlerId: string
|
183
184
|
/* @internal */
|
184
185
|
log: any
|
185
186
|
request: CyHttpMessages.IncomingRequest
|
@@ -191,16 +192,20 @@ export interface Request {
|
|
191
192
|
response?: CyHttpMessages.IncomingResponse
|
192
193
|
/* @internal */
|
193
194
|
responseHandler?: HttpResponseInterceptor
|
195
|
+
/**
|
196
|
+
* The error that occurred during this request.
|
197
|
+
*/
|
198
|
+
error?: Error
|
194
199
|
/**
|
195
200
|
* Was `cy.wait()` used to wait on the response to this request?
|
196
201
|
* @internal
|
197
202
|
*/
|
198
203
|
responseWaited: boolean
|
199
204
|
/* @internal */
|
200
|
-
state:
|
205
|
+
state: InterceptionState
|
201
206
|
}
|
202
207
|
|
203
|
-
export type
|
208
|
+
export type InterceptionState =
|
204
209
|
'Received' |
|
205
210
|
'Intercepted' |
|
206
211
|
'ResponseReceived' |
|
@@ -214,7 +219,8 @@ export interface Route {
|
|
214
219
|
options: RouteMatcherOptions
|
215
220
|
handler: RouteHandler
|
216
221
|
hitCount: number
|
217
|
-
requests: { [key: string]:
|
222
|
+
requests: { [key: string]: Interception }
|
223
|
+
command: any
|
218
224
|
}
|
219
225
|
|
220
226
|
export interface RouteMap { [key: string]: Route }
|
@@ -224,13 +230,9 @@ export interface RouteMap { [key: string]: Route }
|
|
224
230
|
*/
|
225
231
|
export type RouteMatcher = StringMatcher | RouteMatcherOptions
|
226
232
|
|
227
|
-
export interface RouteMatcherCompatOptions {
|
228
|
-
response?: string | object
|
229
|
-
}
|
230
|
-
|
231
233
|
export type RouteMatcherOptions = RouteMatcherOptionsGeneric<StringMatcher>
|
232
234
|
|
233
|
-
export interface RouteMatcherOptionsGeneric<S>
|
235
|
+
export interface RouteMatcherOptionsGeneric<S> {
|
234
236
|
/**
|
235
237
|
* Match against the username and password used in HTTP Basic authentication.
|
236
238
|
*/
|
@@ -248,6 +250,11 @@ export interface RouteMatcherOptionsGeneric<S> extends RouteMatcherCompatOptions
|
|
248
250
|
* If 'false', only HTTP requests will be matched.
|
249
251
|
*/
|
250
252
|
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
|
251
258
|
/**
|
252
259
|
* Match against the request's HTTP method.
|
253
260
|
* @default '*'
|
@@ -328,41 +335,112 @@ export interface GenericStaticResponse<Fixture, Body> {
|
|
328
335
|
*/
|
329
336
|
export type StringMatcher = GlobPattern | RegExp
|
330
337
|
|
338
|
+
interface WaitOptions {
|
339
|
+
/**
|
340
|
+
* Displays the command in the Command Log
|
341
|
+
*
|
342
|
+
* @default true
|
343
|
+
*/
|
344
|
+
log: boolean
|
345
|
+
/**
|
346
|
+
* Time to wait for the request (ms)
|
347
|
+
*
|
348
|
+
* @default {@link Timeoutable#timeout}
|
349
|
+
* @see https://on.cypress.io/configuration#Timeouts
|
350
|
+
*/
|
351
|
+
requestTimeout: number
|
352
|
+
/**
|
353
|
+
* Time to wait for the response (ms)
|
354
|
+
*
|
355
|
+
* @default {@link Timeoutable#timeout}
|
356
|
+
* @see https://on.cypress.io/configuration#Timeouts
|
357
|
+
*/
|
358
|
+
responseTimeout: number
|
359
|
+
/**
|
360
|
+
* Time to wait (ms)
|
361
|
+
*
|
362
|
+
* @default defaultCommandTimeout
|
363
|
+
* @see https://on.cypress.io/configuration#Timeouts
|
364
|
+
*/
|
365
|
+
timeout: number
|
366
|
+
}
|
367
|
+
|
331
368
|
declare global {
|
332
369
|
namespace Cypress {
|
333
370
|
interface Chainable<Subject = any> {
|
334
371
|
/**
|
335
|
-
* Use `cy.
|
372
|
+
* Use `cy.intercept()` to stub and intercept HTTP requests and responses.
|
336
373
|
*
|
337
|
-
*
|
338
|
-
* configuration option to `true`.
|
339
|
-
*
|
340
|
-
* @see https://on.cypress.io/route2
|
374
|
+
* @see https://on.cypress.io/intercept
|
341
375
|
* @example
|
342
|
-
* cy.
|
376
|
+
* cy.intercept('https://localhost:7777/users', [{id: 1, name: 'Pat'}])
|
343
377
|
* @example
|
344
|
-
* cy.
|
378
|
+
* cy.intercept('https://localhost:7777/protected-endpoint', (req) => {
|
345
379
|
* req.headers['authorization'] = 'basic fooabc123'
|
346
380
|
* })
|
347
381
|
* @example
|
348
|
-
* cy.
|
382
|
+
* cy.intercept('https://localhost:7777/some-response', (req) => {
|
349
383
|
* req.reply(res => {
|
350
384
|
* res.body = 'some new body'
|
351
385
|
* })
|
352
386
|
* })
|
353
387
|
*/
|
354
|
-
|
388
|
+
intercept(url: RouteMatcher, response?: RouteHandler): Chainable<null>
|
355
389
|
/**
|
356
|
-
* Use `cy.
|
390
|
+
* Use `cy.intercept()` to stub and intercept HTTP requests and responses.
|
357
391
|
*
|
358
|
-
*
|
359
|
-
* configuration option to `true`.
|
360
|
-
*
|
361
|
-
* @see https://on.cypress.io/route2
|
392
|
+
* @see https://on.cypress.io/intercept
|
362
393
|
* @example
|
363
|
-
* cy.
|
394
|
+
* cy.intercept('GET', 'http://foo.com/fruits', ['apple', 'banana', 'cherry'])
|
395
|
+
*/
|
396
|
+
intercept(method: Method, url: RouteMatcher, response?: RouteHandler): Chainable<null>
|
397
|
+
/**
|
398
|
+
* @deprecated Use `cy.intercept()` instead.
|
399
|
+
*/
|
400
|
+
route2(url: RouteMatcher, response?: RouteHandler): Chainable<null>
|
401
|
+
/**
|
402
|
+
* @deprecated Use `cy.intercept()` instead.
|
364
403
|
*/
|
365
404
|
route2(method: Method, url: RouteMatcher, response?: RouteHandler): Chainable<null>
|
405
|
+
/**
|
406
|
+
* Wait for a specific request to complete.
|
407
|
+
*
|
408
|
+
* @see https://on.cypress.io/wait
|
409
|
+
* @param {string} alias - Name of the alias to wait for.
|
410
|
+
*
|
411
|
+
```
|
412
|
+
// Wait for the route aliased as 'getAccount' to respond
|
413
|
+
// without changing or stubbing its response
|
414
|
+
cy.intercept('https://api.example.com/accounts/*').as('getAccount')
|
415
|
+
cy.visit('/accounts/123')
|
416
|
+
cy.wait('@getAccount').then((interception) => {
|
417
|
+
// we can now access the low level request
|
418
|
+
// that contains the request body,
|
419
|
+
// response body, status, etc
|
420
|
+
})
|
421
|
+
```
|
422
|
+
*/
|
423
|
+
wait(alias: string, options?: Partial<WaitOptions>): Chainable<Interception>
|
424
|
+
/**
|
425
|
+
* Wait for list of requests to complete.
|
426
|
+
*
|
427
|
+
* @see https://on.cypress.io/wait
|
428
|
+
* @param {string[]} aliases - An array of aliased routes as defined using the `.as()` command.
|
429
|
+
*
|
430
|
+
```
|
431
|
+
// wait for 3 XHR requests to complete
|
432
|
+
cy.intercept('users/*').as('getUsers')
|
433
|
+
cy.intercept('activities/*').as('getActivities')
|
434
|
+
cy.intercept('comments/*').as('getComments')
|
435
|
+
cy.visit('/dashboard')
|
436
|
+
|
437
|
+
cy.wait(['@getUsers', '@getActivities', '@getComments'])
|
438
|
+
.then((interceptions) => {
|
439
|
+
// intercepts will now be an array of matching HTTP requests
|
440
|
+
})
|
441
|
+
```
|
442
|
+
*/
|
443
|
+
wait(alias: string[], options?: Partial<WaitOptions>): Chainable<Interception[]>
|
366
444
|
}
|
367
445
|
}
|
368
446
|
}
|