Cypress Assertion: 9 Facts You Should Know

Cypress Assertion helps us to assert a particular Assertions are validation steps that ensures whether the expected result is equal to the actual result. In test automation, we assert a statement to verify that the test is generating the expected result. If the assertion fails, then the test case fails ensuring that there is a bug. In this article, we will discuss about Cypress Assertion with Handson implementation and examples.

Table of Content

Cypress Assertion

What is Cypress Assertion?

Cypress uses and wraps Chai assertion library and extensions like Sinon and JQuery. Cypress automatically waits and retries until the assertion is resolved. Assertions can be used to describe how the application should look like. We can use Cypress assertions with combination of waits, retry, block until it reaches the desired state.

Cypress Assert Text

In general English, we would describe an assertion something like, I would expect the button to have login text. The same assertion can be written in Cypress as

cy.get('button').should('have.value', 'login')

The above assertion will pass if the button has ‘login’ value.

Cypress Common Assertions

There are a set of common Cypress assertion that we use in our test cases. We will be using them with .should() . Let us look into the use case and examples.

Some of the common Cypress assertion are listed below

  1. Length
  2. Value
  3. Text Context
  4. Class
  5. Existence
  6. CSS
  7. Visibility
  8. State
  9. Disabled Property

Cypress Length Assertion

length() will check if the particular element has length

cy.get('dropdown').should('have.length', 5)

Cypress Value Assertion

The Cypress value will assert if the particular element has the expected value

cy.get('textfield').should('have.value', 'first name')

Cypress Text Context Assertion

Text context will assert if the element has the particular text

cy.get('#user-name').should('have.text', 'John Doe')

Cypress Class Assertion

Asserts whether the class is present or the particular element should have the class

cy.get('form').find('input').should('have.class', 'disabled')

Cypress Existence Assertion

Existence command checks whether the particular element is present or exist in the DOM or not

cy.get('#button').should('exist')

Cypress CSS Assertion

CSS Assertion checks whether the particular elements has a particular property

cy.get('.completed').should('have.css', 'text-decoration', 'line-through')

Cypress Visibility Assertion

Cypress Visibility Assertion asserts whether the DOM element is visible in the UI

cy.get('#form-submit').should('be.visible')

Cypress State Assertion

Asserts the state of the DOM element

cy.get(':radio').should('be.checked')

Cypress Disabled Property Assertion

Cypress Disabled property assertion asserts whether the element is disabled

cy.get('#example-input').should('be.disabled')

Cypress Retry Assertion

A single command followed with an assertion will execute in order. Initially, the command executes and then the assertion will get executed. A single command followed by multiple assertions will also execute in order – first and second assertion respectively. So when the first assertion passes, the first and the second assertion will be executed along with the commands again.

For example, the below command contains both .should() and .and() assertion commands, where .and() is otherwise known as .should()

cy.get('.todo-list li') // command
  .should('have.length', 2) // assertion
  .and(($li) => {
    // 2 more assertions
    expect($li.get(0).textContent, 'first item').to.equal('todo A')
    expect($li.get(1).textContent, 'second item').to.equal('todo B')
  })

Cypress Assertion Examples

In this section, we will discuss on the different types of assertions in Cypress such as

  • Implicit Assertion
  • Explicit Assertion

We will look into detail on both the types with examples

Implicit Assertion in Cypress

In implicit assertion, we use .should() or .and() commands. These assertion commands apply to the currently yielded subject in the chain of commands. They are dependant on the previously yielded subject.

We will look into an example on how to use .should() or .and() commands

cy.get('button').should('have.class', 'enabled')

With .and() which is an alias of .should() ,we can chain multiple assertions. These commands are more readable.

cy.get('#title')
  .should('have.class', 'active')
  .and('have.attr', 'href', '/post')

The above example is chained with .should() stating it should have the class “active”, followed by .and() is executed against the same command. This is very helpful when we want to assert multiple commands.

Explicit Assertion in Cypress

Passing explicit subject in the assertions falls under the explicit type of Cypress assertion. Here, we will use expect and assert commands as assertion. Explicit assertions are used when we want to use multiple assertions for the same subject. We also use explicit assertion in Cypress when we want to do custom logic prior making the assertion.

We will look into the example for explicit Cypress assertion

expect(true).to.be.true //checks for a boolean
expect(object).to.equal(object)

Negative Cypress Assertion

Similar to positive assertions, there are negative assertion in Cypress. We will be using “not” keyword added to the prefix of the assertion statement. Let us see an example of negative assertion

cy.get('#loading').should('not.be.visible')

Negative assertion is recommended only in cases to verify that a particular condition is no longer available after a specific action is performed by the application.

For example, let us consider that a toggle is checked and verify that it has been removed

// at first the item is marked completed
cy.contains('li.todo', 'Write tests')
  .should('have.class', 'completed')
  .find('.toggle')
  .click()
// the CSS class has been removed
cy.contains('li.todo', 'Write tests').should('not.have.class', 'completed')

Cypress Custom Assertion Message

With Cypress, we can provide additional information or custom message for assertions by using a library of matchers. Matchers comprises of small functions that differentiate values and will throw detailed error message. Chai assertion library will help our code look more readable and test failure very useful

const expect = require('chai').expect
it('checks a number', () => {
  const value = 10
  const expected = 3
  expect(value).to.equal(expected)
})
cyyy
Cypress Custom Error message

Cypress Assertion Best Practices

We can write multiple assertions in a single block by using a chain of commands. It is not necessary to write single assertion like in unit tests. Many write assertions like below. It is okay to write in that manner, but it increases the line of code and redundancy.

describe('my form', () => {
  before(() => {
    cy.visit('/users/new')
    cy.get('#first').type('ashok')
  })
  it('has validation attribute', () => {
    cy.get('#first').should('have.attr', 'data-validation', 'required') // asserting whether the #first has required field
  })
  it('has active class', () => {
    cy.get('#first').should('have.class', 'active') // asserting whether the #first has active class
  })
  it('has formatted first name', () => {
    cy.get('#first').should('have.value', 'Ashok') // asserting whether the #first has capitalized first letter
  })
})

As you see above, the same selector and assertion type is getting repeated. Instead, we can chain these commands in one single assertion which performs all the checks in a linear fashion.

describe('my form', () => {
  before(() => {
    cy.visit('/users/new')
  })
  it('validates and formats first name', () => {
    cy.get('#first')
      .type('ashok')
      .should('have.attr', 'data-validation', 'required')
      .and('have.class', 'active')
      .and('have.value', 'Ashok')
  })
})

As mentioned above, we can chain the single selector with multiple assertions! This is one of the recommended best practices of writing assertion in Cypress.

To understand about the Page Object Model in Cypress, click here.