6

I have a custom cypress command which performs some asynchronous tasks, and based on the result of the command I want to perform some assertions

But the problem is the tests that come after calling the command will either run before the command finishes or will have wrong values.

below is my code

Command

Cypress.Commands.add("testCommand", () => {
    cy.request("http://localhost:3000/testApi").then(({ body }) => {
        cy.request(`http://localhost:3000/testApi${body.query}`).then(() => {
            console.log("success");
        });
    });
});

test

describe("Summary Page", () => {
    it("my demo test", () => {
        console.log("before command runs");

        cy.testCommand();

        console.log("after command runs");
    });
});

Actual result

before command runs
after command runs
success

Required result

before command runs
success
after command runs

as you can see the output after command runs will run before the command finished

Is there any way to wait for the command to complete before moving forward with tests

jayesh
  • 61
  • 1
  • 3

5 Answers5

7

Regardless of whether or not your custom command returns a cypress chain, you can run code after the command wrapping it in a then callback:

describe('Summary Page', () => {
  it('my demo test', () => {
    console.log('before command runs')
    cy.testCommand()
    cy.then(() => {
      console.log('after command runs')
    })
  })
})

As for using async/await, Cypress by default does not support async/await, see this issue and the long discussion inside it.

To reduce the number of callback you may try either cypress-promise or cypress-thenify libraries. However, each of them has it's own limitations.

Mikhail Bolotov
  • 976
  • 1
  • 6
  • 13
2

Along with above answers , you can also use wait() and do the synchronous operations

describe("Summary Page", () => {

    it("my demo test", () => {
        console.log("before command runs");

        cy.testCommand().as('getCommand');
        cy.wait('@getCommand').then((interception) => {
        console.log("after command runs");
    })  
});

Refer to this for more details: https://docs.cypress.io/api/commands/wait#Alias

Umesh Sulakude
  • 286
  • 2
  • 14
1

Try something like this

  Cypress.Commands.add("testCommand", () => {
    cy.request("http://localhost:3000/testApi").then(({ body }) => {      
      cy.request(
        `http://localhost:3000/testApi${body.query}`
      ).then(() => { console.log("success"); });
    }).as('myRequest')
  
    cy.wait(
      '@myRequest', {timeout:30000}
    ).its('response.statusCode').should('eq', '200')
  });
Viktor Ivliiev
  • 1,015
  • 4
  • 14
  • 21
majac
  • 11
  • 3
0

It's due to the fact that non-cypress commands runs asynchronously meaning it will not necessarily run the commands in sequence in which it is written. To tackle this you can use then(), something like:

describe('Summary Page', () => {
  it('my demo test', () => {
    console.log('before command runs')
    cy.testCommand().then(() => {
      console.log('after command runs')
    })
  })
})
Alapan Das
  • 17,144
  • 3
  • 29
  • 52
  • hey alapan thanks for quick response .. i have two doubts .. first my command is not chainable so .then is not working on it ... secondly is there any way to not chain like this and use something like await in js i am new to cypress so don't have much idea about it .. thanks – jayesh Jan 26 '22 at 14:27
  • Please add the original code in order to give a proper answer. Yes async-await can help in this regard. – Alapan Das Jan 26 '22 at 14:55
  • The actual code is a bit complicated that's why I have provided the simplified demo code with almost exact condition as actual code – jayesh Jan 26 '22 at 15:00
0

If console.log() is not necessary, then you can replace with cy.log(), which will log to the test runner. That way you can replace at the exact locations without altering too much of you code.

Command

Cypress.Commands.add("testCommand", () => {
    cy.request("http://localhost:3000/testApi").then(({ body }) => {
        cy.request(`http://localhost:3000/testApi${body.query}`).then(() => {
            // you may want to add some assertion here, maybe expected status code
            cy.log("success");
        });
    });
});

test

describe("Summary Page", () => {
    it("my demo test", () => {
        cy.log("before command runs");
        cy.testCommand();
        cy.log("after command runs");
    });
});
jjhelguero
  • 2,281
  • 5
  • 13