Search code examples
cypress

Cypress async command confusion


describe('Post Resource', () => {
  it('Creating a New Post', () => {
    cy.visit('/posts/new') // 1.

    cy.get("input.post-title") // 2.
      .type("My First Post"); // 3.

    cy.get("input.post-body") // 4.
      .type("Hello, world!"); // 5.

    cy.contains("Submit") // 6.
      .click(); // 7.

    cy.get("h1") // 8.
      .should("contain", "My First Post");
  });
});

This example is taken from the Cypress documentation. I'm struggling with 2 statements from the documentation about Cypress commands.

  1. Remember: Cypress commands are asynchronous and get queued for execution at a later time.

  2. Cypress guarantees that it will execute all of its commands and queries deterministically and identically every time they are run.

Using the example above there are 5 commands, they will all be enqueued and run "asynchronously" but yet "deterministically"?

Either each command is run in the order it was added to the queue and the next waits for the previous to complete or they all run asynchronously, i.e. independently of each other.

How do we ensure that "Hello, world!" is added to the post body before we click Submit for example unless the commands are actually run in sequence and synchronously?


Solution

  • Queries like cy.get() are asynchronous, they repeat until the DOM satisfies the query or they timeout and the test stops. So cy.get("input.post-body") will keep checking the DOM until it finds that element.

    The command queue is synchronous. One command or query has to complete and pass before the next one starts, which is why .click() on Submit does not happen until .type("Hello, world!") has finished.