Search code examples
javascripttypescriptautomationcypress

How to use static nested loops in cypress


I am trying to automate one test scenario where i am first traversing pages one by one and on each page i am traversing list of elements until i find my desired element, but when my condition is met in the if statement i am setting a flag to stop both the loops, but the outer loop keeps on running till the last page even if my condition is already met at 2nd page can you guys please help me in this

my method

clickOnNextBtnUntilDisable() {
    cy.get(".MuiPagination-ul li button").last().invoke("text").as("lastPage");
    cy.get("@lastPage").then((lastPageText) => { 
      const index = parseInt(lastPageText, 10); // converting last page text into int.
      let flag = false;
      for (let i = 1; i < index; i++) {
        cy.get(".MuiGrid-justify-xs-space-evenly .MuiGrid-container > p").each(
          (el, index) => {
            if (el.text() === "Test Attribute Do not touch") {
              cy.log("Condition met");
              flag = true;
              return;
            }
          }
        );
        if (!flag) {
          cy.contains("Next").click();
        } else {
          return;
        }
      }
    });
  }

my test

it("Adding question to existing attribute", function () {
    dashBoardPage.clickOnSwitchView();
    dashBoardPage.clickOnAttributes();
    attributesPage.clickOnNextBtnUntilDisable();
  });

Sharing UI Images for ref 1st page enter image description here

2nd page and so on enter image description here


Solution

  • Aliasing the flag

    You could use an alias to test your flag condition:

    let flag = false;
    cy.wrap(flag).as('stop')
    
    for (let i = 1; i < index; i++) {
      cy.get('@stop').then(stop =>
        if (!stop) {
    
            cy.get(".MuiGrid-justify-xs-space-evenly .MuiGrid-container > p").each(
            (el, index) => {
                if (el.text() === "Test Attribute Do not touch") {
                  cy.log("Condition met");
                  flag = true;
                  cy.wrap(flag).as('stop')
                  
                  return          // <-- early exit for .each()
                }
              }
            )
    
            // also need the alias check here, since above .each() needs to finish
            cy.get('@stop').then(stop =>
              if (!stop) {
                cy.contains("Next").click();
              }
            })
    

    This "coordinates" the static for() loop with the results of the dynamic queries inside the loop.

    Without the line cy.get('@stop').then(stop =>, the code is enqueuing all the commands onto the queue before the command queue has started to run.