Home > Enterprise >  Why do pre-defined variables not behave as expected in Cypress?
Why do pre-defined variables not behave as expected in Cypress?

Time:08-05

I'm getting wacky results when pre-defining element variables and using them afterwards in Cypress 10 w/ Cucumber. Consider this login test:

Given("I'm logged in as Default user", () => {        

    cy.visit('/');

    let usernameField = cy.get('#myUsernameInputField');
    let passwordField = cy.get('#myPasswordInputField');
    let signInButton = cy.get('#mySignInButton');
  
    usernameField.clear();

    usernameField.type('[email protected]');
   
    passwordField.type('myPassword');
  
    signInButton.click();

});

This results in both the username and password being typed into the passwordField, and the signInButton never being clicked. Only when I rearrange the variables in a more chronological order does this test behave as expected:

Given("I'm logged in as Default user", () => {

    cy.visit('/');

    let usernameField = cy.get('#myUsernameInputField');
    usernameField.clear();
    usernameField.type('[email protected]');

    let password = cy.get('#myPasswordInputField');
    password.type('myPassword');
  
    let signInButton = cy.get('#mySignInButton');
    signInButton.click();

});

I planned to eventually move these variables into a page object file. But here in the test, they don't behave as expected when I pre-define them and try to use them later. Why is this?

CodePudding user response:

Basically, you shouldn't hold references to query results in plain javascript variables.

The reason is, Cypress runs on a queue system and the queue has only one "subject" at any time.

You should think of the queue as a separate thread or execution process that runs asynchronously to the test execution, so it's possible that the variables in the thread are getting out of sync with the queue subject.


The conventional way to do this is to use the query results immediately like

cy.get('#myUsernameInputField').type('[email protected]');

then move on to the next query (password).

If for some reason you do need a reference to the query result, Cypress has an alias mechanism to handle it

cy.get('#myUsernameInputField').as('username)

...
// later in the test

cy.get('@username').type('[email protected]');

CodePudding user response:

You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously.

https://docs.cypress.io/guides/core-concepts/variables-and-aliases

  • Related