Search code examples
cypress

How to pause when an assertion fails?


Cypress has assertions (cy.should) and a way to pause the test runner (cy.pause). Is there any way to connect the two, so that if a should fails, the test runner pauses?

I know I can do:

cy.should(whatever)
  .pause();

...but that pauses every time. I only want to pause if the should fails.

You might think:

try {
  cy.should(whatever)
} catch (err) {
  cy.pause();
}

would work, but it doesn't, because (like everything in Cypress) the actual throwing of the error doesn't happen at the should line, it happens later on (when it can't be caught).

Similarly, I tried doing:

cy.on('uncaught:exception', () => {
  cy.pause();
});
cy.should(whatever);

But it doesn't work, presumably because by the time the error is caught using cy.on, it's already too late to pause.


Solution

  • You answer fails with

    CypressError:

    cy.should() failed because you invoked a command inside the callback.
    ...
    Use cy.then() instead of cy.should(), or move any commands outside the callback function.

    But if you just swap .then() for should() as the message suggests

    cy.visit('https://example.com')
    cy.get('h1').then(el => {
      if (el.innerText !== 'foo') cy.pause();
      expect(el).to.have.text('foo');
    })
    

    it also fails because expect() is synchronous and cy.pause() is asynchronous - the .then() runs to completion before the newly queued pause command can run.

    AssertionError:

    expected '<h1>' to have text 'foo', but the text was 'Example Domain'


    Use an else branch

    cy.visit('https://example.com')
    cy.get('h1').then(el => {
      if (el.innerText !== 'foo') {
        cy.pause()
      } else {
        expect(el).to.have.text('foo')
      }
    })
    

    enter image description here

    But note, with this pattern you lose retry.