Fix discrepancies between .then and .should

This commit is contained in:
Jennifer Shehane
2017-06-13 11:28:25 -04:00
parent a433b1eaa7
commit 08a7954700
5 changed files with 58 additions and 32 deletions
@@ -1,7 +1,5 @@
all the differences in markdown
**What's the difference between `.then()` and `.should()`/`.and()`?**
***
Using `.then()` simply allows you to use the yielded subject in a callback function and should be used when you need to manipulate some values or do some actions.
asdfkljasdfl
## foo
When using a callback function with `.should()` or `.and()`, on the other hand, there is special logic to rerun the callback function until no assertions throw within it. You should be careful of side affects in a `.should()` or `.and()` callback function that you would not want performed multiple times.
+16 -5
View File
@@ -3,8 +3,6 @@ title: and
comments: true
---
{% partial then_should_difference %}
Make an assertion.
{% note info %}
@@ -80,13 +78,24 @@ cy
## Timeout
`.and()` will continue to retry the assertion to the duration of the previous cy commands `timeout` or the {% url `defaultCommandTimeout` configuration#Timeouts %}.
`.and()` will continue to retry until none of the assertions throw for the duration of the previous cy commands `timeout`.
```javascript
cy.get('input', {timeout: 10000}).should('have.value', '10').and('have.class', 'error')
// timeout here will be passed down to the '.and()'
// and it will retry for up to 10 secs
// timeout here will be passed down to the '.and()'
// and it will retry for up to 10 secs
```
```javascript
cy.get('input', {timeout: 10000}).should('have.value', 'US').and(function($input)){
// timeout here will be passed down to the '.and()'
// unless an assertion throws earlier,
// ALL of the assertions will retry for up to 10 secs
expect($input).to.not.be('disabled')
expect($input).to.not.have.class('error')
})
```
# Examples
@@ -213,6 +222,8 @@ The chainers that come from {% url 'Chai' bundled-tools#Chai %} or {% url 'Chai-
You can [read more about debugging assertions](https://on.cypress.io/guides/making-assertions#debugging-assertions) here.
{% partial then_should_difference %}
# Command Log
**Chain assertions on the same subject**
+26 -13
View File
@@ -68,6 +68,7 @@ cy
.get('nav') // yields <nav>
.should('be.visible') // yields <nav>
```
Although some chainers change what is yielded. In the example below, the second `.should()` yields the String 'sans-serif' because the chainer `have.css, 'font-family'` yields a string.
```javascript
@@ -79,13 +80,25 @@ cy
## Timeout
`.should()` will continue to retry the assertion to the duration of the previous cy commands `timeout` or the {% url `defaultCommandTimeout` configuration#Timeouts %}.
`.should()` will continue to retry until none of the assertions throw for the duration of the previous cy commands `timeout`.
```javascript
cy.get('input', {timeout: 10000}).should('have.value', '10')
// timeout here will be passed down to the '.should()'
// and it will retry for up to 10 secs
// timeout here will be passed down to the '.should()'
// and it will retry for up to 10 secs
```
```javascript
cy.get('input', {timeout: 10000}).should(function($input)){
// timeout here will be passed down to the '.should()'
// unless an assertion throws earlier,
// ALL of the assertions will retry for up to 10 secs
expect($input).to.not.be('disabled')
expect($input).to.not.have.class('error')
expect($input).to.have.value('US')
})
```
# Examples
@@ -114,10 +127,10 @@ cy.get('option:first').should('be.selected').then(function($option)){
cy.get('form').should('have.class', 'form-horizontal')
```
**Assert the value is not 'foo'**
**Assert the value is not 'Jane'**
```javascript
cy.get('input').should('not.have.value', 'foo')
cy.get('input').should('not.have.value', 'Jane')
```
**The current subject is yielded**
@@ -141,7 +154,7 @@ cy.get('#header a').should('have.attr', 'href', '/users')
**Verify length, content, and classes from multiple `<p>`**
Passing a function to `.should()` enables you to assert on the yielded subject. This gives you the opportunity to *massage* what you'd like to assert on.
Passing a function to `.should()` enables you to make multiple assertions on the yielded subject. This also gives you the opportunity to *massage* what you'd like to assert on.
Just be sure *not* to include any code that has side effects in your callback function. The callback function will be retried over and over again until no assertions within it throw.
@@ -191,16 +204,16 @@ Any errors raised by failed assertions will immediately bubble up and cause the
```
```javascript
cy.get("#todos li").should(function($lis){
cy.get('#todos li').should(function($lis){
expect($lis).to.have.length(3)
expect($lis.eq(0)).to.contain("Walk the dog")
expect($lis.eq(1)).to.contain("Feed the cat")
expect($lis.eq(2)).to.contain("Write JavaScript")
expect($lis.eq(0)).to.contain('Walk the dog')
expect($lis.eq(1)).to.contain('Feed the cat')
expect($lis.eq(2)).to.contain('Write JavaScript')
})
```
**Using a callback function will not change the subject**
**Using a callback function will not change what is yielded**
Whatever is returned in the function is ignored. Cypress always forces the command to yield the value from the previous cy command's yield (which in the example below is `<button>`)
@@ -250,8 +263,6 @@ cy.get('button').click()
.and('not.have.class', 'inactive')
```
You can [read more about how Cypress resolves your assertions](https://on.cypress.io/guides/making-assertions#resolving-assertions) here.
# Notes
**How do I know which assertions change the subject and which keep it the same?**
@@ -260,6 +271,8 @@ The chainers that come from {% url 'Chai' bundled-tools#Chai %} or {% url 'Chai-
You can [read more about debugging assertions](https://on.cypress.io/guides/making-assertions#debugging-assertions) here.
{% partial then_should_difference %}
# Command Log
**Assert that there should be 8 children in a nav**
+13 -4
View File
@@ -67,10 +67,10 @@ cy.get('form').find('input').then(function($input){
```javascript
cy.then(function(){
return {foo: 'bar'}
return {id: 123}
}).then(function(obj){
// subject is now the obj {foo: 'bar'}
expect(obj).to.deep.eq({foo: 'bar'}) // true
// subject is now the obj {id: 123}
obj.id === 123 // true
})
```
@@ -85,7 +85,7 @@ cy
}).find('input').then(function($input){
// we have our $input element here since
// our form element was yielded and we called
// .find("input") on it
// .find('input') on it
})
```
@@ -129,9 +129,18 @@ cy.get('button').click().then(function($button){
})
```
# Notes
{% partial then_should_difference %}
# Command Log
**`cy.then()` does *not* log in the command log**
# See also
- {% url `.and()` and %}
- {% url `.each()` each %}
- {% url `.invoke()` invoke %}
- [Issuing Commands](https://on.cypress.io/guides/issuing-commands)
- {% url `.its()` its %}
-5
View File
@@ -1,5 +0,0 @@
title: Guides
comments: true
---
# Placeholder