Cypress throw an error when returning `true` inside the cy.waitUntil callback

This issue has been tracked since 2021-12-28.

Hello !

I'm using Cypress version 9.2.0 (latest) and cypress-wait-until version 1.7.2.

When I'm using cy.waitUntil( () => condition ), it works nice when the condition is falsy but as long as it become truthy, the test fail and cypress returns the following error:

cy.then() failed because you are mixing up async and sync code.

In your callback function you invoked 1 or more cy commands but then returned a synchronous value.

Cypress commands are asynchronous and it doesn't make sense to queue cy commands and yet return a synchronous value.

You likely forgot to properly chain the cy commands using another cy.then().

The value you synchronously returned was: true

node_modules/cypress-wait-until/src/index.js:64:47
  62 |       throw new Error(msg)
  63 |     }
> 64 |     cy.wait(options.interval, { log: false }).then(() => {
     |                                               ^
  65 |       retries--
  66 |       return resolveValue()
  67 |     })

Something is failing inside the source code... why ? is the wait-until broken after release v9 from Cypress ?

Here more details of my code which is failing:

      const obtainResults = (selector) => {
        let amount = 0;

        return cy.get('body').then($body => {
          amount = $body.find(selector).length;
          const data = { exist: amount > 0, numberOfElements: amount };
          return cy.wrap(data);
        })
      };

      cy.waitUntil(() => {
        return obtainResults("*css_selector**").then(({ exist }) => {
         return exist
        });
      });
Emidomenge wrote this answer on 2021-12-28

Actually I found a workaround:

Instead of returning a boolean, I'm doing an assertion:

 cy.waitUntil(() => {
        return obtainResults("*css_selector**")).its("exist").should("eq", true);
      });

And no more errors ! ๐ŸŽ‰

But I don't know if it's the actual fix as it's a bit tricky

NoriSte wrote this answer on 2021-12-28

I don't know how you are going to use obtainResults but I suggest you to try some simpler versions, like

cy.get('body')
  .waitUntil(($body) => $body.find('*css_selector**').length)
  .then((numberOfElements) => {
    // consume numberOfElements
  })

cy.get('body')
  .waitUntil(($body) => !!$body.find('*css_selector**').length)
  .then((exist) => {
    // consume exist
  })

or, even simpler

cy.waitUntil(() => Cypress.$('*css_selector**').length).then((numberOfElements) => {
  // consume numberOfElements
})

cy.waitUntil(() => !!Cypress.$('*css_selector**').length).then((exist) => {
  // consume exist
})

please let me know if:

  • my solution work
  • they are suitable for your use case

Thanks ๐Ÿ˜Š

Emidomenge wrote this answer on 2021-12-29

@NoriSte Yes indeed, your solutions are nice, thanks for the feedback, I appreciate it a lot. :)

NoriSte wrote this answer on 2021-12-29

You're more than welcome. I know that I haven't answered your "why does cypress throw this error?" question... But I tried to think from the outside because your code seemed (at least to me) to be unnecessarily complex ๐Ÿ˜Š

More Details About Repo
Owner Name NoriSte
Repo Name cypress-wait-until
Full Name NoriSte/cypress-wait-until
Language JavaScript
Created Date 2019-04-27
Updated Date 2023-03-19
Star Count 635
Watcher Count 8
Fork Count 24
Issue Count 3

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date