skip to Main Content

I want first to get the #product_list for the full elements list on the current page and then find every element in this list
If the element .ajax_block_product.col-xs-12.col-sm-4.col-md-3[data-id-product=’22578′] is in the first page then click it, else click on the #pagination_next_bottom button on the bottom of page and search again in other pages to find the element present in #product_list element

I tried with this function but it only finds every page and navigates without clicking on desired element.

// findItem("Printer Brother MFP Laser HL1222WEYJ1");

      // function findItem(value) {
      //   let found = false;
      //   let attempts = 0;
      //   const maxAttempts = 20; // Define a maximum number of attempts
      
      //   function clickNext() {
      //     cy.get("#pagination_next_bottom").click()
      //     cy.wait(5000);
      //   }
      
      //   function findInPage() {
      //     if (found || attempts >= maxAttempts) {
      //       return; // If item found or max attempts reached, exit
      //     }
      
      //     cy.get("#product_list li div.produkti h5").each(itemNameEl => {
      //       const itemText = itemNameEl.text();
      //       console.log(itemText);
      //       if (itemText === value) {
      //         found = true;
      //         cy.get(itemNameEl).should('be.visible').click(); // Click the parent element of the product
      //         return false;
      //       }
      //     });
      
      //     if (!found) {
      //       clickNext(); // Click the "Next" button
      //       attempts++; // Increment attempts
      //       findInPage(); // Continue searching on the next page
      //     }
      //   }
      
      //   findInPage();
      // }

2

Answers


  1. The issue in your code is that the line where you check if the object is found (if (!found)) is synchronous, and runs before Cypress executes (asynchronously) and potentially updates the value of found. Because you are executing Cypress commands inside of the synchronous functions, I’d recommend using a Cypress custom command to handle your recursion.

    Cypress.Commands.add("findItem", (value, attempt) => {
      let currAttempt = attempt ?? 0;
      const maxAttempts = 20;
    
      if (attempt < maxAttempts) {
        let found = false;
        cy.get("#product_list li div.produkti h5")
          .each(($item) => {
            const itemText = $item.text();
            console.log(itemText);
            if (itemText === value) {
              found = true;
              return false;
            }
          })
          .then(() => {
            if (!found) {
              cy.get("#pagination_next_bottom").click();
              cy.wait(5000);
              cy.findItem(value, currAttempt++);
            } else {
              cy.wrap($item).should("be.visible").click(); // Click the parent element of the product
            }
          });
      } else {
        expect(true === false); // placeholder assertion to fail if too many attempts are made
      }
    });
    
    

    Also, moving the cy.wrap($item)... line to the .then() block allows the .each() block to be completely synchronous and not be in competition with any Cypress commands for execution times.

    Login or Signup to reply.
  2. Two things that might be a problem (since click is not happening)

    • itemText === value This might need an inexact match like itemText.includes(value) due to whitespace chars

    • cy.get('itemNameEl') maybe needs to be cy.wrap('itemNameEl'), although I’m not convinced of that

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search