cypress 6.1.0 → 6.4.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', 'run', 'verify', '-v', '--version', 'version', 'info'];
146
+ const knownCommands = ['cache', 'help', '-h', '--help', 'install', 'open', 'open-ct', 'run', 'verify', '-v', '--version', 'version', 'info'];
147
147
 
148
148
  const text = description => {
149
149
  if (!descriptions[description]) {
@@ -322,6 +322,16 @@ module.exports = {
322
322
 
323
323
  require('./exec/run').start(parseVariableOpts(fnArgs, args)).then(util.exit).catch(util.logErrorExit1);
324
324
  });
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 => {
329
+ debug('opening Cypress');
330
+
331
+ require('./exec/open').start(util.parseOpts(opts), {
332
+ isComponentTesting: true
333
+ }).catch(util.logErrorExit1);
334
+ });
325
335
  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 => {
326
336
  debug('opening Cypress');
327
337
 
package/lib/exec/open.js CHANGED
@@ -9,7 +9,11 @@ const spawn = require('./spawn');
9
9
  const verify = require('../tasks/verify');
10
10
 
11
11
  module.exports = {
12
- start(options = {}) {
12
+ start(options = {}, {
13
+ isComponentTesting
14
+ } = {
15
+ isComponentTesting: false
16
+ }) {
13
17
  if (!util.isInstalledGlobally() && !options.global && !options.project) {
14
18
  options.project = process.cwd();
15
19
  }
@@ -40,6 +44,10 @@ module.exports = {
40
44
  args.push('--project', options.project);
41
45
  }
42
46
 
47
+ if (isComponentTesting) {
48
+ args.push('--componentTesting');
49
+ }
50
+
43
51
  debug('opening from options %j', options);
44
52
  debug('command line arguments %j', args);
45
53
 
@@ -14,7 +14,9 @@ const {
14
14
 
15
15
  const Table = require('cli-table3');
16
16
 
17
- const moment = require('moment');
17
+ const dayjs = require('dayjs');
18
+
19
+ const relativeTime = require('dayjs/plugin/relativeTime');
18
20
 
19
21
  const chalk = require('chalk');
20
22
 
@@ -22,8 +24,9 @@ const _ = require('lodash');
22
24
 
23
25
  const getFolderSize = require('./get-folder-size');
24
26
 
25
- const Bluebird = require('bluebird'); // output colors for the table
27
+ const Bluebird = require('bluebird');
26
28
 
29
+ dayjs.extend(relativeTime); // output colors for the table
27
30
 
28
31
  const colors = {
29
32
  titles: chalk.white,
@@ -123,7 +126,7 @@ const getCachedVersions = showSize => {
123
126
  return binary;
124
127
  }
125
128
 
126
- const accessed = moment(lastAccessedTime).fromNow();
129
+ const accessed = dayjs(lastAccessedTime).fromNow();
127
130
  binary.accessed = accessed;
128
131
  return binary;
129
132
  }, e => {
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', 'config', 'configFile', 'cypressVersion', 'destination', 'detached', 'dev', 'exit', 'env', 'force', 'global', 'group', 'headed', 'headless', 'key', 'path', 'parallel', 'port', 'project', 'quiet', 'reporter', 'reporterOptions', 'record', 'spec', 'tag');
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', 'spec', 'tag');
216
216
 
217
217
  if (opts.exit) {
218
218
  opts = _.omit(opts, 'exit');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cypress",
3
- "version": "6.1.0",
3
+ "version": "6.4.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node index.js --exec install",
@@ -21,6 +21,7 @@
21
21
  "cli-table3": "~0.6.0",
22
22
  "commander": "^5.1.0",
23
23
  "common-tags": "^1.8.0",
24
+ "dayjs": "^1.9.3",
24
25
  "debug": "^4.1.1",
25
26
  "eventemitter2": "^6.4.2",
26
27
  "execa": "^4.0.2",
@@ -35,7 +36,7 @@
35
36
  "lodash": "^4.17.19",
36
37
  "log-symbols": "^4.0.0",
37
38
  "minimist": "^1.2.5",
38
- "moment": "^2.27.0",
39
+ "moment": "^2.29.1",
39
40
  "ospath": "^1.2.2",
40
41
  "pretty-bytes": "^5.4.1",
41
42
  "ramda": "~0.26.1",
@@ -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
+ }
@@ -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
  */
@@ -227,23 +240,17 @@ declare namespace Cypress {
227
240
  /**
228
241
  * Currently executing spec file.
229
242
  * @example
230
- ```
231
- Cypress.spec
232
- // {
233
- // name: "config_passing_spec.coffee",
234
- // relative: "cypress/integration/config_passing_spec.coffee",
235
- // absolute: "/users/smith/projects/web/cypress/integration/config_passing_spec.coffee"
236
- // specType: "integration"
237
- // }
238
- ```
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
+ * ```
239
252
  */
240
- spec: {
241
- name: string // "config_passing_spec.coffee"
242
- relative: string // "cypress/integration/config_passing_spec.coffee" or "__all" if clicked all specs button
243
- absolute: string
244
- specFilter?: string // optional spec filter used by the user
245
- specType?: CypressSpecType
246
- }
253
+ spec: Spec
247
254
 
248
255
  /**
249
256
  * Information about the browser currently running the tests
@@ -274,7 +281,7 @@ declare namespace Cypress {
274
281
  // {defaultCommandTimeout: 10000, pageLoadTimeout: 30000, ...}
275
282
  ```
276
283
  */
277
- config(): ResolvedConfigOptions
284
+ config(): ResolvedConfigOptions & RuntimeConfigOptions
278
285
  /**
279
286
  * Returns one configuration value.
280
287
  * @see https://on.cypress.io/config
@@ -2472,6 +2479,11 @@ declare namespace Cypress {
2472
2479
  * @default "cypress/integration"
2473
2480
  */
2474
2481
  integrationFolder: string
2482
+ /**
2483
+ * Path to folder where files downloaded during a test are saved
2484
+ * @default "cypress/downloads"
2485
+ */
2486
+ downloadsFolder: string
2475
2487
  /**
2476
2488
  * If set to `system`, Cypress will try to find a `node` executable on your path to use when executing your plugins. Otherwise, Cypress will use the Node version bundled with Cypress.
2477
2489
  * @default "bundled"
@@ -2569,12 +2581,22 @@ declare namespace Cypress {
2569
2581
  * @default { runMode: 1, openMode: null }
2570
2582
  */
2571
2583
  firefoxGcInterval: Nullable<number | { runMode: Nullable<number>, openMode: Nullable<number> }>
2584
+ /**
2585
+ * Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file.
2586
+ * @default false
2587
+ */
2588
+ experimentalRunEvents: boolean
2572
2589
  /**
2573
2590
  * Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement
2574
2591
  * algorithm.
2575
2592
  * @default false
2576
2593
  */
2577
2594
  experimentalSourceRewriting: boolean
2595
+ /**
2596
+ * Generate and save commands directly to your test suite by interacting with your app as an end user would.
2597
+ * @default false
2598
+ */
2599
+ experimentalStudio: boolean
2578
2600
  /**
2579
2601
  * Number of times to retry a failed test.
2580
2602
  * If a number is set, tests will retry in both runMode and openMode.
@@ -2592,7 +2614,111 @@ declare namespace Cypress {
2592
2614
  includeShadowDom: boolean
2593
2615
  }
2594
2616
 
2595
- interface TestConfigOverrides extends Partial<Pick<ConfigOptions, 'baseUrl' | 'defaultCommandTimeout' | 'taskTimeout' | 'animationDistanceThreshold' | 'waitForAnimations' | 'viewportHeight' | 'viewportWidth' | 'requestTimeout' | 'execTimeout' | 'env' | 'responseTimeout' | 'retries' | 'includeShadowDom'>> {
2617
+ /**
2618
+ * Options appended to config object on runtime.
2619
+ */
2620
+ interface RuntimeConfigOptions {
2621
+ /**
2622
+ * CPU architecture, from Node `os.arch()`
2623
+ *
2624
+ * @see https://nodejs.org/api/os.html#os_os_arch
2625
+ */
2626
+ arch: string
2627
+ /**
2628
+ * The list of hosts to be blocked
2629
+ */
2630
+ blockHosts: null | string | string[]
2631
+ /**
2632
+ * The browser Cypress is running on.
2633
+ */
2634
+ browser: Browser
2635
+ /**
2636
+ * Available browsers found on your system.
2637
+ */
2638
+ browsers: Browser[]
2639
+ /**
2640
+ * Path to folder containing component test files.
2641
+ */
2642
+ componentFolder: string
2643
+ /**
2644
+ * Whether component testing is enabled.
2645
+ */
2646
+ experimentalComponentTesting: boolean
2647
+ /**
2648
+ * Hosts mappings to IP addresses.
2649
+ */
2650
+ hosts: null | string[]
2651
+ /**
2652
+ * Whether Cypress was launched via 'cypress open' (interactive mode)
2653
+ */
2654
+ isInteractive: boolean
2655
+ /**
2656
+ * Whether Cypress will search for and replace
2657
+ * obstructive JS code in .js or .html files.
2658
+ *
2659
+ * @see https://on.cypress.io/configuration#modifyObstructiveCode
2660
+ */
2661
+ modifyObstructiveCode: boolean
2662
+ /**
2663
+ * The platform Cypress is running on.
2664
+ */
2665
+ platform: 'linux' | 'darwin' | 'win32'
2666
+ /**
2667
+ * A unique ID for the project used for recording
2668
+ */
2669
+ projectId: null | string
2670
+ /**
2671
+ * Path to the support folder.
2672
+ */
2673
+ supportFolder: string
2674
+ /**
2675
+ * Glob pattern to determine what test files to load.
2676
+ */
2677
+ testFiles: string
2678
+ /**
2679
+ * The user agent the browser sends in all request headers.
2680
+ */
2681
+ userAgent: null | string
2682
+ /**
2683
+ * The Cypress version being used.
2684
+ */
2685
+ version: string
2686
+
2687
+ // Internal or Unlisted at server/lib/config_options
2688
+ autoOpen: boolean
2689
+ browserUrl: string
2690
+ clientRoute: string
2691
+ configFile: string
2692
+ cypressEnv: string
2693
+ integrationExampleName: string
2694
+ integrationExamplePath: string
2695
+ isNewProject: boolean
2696
+ isTextTerminal: boolean
2697
+ morgan: boolean
2698
+ namespace: string
2699
+ parentTestsFolder: string
2700
+ parentTestsFolderDisplay: string
2701
+ projectName: string
2702
+ projectRoot: string
2703
+ proxyUrl: string
2704
+ report: boolean
2705
+ reporterRoute: string
2706
+ reporterUrl: string
2707
+ socketId: null | string
2708
+ socketIoCookie: string
2709
+ socketIoRoute: string
2710
+ spec: {
2711
+ absolute: string
2712
+ name: string
2713
+ relative: string
2714
+ specFilter: null | string
2715
+ specType: 'integration' | 'component'
2716
+ }
2717
+ xhrRoute: string
2718
+ xhrUrl: string
2719
+ }
2720
+
2721
+ interface TestConfigOverrides extends Partial<Pick<ConfigOptions, 'animationDistanceThreshold' | 'baseUrl' | 'defaultCommandTimeout' | 'env' | 'execTimeout' | 'includeShadowDom' | 'requestTimeout' | 'responseTimeout' | 'retries' | 'scrollBehavior' | 'taskTimeout' | 'viewportHeight' | 'viewportWidth' | 'waitForAnimations'>> {
2596
2722
  browser?: IsBrowserMatcher | IsBrowserMatcher[]
2597
2723
  }
2598
2724
 
@@ -4970,7 +5096,7 @@ declare namespace Cypress {
4970
5096
  dimensions?: Dimensions
4971
5097
  }
4972
5098
 
4973
- interface FileObject {
5099
+ interface FileObject extends NodeEventEmitter {
4974
5100
  filePath: string
4975
5101
  outputPath: string
4976
5102
  shouldWatch: boolean
@@ -4987,9 +5113,31 @@ declare namespace Cypress {
4987
5113
  [key: string]: Task
4988
5114
  }
4989
5115
 
5116
+ interface SystemDetails {
5117
+ osName: string
5118
+ osVersion: string
5119
+ }
5120
+
5121
+ interface BeforeRunDetails {
5122
+ browser: Browser
5123
+ config: ConfigOptions
5124
+ cypressVersion: string
5125
+ group?: string
5126
+ parallel: boolean
5127
+ runUrl?: string
5128
+ specs: Spec[]
5129
+ specPattern: string[]
5130
+ system: SystemDetails
5131
+ tag?: string
5132
+ }
5133
+
4990
5134
  interface PluginEvents {
4991
- (action: 'before:browser:launch', fn: (browser: Browser, browserLaunchOptions: BrowserLaunchOptions) => void | BrowserLaunchOptions | Promise<BrowserLaunchOptions>): void
5135
+ (action: 'after:run', fn: (results: CypressCommandLine.CypressRunResult | CypressCommandLine.CypressFailedRunResult) => void | Promise<void>): void
4992
5136
  (action: 'after:screenshot', fn: (details: ScreenshotDetails) => void | AfterScreenshotReturnObject | Promise<AfterScreenshotReturnObject>): void
5137
+ (action: 'after:spec', fn: (spec: Spec, results: CypressCommandLine.RunResult) => void | Promise<void>): void
5138
+ (action: 'before:run', fn: (runDetails: BeforeRunDetails) => void | Promise<void>): void
5139
+ (action: 'before:spec', fn: (spec: Spec) => void | Promise<void>): void
5140
+ (action: 'before:browser:launch', fn: (browser: Browser, browserLaunchOptions: BrowserLaunchOptions) => void | BrowserLaunchOptions | Promise<BrowserLaunchOptions>): void
4993
5141
  (action: 'file:preprocessor', fn: (file: FileObject) => string | Promise<string>): void
4994
5142
  (action: 'task', tasks: Tasks): void
4995
5143
  }
@@ -95,9 +95,9 @@ export namespace CyHttpMessages {
95
95
  */
96
96
  send(): void
97
97
  /**
98
- * Wait for `delayMs` milliseconds before sending the response to the client.
98
+ * Wait for `delay` milliseconds before sending the response to the client.
99
99
  */
100
- delay: (delayMs: number) => IncomingHttpResponse
100
+ delay: (delay: number) => IncomingHttpResponse
101
101
  /**
102
102
  * Serve the response at `throttleKbps` kilobytes per second.
103
103
  */
@@ -180,6 +180,7 @@ export type NumberMatcher = number | number[]
180
180
  */
181
181
  export interface Interception {
182
182
  id: string
183
+ routeHandlerId: string
183
184
  /* @internal */
184
185
  log: any
185
186
  request: CyHttpMessages.IncomingRequest
@@ -191,6 +192,10 @@ export interface Interception {
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
@@ -215,6 +220,7 @@ export interface Route {
215
220
  handler: RouteHandler
216
221
  hitCount: number
217
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> extends RouteMatcherCompatOptions {
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 '*'
@@ -288,8 +295,9 @@ export type RouteHandler = string | StaticResponse | RouteHandlerController | ob
288
295
  export type StaticResponse = GenericStaticResponse<string, string | object> & {
289
296
  /**
290
297
  * Milliseconds to delay before the response is sent.
298
+ * @deprecated Use `delay` instead of `delayMs`.
291
299
  */
292
- delayMs?: number
300
+ delayMs?: number
293
301
  }
294
302
 
295
303
  export interface GenericStaticResponse<Fixture, Body> {
@@ -321,6 +329,10 @@ export interface GenericStaticResponse<Fixture, Body> {
321
329
  * Kilobits per second to send 'body'.
322
330
  */
323
331
  throttleKbps?: number
332
+ /**
333
+ * Milliseconds to delay before the response is sent.
334
+ */
335
+ delay?: number
324
336
  }
325
337
 
326
338
  /**