-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
10.9.0 Release #4747
10.9.0 Release #4747
Changes from 16 commits
92aff45
2ec8117
165b3ce
bee2787
f38e9b5
5005028
b6685be
45a89f1
f24610d
ff18ac0
f850260
5c39844
a0cca06
7b68040
779f648
cba137b
59809e4
5653543
58d9d34
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
## 10.9.0 | ||
|
||
_Released 9/27/2022_ | ||
|
||
**Features:** | ||
|
||
- Added support for requiring dependencies within the | ||
[`cy.origin()`](/api/commands/origin) callback. See the | ||
[`Cypress.require()`](/api/cypress-api/require) and | ||
[`cy.origin()`](/api/commands/origin#Dependencies-Sharing-Code) docs for more | ||
information. | ||
- Added support for visiting cross-origin pages outside of a | ||
[`cy.origin()`](/api/commands/origin) callback. See the | ||
[`cy.origin()`](/api/commands/origin#Alternative-navigation) and | ||
[`cy.visit()`](/api/commands/visit#Visiting-cross-origin-sites) docs for more | ||
information and caveats. Addresses | ||
[#21485](https://github.com/cypress-io/cypress/issues/21485), | ||
[#22282](https://github.com/cypress-io/cypress/issues/22282), | ||
[#21300](https://github.com/cypress-io/cypress/issues/21300), and | ||
[#23236](https://github.com/cypress-io/cypress/issues/23236). | ||
- Added support for re-using session data cached by | ||
[`cy.session()`](/api/commands/session) across specs via the | ||
`cacheAcrossSpecs` option. Addresses | ||
[#17710](https://github.com/cypress-io/cypress/issues/17710). | ||
- Added support for advanced dev server configuration via an async function that | ||
can optionally modify the dev server config. Addresses | ||
[#23302](https://github.com/cypress-io/cypress/issues/23302). | ||
- Launch options returned from the | ||
[`before:browser:launch`](/api/plugins/browser-launch-api) event can now | ||
include an `env` key that can be used to pass environment variables to the | ||
browser when it is launched. Addressed by | ||
[#23624](https://github.com/cypress-io/cypress/pull/23624). | ||
- Component tests that fail now display a code frame of the source location of | ||
the error within the Cypress reporter. Addresses | ||
[#21720](https://github.com/cypress-io/cypress/issues/21720). | ||
|
||
**Bugfixes:** | ||
|
||
- The spec results printed stdout after a test run now show the path to the spec | ||
and not just the file name. Fixes | ||
[#22304](https://github.com/cypress-io/cypress/issues/22304). | ||
- The viewport dropdown in the Cypress App now displays the correct text. Fixes | ||
[#23789](https://github.com/cypress-io/cypress/issues/23789). | ||
- Compile errors are now surfaced in the command log during tests for Angular | ||
and Next projects. Fixes | ||
[#23219](https://github.com/cypress-io/cypress/issues/23219). | ||
- The error "Automatic publicPath is not supported in this browser" will no | ||
longer be displayed when using Webpack 5 and dynamic imports. Fixes | ||
[#18435](https://github.com/cypress-io/cypress/issues/18435). | ||
- The correct source control link is now sent to the Cypress Dashboard for | ||
failed specs when the cypress config file is not the project root. Fixes | ||
[#22971](https://github.com/cypress-io/cypress/issues/22971). | ||
- The error "Invalid left-hand-side in assignment" will no longer be thrown when | ||
the `experimentalModifyObstructiveThirdPartyCode` flag is enabled. Fixes | ||
[#23647](https://github.com/cypress-io/cypress/issues/23647). | ||
- `it.skip` now functions correctly in Angular component tests. Fixes | ||
[#23409](https://github.com/cypress-io/cypress/issues/23409). | ||
- The `tsConfig` build option is now respected for Angular component tests. | ||
Fixes [#23673](https://github.com/cypress-io/cypress/issues/23673). | ||
- Configuring a custom browser no longer logs a warning when trying to use that | ||
browser. Addressed in | ||
[#23446](https://github.com/cypress-io/cypress/pull/23446). | ||
|
||
**Misc:** | ||
|
||
- Improved the accessibility of a few components within the Cypress Launchpad | ||
and App. Addressed in | ||
[#23745](https://github.com/cypress-io/cypress/pull/23745). | ||
- Improved the UI of the Sessions instrument panel in the Cypress reporter. | ||
Addresses [#21400](https://github.com/cypress-io/cypress/issues/21400). |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,9 +33,8 @@ Enabling this flag does the following: | |
- It supersedes | ||
the [`Cypress.Cookies.preserveOnce()`](/api/cypress-api/cookies#Preserve-Once) and | ||
[`Cypress.Cookies.defaults()`](/api/cypress-api/cookies#Defaults) methods. | ||
- Cross-origin requests will no longer fail immediately, but instead, time out | ||
based on [`pageLoadTimeout`](/guides/references/configuration#Timeouts). | ||
- Tests will no longer wait on page loads before moving on to the next test. | ||
- Cross-origin requests will now succeed, however, to interact with a | ||
cross-origin page you must use a `cy.origin` block. | ||
|
||
Because the page is cleared before each | ||
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') | |
|
||
```js | ||
const hits = getHits() | ||
// cy.visit() should be inside cy.origin() callback | ||
cy.visit('https://www.acme.com/history/founder') | ||
// to interact with cross-origin content, move this inside cy.origin() callback | ||
cy.get('h1').contains('About our Founder, Marvin Acme') | ||
cy.origin('https://www.acme.com', () => { | ||
// Fails because origin was visited before cy.origin() block | ||
cy.visit('/history/founder') | ||
cy.get('h1').contains('About our Founder, Marvin Acme') | ||
// Fails because hits is not passed in via args | ||
cy.get('#hitcounter').contains(hits) | ||
|
@@ -214,9 +214,10 @@ cy.origin('https://www.acme.com', () => { | |
|
||
### Navigating to secondary origin with cy.visit | ||
|
||
When navigating to a secondary origin using `cy.visit()`, it is essential to | ||
trigger the navigation **after** entering the origin callback, otherwise a | ||
cross-origin error will be thrown. | ||
When navigating to a secondary origin using `cy.visit()`, you can either | ||
navigate prior to or after the `cy.origin` block. Errors are no longer thrown on | ||
cross-origin navigation, but instead when commands interact with a cross-origin | ||
page. | ||
|
||
```js | ||
// Do things in primary origin... | ||
|
@@ -233,11 +234,42 @@ and the protocol defaults to `https`. When `cy.visit()` is called with the path | |
`/history/founder`, the three are concatenated to make | ||
`https://www.acme.com/history/founder`. | ||
|
||
#### Alternative navigation | ||
|
||
```js | ||
// Do things in primary origin... | ||
|
||
cy.visit('https://www.acme.com/history/founder') | ||
|
||
// The cy.origin block is required to interact with the cross-origin page. | ||
cy.origin('www.acme.com', () => { | ||
cy.get('h1').contains('About our Founder, Marvin Acme') | ||
}) | ||
``` | ||
|
||
Here the cross-origin page is visited prior to the `cy.origin` block, but any | ||
interactions with the window are performed within the block which can | ||
communicate with the cross-origin page | ||
|
||
#### Incorrect usage | ||
|
||
```js | ||
// Do things in primary origin... | ||
|
||
cy.visit('https://www.acme.com/history/founder') | ||
|
||
// This command will fail, it's executed on localhost but the application is at acme.com | ||
cy.get('h1').contains('About our Founder, Marvin Acme') | ||
``` | ||
|
||
Here `cy.get('h1')` fails because we are trying to interact with a cross-origin | ||
page outside of the cy.origin block, due to 'same-origin' restrictions, the | ||
'localhost' javascript context can't communicate with 'acme.com'. | ||
|
||
### Navigating to secondary origin with UI | ||
|
||
When navigating to a secondary origin by clicking a link or button in the | ||
primary origin, it is essential to trigger the navigation _before_ entering the | ||
origin callback, otherwise a cross-origin error will be thrown. | ||
Navigating to a secondary origin by clicking a link or button in the primary | ||
origin is supported. | ||
|
||
```js | ||
// Button in primary origin goes to https://www.acme.com | ||
|
@@ -290,7 +322,7 @@ do this with `cy.origin()`. | |
|
||
```js | ||
Cypress.Commands.add('login', (username, password) => { | ||
// Remember to pass in dependencies via `args` | ||
// Remember to pass in arguments via `args` | ||
const args = { username, password } | ||
cy.origin('my-auth.com', { args }, ({ username, password }) => { | ||
// Go to https://auth-provider.com/login | ||
|
@@ -473,49 +505,115 @@ of | |
[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) | ||
into the callback. | ||
|
||
### Callback restrictions | ||
### Dependencies / Sharing Code | ||
|
||
Because of the way in which the callback is transmitted and executed, there are | ||
certain limitations on what code may be run inside it. In particular, the | ||
following Cypress commands will throw errors if used in the callback: | ||
It is not possible to use | ||
[CommonJS `require()`](https://nodejs.org/en/knowledge/getting-started/what-is-require/) | ||
or | ||
[dynamic ES module `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports) | ||
within the callback. However, [`Cypress.require()`](/api/cypress-api/require) | ||
can be utilized to include [npm](https://www.npmjs.com/) packages and other | ||
files. It is functionally the same as using | ||
[CommonJS `require()`](https://nodejs.org/en/knowledge/getting-started/what-is-require/) | ||
in browser-targeted code. | ||
|
||
- `cy.origin()` | ||
- [`cy.intercept()`](/api/commands/intercept) | ||
- [`cy.session()`](/api/commands/session) | ||
- [`cy.server()`](/api/commands/server) | ||
- [`cy.route()`](/api/commands/route) | ||
- [`Cypress.Cookies.preserveOnce()`](/api/cypress-api/cookies) | ||
```js | ||
cy.origin('somesite.com', () => { | ||
const _ = Cypress.require('lodash') | ||
const utils = Cypress.require('../support/utils') | ||
|
||
It is also currently not possible to use | ||
[`require()`](https://nodejs.org/en/knowledge/getting-started/what-is-require/) | ||
or | ||
[dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports) | ||
within the callback. Because of this limitation, it cannot use | ||
[npm](https://www.npmjs.com/) packages or other third-party libraries inside the | ||
callback, as there is no mechanism to reference them. This functionality will be | ||
provided in a future version of Cypress. | ||
// ... use lodash and utils ... | ||
}) | ||
``` | ||
|
||
`Cypress.require()` can be used to share custom commands between tests run in | ||
primary and secondary origins. We recommend this pattern for setting up your | ||
[support file](/guides/core-concepts/writing-and-organizing-tests#Support-file) | ||
and setting up custom commands to run within the `cy.origin()` callback: | ||
|
||
`cypress/support/commands.js`: | ||
|
||
While third-party packages are strictly unavailable, it is possible to reuse | ||
your **own** code between `cy.origin()` callbacks. The workaround is to create a | ||
custom Cypress command within the secondary origin in a `before` block: | ||
```js | ||
Cypress.Commands.add('clickLink', (label) => { | ||
cy.get('a').contains(label).click() | ||
}) | ||
``` | ||
|
||
`cypress/support/e2e.js`: | ||
|
||
```js | ||
// makes custom commands available to all Cypress tests, outside of | ||
// cy.origin() callbacks | ||
import './commands' | ||
|
||
// code we only want run per test, so it shouldn't be run as part of | ||
// the execution of cy.origin() as well | ||
beforeEach(() => { | ||
// ... code to run before each test ... | ||
}) | ||
``` | ||
|
||
`cypress/e2e/spec.cy.js`: | ||
|
||
```js | ||
it('tests somesite.com', () => { | ||
cy.origin('somesite.com', () => { | ||
// makes custom commands available to all subsequent | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this all subsequent calls within this test, within this spec, or within this cypress run? Same question for the rest of this section - "persisted between cy.origin callbacks" (for how long?), "makes commands defined in this file available to all callbacks for somesite.com" (all callbacks this cypress run? Wouldn't that imply some pollution / lack of test isolation?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All calls within the spec. I'll update the comment to make that clear. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in 59809e4 |
||
// cy.origin('somesite.com') calls | ||
Cypress.require('../support/commands') | ||
|
||
cy.visit('/page') | ||
cy.clickLink('Click Me') | ||
}) | ||
}) | ||
``` | ||
|
||
The JavaScript execution context is persisted between `cy.origin()` callbacks | ||
that share the same origin. This can be utilized to share code between | ||
successive `cy.origin()` calls. | ||
|
||
```js | ||
before(() => { | ||
cy.origin('somesite.com', () => { | ||
Cypress.Commands.add('clickLink', (label) => { | ||
cy.get('a').contains(label).click() | ||
}) | ||
// makes commands defined in this file available to all callbacks | ||
// for somesite.com | ||
Cypress.require('../support/commands') | ||
}) | ||
}) | ||
|
||
it('uses cy.origin() + custom command', () => { | ||
cy.origin('somesite.com', () => { | ||
cy.visit('/page') | ||
cy.clickLink('Click Me') | ||
}) | ||
}) | ||
|
||
it('clicks the secondary origin link', () => { | ||
it('also uses cy.origin() + custom command', () => { | ||
cy.origin('somesite.com', () => { | ||
cy.visit('/page') | ||
cy.clickLink('Click Me') | ||
}) | ||
|
||
cy.origin('differentsite.com', () => { | ||
// WARNING: cy.clickLink() will not be available because it is a | ||
// different origin | ||
}) | ||
}) | ||
``` | ||
|
||
### Callback restrictions | ||
|
||
Because of the way in which the callback is transmitted and executed, there are | ||
certain limitations on what code may be run inside it. In particular, the | ||
following Cypress commands will throw errors if used in the callback: | ||
|
||
- `cy.origin()` | ||
- [`cy.intercept()`](/api/commands/intercept) | ||
- [`cy.session()`](/api/commands/session) | ||
- [`cy.server()`](/api/commands/server) | ||
- [`cy.route()`](/api/commands/route) | ||
- [`Cypress.Cookies.preserveOnce()`](/api/cypress-api/cookies) | ||
|
||
### Other limitations | ||
|
||
There are other testing scenarios which are not currently covered by | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have the red exclamation triangle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like it would make sense, though you should probably render it to see what the bolding and heading level do together
####
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM:
Addressed in 59809e4