Cypress: cy.wrap does not respect timeout

Created on 17 Dec 2019  Â·  9Comments  Â·  Source: cypress-io/cypress

This example spec file fails with the error below:

describe('Cypress wait', () => {
  it('wrap does not wait', () => {
    cy.wrap(
        new Promise((resolve) => setTimeout(resolve, 5000)), {timeout: 20000});
  });
});
 Cypress wait
    1) wrap does not wait


  0 passing (4s)
  1 failing

  1) Cypress wait wrap does not wait:
     Error: Cypress command timeout of '4000ms' exceeded.
      at http://localhost:57838/__cypress/runner/cypress_runner.js:103532:25

Shouldn't cy.wrap respect the timeout option? The test passes if I pass --config defaultCommandTimeout=6000 on the command line, but I want to pass a specific timeout for this cy.wrap command.

first-timers-only pkdriver bug

Most helpful comment

Hello here is a workaround to force Cypress to wait for a promise:


/**
 *  helper function that forces cy to wait for a promise
 *
 * @export
 * @param {Promise} promise promise to wait
 * @param {number} [interval=1000] recheck in minlisecons
 * @returns
 */
export function waitPromise(promise, interval = 1000) {
  let isDone = false;

  const runPromise = () => {
    if (isDone) {
      // Wrap and returns the result
      return cy.wrap(promise.catch(error => assert.isNotOk(true, error)));
    }
    return cy.wait(interval).then(() => runPromise());
  };

  // Marks as resolved
  promise.then(() => (isDone = true)).catch(() => (isDone = true));

  return runPromise();
}

And in-use example

it('Restore Password - Should received an email', () => {
  const task = emailHelper.searchLastEmail({
    emailAddress: user.email,
    subject: 'Reset Password',
    timeout: 2 * 60000 // 2 min
  });

  testHelpers.waitPromise(task).then(mail => {
    // Save for later test
    restorePasswordMail = mail;
    return expect(mail).not.to.be.null;
  });
});

All 9 comments

I do feel like it should respect the timeout option here.

The code for the .wrap() command can be found here:

https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/commands/misc.coffee#L28:L28

should the entire run wait for the timeout before advancing the test? Won't that potentially make the test take too long?

Not sure I understand the question. Is it different from how you expect
cy.get to behave with respect to the timeout?

On Sun, Jan 26, 2020, 8:41 AM Datner notifications@github.com wrote:

should the entire run wait for the timeout before advancing the test?
Won't that potentially make the test take too long?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/cypress-io/cypress/issues/5980?email_source=notifications&email_token=ACNKK4FUASS2HXDU5DUAY43Q7WHJRA5CNFSM4J3WN6CKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJ5UDCQ#issuecomment-578503050,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ACNKK4HQBM2YCANTZ6LAWB3Q7WHJRANCNFSM4J3WN6CA
.

Please read the docs for the defaultCommandTimeout definition. https://on.cypress.io/configuration#Timeouts It is not per test, but per command and yes, increasing the timeout will sometimes increase the test time when it has to potentially retry for the entirety of the command timeout.

I am seeing the same issue. I am using cy.wrap to make an async call to set up some data. Sometimes it takes longer than 4 seconds which causes the test to fail.

I'm seeing the same problem. I'm setting the timeout property to 12000 and I'm still getting the "4000ms timeout exceeded" error.

Using cypress version 3.6.1

Hello here is a workaround to force Cypress to wait for a promise:


/**
 *  helper function that forces cy to wait for a promise
 *
 * @export
 * @param {Promise} promise promise to wait
 * @param {number} [interval=1000] recheck in minlisecons
 * @returns
 */
export function waitPromise(promise, interval = 1000) {
  let isDone = false;

  const runPromise = () => {
    if (isDone) {
      // Wrap and returns the result
      return cy.wrap(promise.catch(error => assert.isNotOk(true, error)));
    }
    return cy.wait(interval).then(() => runPromise());
  };

  // Marks as resolved
  promise.then(() => (isDone = true)).catch(() => (isDone = true));

  return runPromise();
}

And in-use example

it('Restore Password - Should received an email', () => {
  const task = emailHelper.searchLastEmail({
    emailAddress: user.email,
    subject: 'Reset Password',
    timeout: 2 * 60000 // 2 min
  });

  testHelpers.waitPromise(task).then(mail => {
    // Save for later test
    restorePasswordMail = mail;
    return expect(mail).not.to.be.null;
  });
});

The code for this is done in cypress-io/cypress#7284, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

Released in 4.8.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v4.8.0, please open a new issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zbigniewkalinowski picture zbigniewkalinowski  Â·  3Comments

scottcrowe picture scottcrowe  Â·  3Comments

stormherz picture stormherz  Â·  3Comments

weskor picture weskor  Â·  3Comments

jennifer-shehane picture jennifer-shehane  Â·  3Comments