Cypress wait for transition completes (wait for correct width)

3.6k views Asked by At

I have menu and burger button that toggles it, and want to test this behavior. But, menu does not disappear completely but just getting thinner when hidden (just icons visible), so I cannot just test if it's visible because it always is.

So instead I'm checking dimensions by invoke('width') like that:

cy.get('[data-test="sidebar"]')
  .invoke('width')
  .should('be.above', 200)
cy.get('[data-test="sidebar-toggle"]')
  .click()
cy.get('[data-test="sidebar"]')
  .invoke('width')
  .should('be.below', 100)

But I'm getting error ResizeObserver loop limit exceeded because it does not wait for menu transition to complete after click. So I just added wait(500) after click() and now it works. But isn't this little hacky? Now I need to set correct delay for every transition, or just always set very long one that will work for all transitions, but this is waste of testing time.

Is there any easy universal way tell Cypress to wait for my width to what it should be, instead just giving up right away?

EDIT: I was wrong about wait() solution, it does not really help. Error probably has nothing to do with transition. There is no need to use changed code from accepted answer - invoke works. But solution from this answer about ignoring error is correct - there are multiple questions about this error, and it is safe to ignore. So short answer - just ignore this exception. It can be placed not in test but in support/index.js so it will work globally.

1

There are 1 answers

2
Richard Matsen On BEST ANSWER

The .should() command has retry built in, but it looks like it's not retrying the complete chain.

Turn the should expression into a single step using a callback function with an expect inside.

cy.get('[data-test="sidebar"]')
  .should($el => expect($el.width()).to.be.above(200))

cy.get('[data-test="sidebar-toggle"]').click()

cy.get('[data-test="sidebar"]')
  .should($el => expect($el.width()).to.be.below(100))

According to ResizeObserver - loop limit exceeded the message is benign.

If Cypress fails your test because of this error, you can swallow it by adding this code to the top of the test

Cypress.on('uncaught:exception', (err, runnable) => {
  if (err.message.includes('ResizeObserver loop limit exceeded')) {
    return false
  }
})

Or change the call to ResizeObserver (in the application source) to include an animation frame request, for example

const resizeObserver = new ResizeObserver(entries => {
   // Wrap it in requestAnimationFrame to avoid "loop limit exceeded" error
   window.requestAnimationFrame(() => {
     if (!Array.isArray(entries) || !entries.length) {
       return;
     }
     // your code
   });
});