Ryan Southcliff
Ryan Southcliff

Reputation: 223

In my Cypress.io tests why do I need to treat a cy.task like it is asyncronous when its not

I have Cypress.io tests that use a simple Cypress task to log some table information to the terminal. For example I have a test like so:

it("Writes some console logs and checks a val", () => {
  cy.task("rowLog", { id: 1, name: "foo", type: "bar" });
  let one = 1;
  expect(one).to.equal(2);
});

And the task, "rowLog" like so:

module.exports = (on, config) => {
  on("task", {
  rowLog(data) {
    // use node.js console.table to pretty print table data:
    console.table(data);
    return null;
  },
}

But the result of rowLog will not display in my terminal if I run Cypress headlessly via Cypress run. This is because the test will fail. If we switch the test so that it passes, then it will show.

However I just realized that if I treat rowLog like it's async like below. It will print the results to the terminal:

it("Writes some console logs and checks a val", () => {
  // add a .then to task:
  cy.task("rowLog", { id: 1, name: "foo", type: "bar" }).then(() => {
    let one = 1;
    expect(one).to.equal(2);
  });
});

This is not what I would expect from the docs. They say that:

cy.task() yields the value returned or resolved by the task event in the pluginsFile. (source)

And that a task can yield either a promise or a value.

I'm new to Cypress here-- is there something I'm missing or doing wrong? I'd like to be able to not have to chain my tasks with .then statements if it is just synchronous stuff like writing output to ensure everything is emitted to my terminal.

Upvotes: 1

Views: 1929

Answers (1)

Mikhail Bolotov
Mikhail Bolotov

Reputation: 1104

If you look into the type definition of cy.task command, you will see that it returns a Chainable (that is a promise-like entity). So it behaves like any other cy command (ansynchrounously). As for the yield either a promise or a **value** - this statement refers to the handler of the task, not the task itself. As for the other command, Cypress will wrap a returned value into a promise if it was not done by the handler.

Upvotes: 2

Related Questions