2

How to Break 'for' loop inside promise 'Then' in Cypress Typescript as in below code:

for (let i = 2; i <= iterationspage; i++) {
    cy.wait(5000)
    cy.get(".page").contains(i).click()
    cy.log("clicked on page"+i)
    // let FlagFound='False'
    homePage.getProductNamesSearchResults().each(($el, index, $list)=> {
        const expProductName=$el.text()
        if(expProductName.includes(this.addtocart.ProductToBuy)){
            homePage.getAddToCartButton().eq(index).click()
            
            homePage.getPriceTagForSearchedProducts().eq(index).then(function(productPrice){
                cy.log(productPrice.text())
                cy.log(expProductName)
                
            }) 
        
            //break
        }
    })
}

3 Answers3

2

In fact you have two loops to break

  • the main for loop where break will stop it
  • the each loop where you can't use break because you are in a callback -> you can use every and return false to stop this loop when condition is meet

let iterationspage = 10;
let data = ['test1','test2','test3','test4']

for (let i = 2; i <= iterationspage; i++) {
      result = data.every(($el, index, $list) => {
        if ($el === 'test3') {
          return false;
        }
        console.log($el);
        return true;
      });
      if (!result) {
        break;
      }
}
jeremy-denis
  • 6,368
  • 3
  • 18
  • 35
  • 1
    your example works synchronously, but the initial question is about breaking inside a cypress command which is asynchronous. The loop will actually be completely executed when execution flow gets inside the cypress command. – Mikhail Bolotov Feb 03 '22 at 13:40
  • @jeremy-denis : In my case Array 'Data' is identified once you will click on page number.. homePage.getProductNamesSearchResults().each(($el, index, $list) – saya somjal Feb 03 '22 at 13:41
  • @Mikhail Bolotov: You are right.. I am trying to break both for(synchronous) and each(asynchronous)if condition satisfies.. – saya somjal Feb 03 '22 at 13:44
  • 1
    @sayasomjal, AFAIK, there is no easy way to break the loop asynchronously. You may try to rewrite your loop using recursion and check the exit condition inside a then callback. – Mikhail Bolotov Feb 03 '22 at 13:49
  • @Mikhail Bolotov : Will you please help me this way for my code? – saya somjal Feb 03 '22 at 13:55
  • I can only point you to this library: https://github.com/bahmutov/cypress-recurse May be it can help. – Mikhail Bolotov Feb 03 '22 at 13:58
  • Hello @MikhailBolotov..the issue is resolved with recursive function. Please find below solution...Thanks for your time everyone.. :) – saya somjal Feb 17 '22 at 11:34
0
Cypress.env("lengthProd",12)//page count
    findItem(ProductToFind)
    

function findItem(value: any){
    const homePage= new HomePage()
    const viewCartPopUp= new ViewCartPopUp()
    const shoppingCartPage= new ShoppingCartPage()
    
    
    function findInPage(index1: any){
        
        
        let found=false
        cy.get("div.bottom div div div cx-pagination a.page").its("length").then(len=>{

            if(index1>Cypress.env("lengthProd")){
                return false
            }else{
                cy.wait(5000)
                
                cy.get(".page").contains(index1).click({force:true})
                cy.log("clicked on page"+index1)
                cy.wait(10000)
                homePage.getProductNamesSearchResults().each(($el, index, $list)=> {
                    
                    const expProductName=$el.text()
                   
                    if(expProductName===value){
                        found =true
                        homePage.getAddToCartButton().eq(index).click()
                        homePage.getPriceTagForSearchedProducts().eq(index).then(function(productPrice){
                            cy.log(productPrice.text())
                            cy.log(expProductName)
                        })
                        
                        return false
                    }
                }).then(()=>{
                    if(!found){
                        findInPage(++index1)
                    }
                })
            }
        })
    }
    findInPage(1)
}
0

Looks like you're trying to click 'next page' until you find the thing you want to find? This was my (recursive) solution:

(note that loadingSpinner and asyncTableNextPage are just strings like [data-testid=whatever] or similar. It improved readability to pull them out into const variables.)

Cypress.Commands.add('paginateUntilTextAppears', (text: string, outerContainer: string = 'table') => {
  cy.get(outerContainer).should('exist');
  cy.get(loadingSpinner).should('not.exist');
  return cy
    .get(outerContainer)
    .then(container => container.find(`:contains(${text})`).length > 0)
    .then(found => {
      if (found) return true;
      return cy
        .get(asyncTableNextPage)
        .first() // i have "next" button at top and at bottom, so, pick one
        .then(nextBtn => {
          if (nextBtn.is('[disabled]')) return cy.log('out of pages to check');
          cy.get(asyncTableNextPage).first().click(); // maybe cy.wrap(nextBtn).click() ??
          cy.get(loadingSpinner).should('exist');
          cy.get(loadingSpinner).should('not.exist');
          return cy.paginateUntilTextAppears(text, outerContainer);
        });
    });
});
Ron Newcomb
  • 2,886
  • 21
  • 24