@@ -33,9 +33,8 @@ Enabling this flag does the following:
33
33
- It supersedes
34
34
the [ ` Cypress.Cookies.preserveOnce() ` ] ( /api/cypress-api/cookies#Preserve-Once ) and
35
35
[ ` Cypress.Cookies.defaults() ` ] ( /api/cypress-api/cookies#Defaults ) methods.
36
- - Cross-origin requests will no longer fail immediately, but instead, time out
37
- based on [ ` pageLoadTimeout ` ] ( /guides/references/configuration#Timeouts ) .
38
- - Tests will no longer wait on page loads before moving on to the next test.
36
+ - Cross-origin requests will now succeed, however, to interact with a
37
+ cross-origin page you must use a ` cy.origin ` block.
39
38
40
39
Because the page is cleared before each
41
40
test, [ ` cy.visit() ` ] ( /api/commands/visit ) must be explicitly called in each test
@@ -91,10 +90,11 @@ cy.get('h1').contains('My cool site under test')
91
90
92
91
``` js
93
92
const hits = getHits ()
94
- // cy.visit() should be inside cy.origin() callback
95
93
cy .visit (' https://www.acme.com/history/founder' )
94
+ // to interact with cross-origin content, move this inside cy.origin() callback
95
+ cy .get (' h1' ).contains (' About our Founder, Marvin Acme' )
96
96
cy .origin (' https://www.acme.com' , () => {
97
- // Fails because origin was visited before cy.origin() block
97
+ cy .visit ( ' /history/founder ' )
98
98
cy .get (' h1' ).contains (' About our Founder, Marvin Acme' )
99
99
// Fails because hits is not passed in via args
100
100
cy .get (' #hitcounter' ).contains (hits)
@@ -214,9 +214,10 @@ cy.origin('https://www.acme.com', () => {
214
214
215
215
### Navigating to secondary origin with cy.visit
216
216
217
- When navigating to a secondary origin using ` cy.visit() ` , it is essential to
218
- trigger the navigation ** after** entering the origin callback, otherwise a
219
- cross-origin error will be thrown.
217
+ When navigating to a secondary origin using ` cy.visit() ` , you can either
218
+ navigate prior to or after the ` cy.origin ` block. Errors are no longer thrown on
219
+ cross-origin navigation, but instead when commands interact with a cross-origin
220
+ page.
220
221
221
222
``` js
222
223
// Do things in primary origin...
@@ -233,11 +234,42 @@ and the protocol defaults to `https`. When `cy.visit()` is called with the path
233
234
` /history/founder ` , the three are concatenated to make
234
235
` https://www.acme.com/history/founder ` .
235
236
237
+ #### Alternative navigation
238
+
239
+ ``` js
240
+ // Do things in primary origin...
241
+
242
+ cy .visit (' https://www.acme.com/history/founder' )
243
+
244
+ // The cy.origin block is required to interact with the cross-origin page.
245
+ cy .origin (' www.acme.com' , () => {
246
+ cy .get (' h1' ).contains (' About our Founder, Marvin Acme' )
247
+ })
248
+ ```
249
+
250
+ Here the cross-origin page is visited prior to the ` cy.origin ` block, but any
251
+ interactions with the window are performed within the block which can
252
+ communicate with the cross-origin page
253
+
254
+ #### <Icon name =" exclamation-triangle " color =" red " ></Icon > Incorrect Usage
255
+
256
+ ``` js
257
+ // Do things in primary origin...
258
+
259
+ cy .visit (' https://www.acme.com/history/founder' )
260
+
261
+ // This command will fail, it's executed on localhost but the application is at acme.com
262
+ cy .get (' h1' ).contains (' About our Founder, Marvin Acme' )
263
+ ```
264
+
265
+ Here ` cy.get('h1') ` fails because we are trying to interact with a cross-origin
266
+ page outside of the cy.origin block, due to 'same-origin' restrictions, the
267
+ 'localhost' javascript context can't communicate with 'acme.com'.
268
+
236
269
### Navigating to secondary origin with UI
237
270
238
- When navigating to a secondary origin by clicking a link or button in the
239
- primary origin, it is essential to trigger the navigation _ before_ entering the
240
- origin callback, otherwise a cross-origin error will be thrown.
271
+ Navigating to a secondary origin by clicking a link or button in the primary
272
+ origin is supported.
241
273
242
274
``` js
243
275
// Button in primary origin goes to https://www.acme.com
@@ -290,7 +322,7 @@ do this with `cy.origin()`.
290
322
291
323
``` js
292
324
Cypress .Commands .add (' login' , (username , password ) => {
293
- // Remember to pass in dependencies via `args`
325
+ // Remember to pass in arguments via `args`
294
326
const args = { username, password }
295
327
cy .origin (' my-auth.com' , { args }, ({ username, password }) => {
296
328
// Go to https://auth-provider.com/login
@@ -473,49 +505,120 @@ of
473
505
[ restrictions on the data which may be passed] ( https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#things_that_dont_work_with_structured_clone )
474
506
into the callback.
475
507
476
- ### Callback restrictions
508
+ ### Dependencies / Sharing Code
477
509
478
- Because of the way in which the callback is transmitted and executed, there are
479
- certain limitations on what code may be run inside it. In particular, the
480
- following Cypress commands will throw errors if used in the callback:
510
+ It is not possible to use
511
+ [ CommonJS ` require() ` ] ( https://nodejs.org/en/knowledge/getting-started/what-is-require/ )
512
+ or
513
+ [ dynamic ES module ` import() ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports )
514
+ within the callback. However, [ ` Cypress.require() ` ] ( /api/cypress-api/require )
515
+ can be utilized to include [ npm] ( https://www.npmjs.com/ ) packages and other
516
+ files. It is functionally the same as using
517
+ [ CommonJS ` require() ` ] ( https://nodejs.org/en/knowledge/getting-started/what-is-require/ )
518
+ in browser-targeted code.
481
519
482
- - ` cy.origin() `
483
- - [ ` cy.intercept() ` ] ( /api/commands/intercept )
484
- - [ ` cy.session() ` ] ( /api/commands/session )
485
- - [ ` cy.server() ` ] ( /api/commands/server )
486
- - [ ` cy.route() ` ] ( /api/commands/route )
487
- - [ ` Cypress.Cookies.preserveOnce() ` ] ( /api/cypress-api/cookies )
520
+ ``` js
521
+ cy .origin (' somesite.com' , () => {
522
+ const _ = Cypress .require (' lodash' )
523
+ const utils = Cypress .require (' ../support/utils' )
488
524
489
- It is also currently not possible to use
490
- [ ` require() ` ] ( https://nodejs.org/en/knowledge/getting-started/what-is-require/ )
491
- or
492
- [ dynamic ` import() ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports )
493
- within the callback. Because of this limitation, it cannot use
494
- [ npm] ( https://www.npmjs.com/ ) packages or other third-party libraries inside the
495
- callback, as there is no mechanism to reference them. This functionality will be
496
- provided in a future version of Cypress.
525
+ // ... use lodash and utils ...
526
+ })
527
+ ```
528
+
529
+ ` Cypress.require() ` can be used to share custom commands between tests run in
530
+ primary and secondary origins. We recommend this pattern for setting up your
531
+ [ support file] ( /guides/core-concepts/writing-and-organizing-tests#Support-file )
532
+ and setting up custom commands to run within the ` cy.origin() ` callback:
533
+
534
+ ` cypress/support/commands.js ` :
535
+
536
+ ``` js
537
+ Cypress .Commands .add (' clickLink' , (label ) => {
538
+ cy .get (' a' ).contains (label).click ()
539
+ })
540
+ ```
541
+
542
+ ` cypress/support/e2e.js ` :
543
+
544
+ ``` js
545
+ // makes custom commands available to all Cypress tests in this spec,
546
+ // outside of cy.origin() callbacks
547
+ import ' ./commands'
548
+
549
+ // code we only want run per test, so it shouldn't be run as part of
550
+ // the execution of cy.origin() as well
551
+ beforeEach (() => {
552
+ // ... code to run before each test ...
553
+ })
554
+ ```
555
+
556
+ ` cypress/e2e/spec.cy.js ` :
557
+
558
+ ``` js
559
+ before (() => {
560
+ // makes custom commands available to all subsequent cy.origin('somesite.com')
561
+ // calls in this spec. put it in your support file to make them available to
562
+ // all specs
563
+ cy .origin (' somesite.com' , () => {
564
+ Cypress .require (' ../support/commands' )
565
+ })
566
+ })
567
+
568
+ it (' tests somesite.com' , () => {
569
+ cy .origin (' somesite.com' , () => {
570
+ cy .visit (' /page' )
571
+ cy .clickLink (' Click Me' )
572
+ })
573
+ })
574
+ ```
497
575
498
- While third-party packages are strictly unavailable, it is possible to reuse
499
- your ** own ** code between ` cy. origin() ` callbacks. The workaround is to create a
500
- custom Cypress command within the secondary origin in a ` before ` block:
576
+ The JavaScript execution context is persisted between ` cy.origin() ` callbacks
577
+ that share the same origin. This can be utilized to share code between
578
+ successive ` cy. origin() ` calls.
501
579
502
580
``` js
503
581
before (() => {
504
582
cy .origin (' somesite.com' , () => {
505
- Cypress . Commands . add ( ' clickLink ' , ( label ) => {
506
- cy . get ( ' a ' ). contains (label). click ()
507
- } )
583
+ // makes commands defined in this file available to all callbacks
584
+ // for somesite.com
585
+ Cypress . require ( ' ../support/commands ' )
508
586
})
509
587
})
510
588
511
- it (' clicks the secondary origin link ' , () => {
589
+ it (' uses cy.origin() + custom command ' , () => {
512
590
cy .origin (' somesite.com' , () => {
513
591
cy .visit (' /page' )
514
592
cy .clickLink (' Click Me' )
515
593
})
516
594
})
595
+
596
+ it (' also uses cy.origin() + custom command' , () => {
597
+ cy .origin (' somesite.com' , () => {
598
+ cy .visit (' /page' )
599
+ cy .clickLink (' Click Me' )
600
+ })
601
+
602
+ cy .origin (' differentsite.com' , () => {
603
+ // WARNING: cy.clickLink() will not be available because it is a
604
+ // different origin
605
+ })
606
+ })
517
607
```
518
608
609
+ ### Callback restrictions
610
+
611
+ Because of the way in which the callback is transmitted and executed, there are
612
+ certain limitations on what code may be run inside it. In particular, the
613
+ following Cypress commands will throw errors if used in the callback:
614
+
615
+ - ` cy.origin() `
616
+ - [ ` cy.intercept() ` ] ( /api/commands/intercept )
617
+ - [ ` cy.session() ` ] ( /api/commands/session )
618
+ - [ ` cy.server() ` ] ( /api/commands/server )
619
+ - [ ` cy.route() ` ] ( /api/commands/route )
620
+ - [ ` Cypress.Cookies.preserveOnce() ` ] ( /api/cypress-api/cookies )
621
+
519
622
### Other limitations
520
623
521
624
There are other testing scenarios which are not currently covered by
0 commit comments