Home > OS >  Cypress: How to get value of div (mixing up async and sync code)
Cypress: How to get value of div (mixing up async and sync code)

Time:04-13

I have a div with the following html

<div data-cy="pop" style="margin-right:5px;">12,300</div>

I am trying to get 12,3001 convert it to a int and save the value for use in another function. I am getting this error.

cy.then() failed because you are mixing up async and sync code.The value you synchronously returned was: 12300

Here is my code to get the value.

cy.elem('pop').invoke('text').then((num) => {
            const res = parseInt(num.replaceAll(',',''))
            return res
        })

Does anyone know what I'm doing wrong?

CodePudding user response:

It's not clear how you are attempting to pass the value of your parsed int into the another function.

One way to save the value of something is with an alias. To do that you will need to use the .as().

cy.elem('pop')
  .invoke('text')
  .then((num) => { return parseInt(num.replaceAll(',','')) })
  .as('num')

// later down in your code
cy.get('@num')
  .then(number => {
    functionYouWantToPassYourNumber(number)
  })

CodePudding user response:

Bit of an edge-case, TLDR: return cy.wrap(res).

If I run this as a minimal test for your code, it passes

const num = "12,300";
cy.wrap(num).then((numAsString) => {
  const numAsInt = parseInt(numAsString.replace(",", ""));
  return numAsInt
})
.then(num => {
  cy.log(num)   // logs 12300    ✅ 
})

If I add an async line cy.wait(5000) (for example), it fails

const num = "12,300";
cy.wrap(num).then((numAsString) => {
  const numAsInt = parseInt(numAsString.replace(",", ""));
  cy.wait(5000)
  return numAsInt
})
.then(num => {
  cy.log(num)                    ❌
})

If I then cy.wrap() the result, it passes again

const num = "12,300";
cy.wrap(num).then((numAsString) => {
  const numAsInt = parseInt(numAsString.replace(",", ""));
  cy.wait(5000)
  return cy.wrap(numAsInt)
})
.then(num => {
  cy.log(num)   // logs 12300    ✅ 
})

Theoretically your code should pass, but if you have another command inside the .then() that could be causing it.

Or possible the cy.elem('pop') is causing it.


For reference, this is Cypress' own test for the error

describe("errors", {defaultCommandTimeout: 100}, () => {

  beforeEach(function () {
    this.logs = [];

    cy.on("log:added", (attrs, log) => {
      this.lastLog = log;
      this.logs?.push(log);
    });

    return null;
  });

  it("throws when mixing up async   sync return values", function (done) {
    cy.on("fail", (err) => {
      const { lastLog } = this;

      assertLogLength(this.logs, 1)
      expect(lastLog.get("error")).to.eq(err);
      expect(err.message).to.include(
        "`cy.then()` failed because you are mixing up async and sync code."
      );

      done();
    });

    cy.then(() => {
      cy.wait(5000);

      return "foo";
    });
  });
});
  • Related