Skip to content

Cypress - Assertions

Assertions are a fundamental part of testing, as they verify that your application is in the expected state. Cypress bundles the Chai assertion library, providing powerful and readable ways to make assertions. It also includes Sinon-Chai for asserting on spies, stubs, and clocks, and jQuery-Chai for jQuery-specific assertions.

Cypress assertions can be broadly categorized into implicit and explicit assertions.

Implicit Assertions (using .should() and .and())

Section titled “Implicit Assertions (using .should() and .and())”

Implicit assertions apply to the ‘subject’ yielded by the previous Cypress command in a chain. The most common commands for implicit assertions are .should() and its alias .and(). These commands automatically retry until the assertion passes or a timeout is reached.

Example of implicit assertions:

describe('Implicit Assertions Example', function() {
it('Validates element properties', function() {
cy.visit('https://example.cypress.io/commands/assertions');
cy.get('.assertion-table tbody tr').eq(2)
.should('have.class', 'success') // Asserts class on the <tr>
.find('td').eq(1) // Now the subject is the second <td>
.should('have.text', 'Column content') // Asserts text content of the <td>
.and('contain', 'content') // Alias for .should(), still on the same <td>
.and('not.contain', 'Foobar');
// Asserting on multiple list items
cy.get('.assertion-list li')
.should('have.length', 3) // Asserts number of <li> elements
.and('include.text', 'List item 1'); // Checks if any li contains this text
});
});

Execution Results for Implicit Assertions:

The Command Log will show each assertion passing. If an assertion were to fail after retrying, the test would fail at that step, highlighting the failed assertion and the reason.

Explicit Assertions (using expect() and assert())

Section titled “Explicit Assertions (using expect() and assert())”

Explicit assertions allow you to assert directly on a specific value or object. You typically use Chai’s expect (BDD style) or assert (TDD style) for this. These are often used within a .then() callback where you have direct access to the yielded subject.

Example of explicit assertions:

describe('Explicit Assertions Example', function() {
it('Uses expect and assert', function() {
cy.visit('https://example.cypress.io/commands/querying');
// Using expect
cy.get('#query-btn').then(($button) => {
const buttonText = $button.text();
expect(buttonText).to.equal('Button');
expect($button).to.have.class('query-btn');
expect($button).not.to.be.disabled;
});
// Using assert (less common in Cypress tests but available)
const person = { name: 'Joe', age: 20 };
assert.isObject(person, 'person is an object');
assert.equal(person.name, 'Joe', 'name should be Joe');
// Example with a simple variable
const myVar = true;
expect(myVar).to.be.true;
});
});

Execution Results for Explicit Assertions:

The Command Log will show steps like .then(). The assertions themselves (expect/assert) don’t create new log entries but will cause the test to fail if they don’t pass within the .then() callback.

Cypress also has Default Assertions built into many of its commands. For example:

  • cy.visit(): Expects the page to send text/html content with a 200 status code.
  • cy.request(): Expects the remote server to exist and provide a response.
  • cy.get(): Expects the element to exist in the DOM (retries until it does or times out).
  • cy.contains(): Expects an element with the content to eventually exist in the DOM.
  • .find(): Expects the element(s) to exist within the current subject.
  • .type(): Expects the element to be in a typeable state.
  • .click(): Expects the element to be in an actionable state (e.g., visible, not disabled).

Here are some common Chai assertions you’ll frequently use with .should() or expect():

Checks the number of elements yielded by the previous command.

cy.get('ul > li').should('have.length', 3);

Checks if the element has a specific CSS class.

cy.get('button.primary').should('have.class', 'active');
cy.get('button.primary').should('not.have.class', 'disabled');

Checks the value of an input, textarea, or select element.

cy.get('input[name="email"]').type('test@example.com').should('have.value', 'test@example.com');

Checks the text content of an element. have.text matches exactly, contain.text or include.text checks for partial match.

cy.get('h1').should('have.text', 'Welcome!');
cy.get('p').should('contain.text', 'important information'); // alias for include.text

Checks if the element is visible or hidden to the user.

cy.get('.modal').should('be.visible');
cy.get('.tooltip').should('not.be.visible');

Checks if the element exists or does not exist in the DOM.

cy.get('#loading-spinner').should('not.exist');
cy.get('main#content').should('exist');

Checks if the element has a specific CSS property and value.

cy.get('.error-message').should('have.css', 'color', 'rgb(255, 0, 0)'); // Color can be hex, rgb, etc.
cy.get('button').should('have.css', 'display', 'block');
  • be.disabled / be.enabled: Checks if an element (like a button or input) is disabled or enabled.
  • be.checked / not.be.checked: For checkboxes or radio buttons.
  • have.attr / not.have.attr: Checks for the presence or value of an attribute (e.g., href, data-testid).
  • match: Asserts that the subject matches a regular expression.

Common Learning Obstacle: Knowing when to use implicit vs. explicit assertions. Generally, prefer implicit assertions (.should()) for commands that yield DOM elements due to their built-in retry-ability. Use explicit assertions (expect()) inside .then() when you need to work with the yielded value directly or perform more complex logic.

For a comprehensive list of Chai assertions, refer to the Chai.js documentation: [https://www.chaijs.com/api/]