skip to Main Content

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

2

Answers


  1. 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.

    Login or Signup to reply.
  2. An alternative approach, set the data with a fixture so that you know exactly what page your text is on.

    Then your loops can be separate, and the Next action does not depend on flag.

    // Move to page directly
    const index = 3                    // if text is on 4th page
    for (let i = 1; i < index; i++) {
      cy.contains("Next").click()
    }
    
    // Find element on page
    let flag = false;
    cy.get(".MuiGrid-justify-xs-space-evenly .MuiGrid-container > p")
      .each((el) => {
         if (el.text() === "Test Attribute Do not touch") {
           cy.log("Condition met");
           flag = true;
           return;
         }
       })
      .should(() => expect(flag).to.eq(true))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search