Lesson 11 / 25

Retry-Ability and Assertions

should, and, and the default timeout.

Queries retry until assertions pass

Cypress retries queries such as cy.get, .find and cy.contains together with the assertions attached by .should() and .and(), until the assertion passes or the command timeout (4 seconds by default, defaultCommandTimeout) expires. Actions such as .click() are not retried, but Cypress waits for the element to be actionable first. Assertions use Chai, chai-jQuery and Sinon-Chai: should('be.visible'), should('have.text', 'Saved'), should('have.length', 3), should('contain', 'Done'). Put the assertion directly on the query you want retried; an assertion inside .then() runs only once.

Retrying assertions

should with chainers and with a callback.

it('shows three saved items', () => {
  cy.visit('/items');
  cy.get('[data-cy=save-all]').click();

  cy.get('[data-cy=toast]').should('be.visible').and('contain', 'Saved');
  cy.get('[data-cy=item]').should('have.length', 3);

  // callback form: retried until the expectations inside pass
  cy.get('[data-cy=item]').should(($items) => {
    expect($items.first()).to.contain.text('Alpha');
  });

  // a longer timeout for one slow query
  cy.get('[data-cy=report]', { timeout: 10000 }).should('exist');
});

Avoid splitting a query from its assertion

Chains like cy.get(...).then(...).should(...) stop retrying at .then. Keep the query and its .should() adjacent so the whole check retries together.

Quick check: Which part of `cy.get('li').should('have.length', 3)` is retried?

  • Only the click that follows
  • Neither; it runs exactly once
  • Only the assertion, against the first result
  • Both the cy.get query and the length assertion, until it passes or times out
Answer

Both the cy.get query and the length assertion, until it passes or times out — Queries and their assertions retry together.