7.3 KiB
title, comments
| title | comments |
|---|---|
| should | false |
Make an assertion.
{% note info %}
An alias of {% url .and() and %}
{% endnote %}
{% note info %}
Note: .should() assumes you are already familiar with core concepts such as {% url 'assertions' cypress-in-a-nutshell#Assertions %}
{% endnote %}
Syntax
.should(chainers)
.should(chainers, value)
.should(chainers, method, value)
.should(callbackFn)
Usage
.should() requires being chained off another cy command.
{% fa fa-check-circle green %} Valid Usage
cy.get('.error').should('be.empty') // Assert that '.error' is empty
cy.contains('Login').should('be.visible') // Assert that el is visible
{% fa fa-exclamation-triangle red %} Invalid Usage
cy.should('eq', '42') // Errors, cannot be chained off 'cy'
Arguments
{% fa fa-angle-right %} chainers (String)
Chainers that come from {% url 'Chai' bundled-tools#Chai %} or {% url 'Chai-jQuery' bundled-tools#Chai-jQuery %}
{% fa fa-angle-right %} value (String)
Value to assert against chainer.
{% fa fa-angle-right %} method (String)
A method to be called on the chainer.
{% fa fa-angle-right %} callbackFn (Function)
Pass a function that can have any number of explicit assertions within it. Whatever was passed to the function is what is yielded.
Yields
In most cases, .should() yields the previous cy command's yield.
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.
cy
.get('nav') // yields <nav>
.should('be.visible') // yields <nav>
.should('have.css', 'font-family') // yields 'sans-serif'
Timeout
.should() will continue to retry until none of the assertions throw for the duration of the previous cy commands timeout.
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
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
Chainers
Assert the checkbox is disabled
cy.get(':checkbox').should('be.disabled')
The current DOM element is yielded
cy.get('option:first').should('be.selected').then(function($option)){
// $option is yielded
})
Chainers with Value
Assert the class is 'form-horizontal'
cy.get('form').should('have.class', 'form-horizontal')
Assert the value is not 'Jane'
cy.get('input').should('not.have.value', 'Jane')
The current subject is yielded
cy.get('button').should('have.id', 'new-user').then(function($button){
// $button is yielded
})
Chainers with Method and Value
Assert the href is equal to '/users'
// have.attr comes from chai-jquery
cy.get('#header a').should('have.attr', 'href', '/users')
Function
Verify length, content, and classes from multiple <p>
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.
<div>
<p class="text-primary">Hello World</p>
<p class="text-danger">You have an error</p>
<p class="text-default">Try again later</p>
</div>
cy
.get('p')
.should(function($p){
// should have found 3 elements
expect($p).to.have.length(3)
// make sure the first contains some text content
expect($p.first()).to.contain('Hello World')
// use jquery's map to grab all of their classes
// jquery's map returns a new jquery object
var classes = $p.map(function(i, el){
return cy.$(el).attr('class')
})
// call classes.get() to make this a plain array
expect(classes.get()).to.deep.eq([
'text-primary',
'text-danger',
'text-default'
])
})
Assert explicitly within .should()
Any errors raised by failed assertions will immediately bubble up and cause the test to fail.
<div id="todos">
<li>Walk the dog</li>
<li>Feed the cat</li>
<li>Write JavaScript</li>
</div>
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')
})
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>)
cy
.get('button').should(function($button){
expect({foo: 'bar'}).to.deep.eq({foo: 'bar'})
return {foo: 'bar'} // return is ignored, .should() yields <button>
})
.then(function($button){
// do anything we want with <button>
})
Multiple Assertions
Chaining multiple assertions
Cypress makes it easy to chain assertions together.
In this example we use {% url .and() and %} which is identical to .should().
// our subject is not changed by our first assertion,
// so we can continue to use DOM based assertions
cy.get('option:first').should('be.selected').and('have.value', 'Metallica')
Wait until the assertions pass
Cypress won't resolve your commands until all of its assertions pass.
// Application Code
$('button').click(function(){
$button = $(this)
setTimeout(function(){
$button.removeClass('inactive').addClass('active')
}, 1000)
})
cy.get('button').click()
.should('have.class', 'active')
.and('not.have.class', 'inactive')
Notes
How do I know which assertions change the subject and which keep it the same?
The chainers that come from {% url 'Chai' bundled-tools#Chai %} or {% url 'Chai-jQuery' bundled-tools#Chai-jQuery %} will always document what they return.
{% partial then_should_difference %}
Command Log
Assert that there should be 8 children in a nav
cy.get('.left-nav>.nav').children().should('have.length', 8)
The commands above will display in the command log as:
When clicking on assert within the command log, the console outputs the following:
See also
- {% url
.and()and %} - {% url 'Assertions' cypress-in-a-nutshell#Assertions %}

