0

I am trying to loop through a list of products, identify products with discount and click on the first product with discount and and navigate to product page. While looping through for loop I get stale element exception. I tried adding a wait as well.

HTML View:

     <div class="slick-track" style="opacity: 1; width: 2448px; transform: translate3d(0px, 0px, 0px);">
   <div class="views-row slick-slide slick-current slick-active" style="width: 286px;" tabindex="0" data-slick-index="0" aria-hidden="false">
      <article class="commerce-product--phones commerce-product--catalog">
         <div class="no-promotions-block"></div>
         <div class="product-catalog">
            <div class="field field--name-title field--type-string field--label-hidden field--item">SAMSUNG GALAXY A5</div>
            <div class="product--variation-field--variation_field_images__14 field field--name-field-images field--type-image field--label-hidden field--items">
               <div class="field--item">  <img loading="lazy" src="https://dialog-qa-bucket.s3.ap-southeast-1.amazonaws.com/s3fs-public/styles/product_thumbnail/public/2022-06/phone_Samsung_2.png?itok=4XnjLLPj" width="92" height="100" alt="Alternative_02" typeof="foaf:Image" class="image-style-product-thumbnail">
               </div>
            </div>
            <div class="product--variation-field--variation_price__14 field field--name-price field--type-commerce-price field--label-hidden field--item">Rs. 0.00</div>
            <div class="list-price">
               Original Price&nbsp;
               <div class="product--variation-field--variation_list_price__14 field field--name-list-price field--type-commerce-price field--label-hidden field--item">Rs. 165,000.00</div>
            </div>
            <div class="buy-now-button">
               <a href="/product/14" class="commerce-product--catalog__hover-text" tabindex="0">BUY NOW</a>
            </div>
         </div>
      </article>
   </div>
   <div class="views-row slick-slide slick-active" style="width: 286px;" tabindex="0" data-slick-index="1" aria-hidden="false">
      <article class="commerce-product--phones commerce-product--catalog">
         <div class="promotions-block">
            <div class="promotions-text">
               <div class="field field--name-field-offer-tag-line field--type-string field--label-hidden field--item">Special price 10% OFF</div>
            </div>
         </div>
         <div class="product-catalog">
            <div class="field field--name-title field--type-string field--label-hidden field--item">Samsung Note 10 - V3</div>
            <div class="product--variation-field--variation_field_images__10 field field--name-field-images field--type-image field--label-hidden field--items">
               <div class="field--item">  <img loading="lazy" src="https://dialog-qa-bucket.s3.ap-southeast-1.amazonaws.com/s3fs-public/styles/product_thumbnail/public/2022-04/gsmarena_005.jpg?itok=fgpdOvFL" width="96" height="100" alt="Samsung Galaxy S21 - V3" typeof="foaf:Image" class="image-style-product-thumbnail">
               </div>
            </div>
            <div class="product--variation-field--variation_price__10 field field--name-price field--type-commerce-price field--label-hidden field--item">Rs. 179,000.00</div>
            <div class="list-price">
               Original Price&nbsp;
               <div class="product--variation-field--variation_list_price__10 field field--name-list-price field--type-commerce-price field--label-hidden field--item">Rs. 179,000.00</div>
            </div>
            <div class="buy-now-button">
               <a href="/product/10" class="commerce-product--catalog__hover-text" tabindex="0">BUY NOW</a>
            </div>
         </div>
      </article>
   </div>
   <div class="views-row slick-slide slick-active" style="width: 286px;" tabindex="0" data-slick-index="2" aria-hidden="false">
      <article class="commerce-product--phones commerce-product--catalog">
         <div class="promotions-block">
            <div class="promotions-text">
               <div class="field field--name-field-offer-tag-line field--type-string field--label-hidden field--item">Special promotion 30% OFF</div>
            </div>
         </div>
         <div class="product-catalog">
            <div class="field field--name-title field--type-string field--label-hidden field--item">OPPO 60 SE - V4101</div>
            <div class="product--variation-field--variation_field_images__1 field field--name-field-images field--type-image field--label-hidden field--items">
               <div class="field--item">  <img loading="lazy" src="https://dialog-qa-bucket.s3.ap-southeast-1.amazonaws.com/s3fs-public/styles/product_thumbnail/public/2022-03/BE2011%201_0.jpg?itok=QOq2qFGz" width="79" height="100" alt="Front view" typeof="foaf:Image" class="image-style-product-thumbnail">
               </div>
            </div>
            <div class="product--variation-field--variation_price__1 field field--name-price field--type-commerce-price field--label-hidden field--item">Rs. 110,000.00</div>
            <div class="list-price">
               Original Price&nbsp;
               <div class="product--variation-field--variation_list_price__1 field field--name-list-price field--type-commerce-price field--label-hidden field--item">Rs. 110,000.00</div>
            </div>
            <div class="buy-now-button">
               <a href="/product/8" class="commerce-product--catalog__hover-text" tabindex="0">BUY NOW</a>
            </div>
         </div>
      </article>
   </div>
</div>

Here is my page class:

public WithDiscountNavigationPage navigateToDiscountProduct() {
        
        //product article
        List<WebElement> article = driver.findElements(By.xpath("//article[@class='commerce-product--phones commerce-product--catalog']"));
        
        for(WebElement product: article) {
            
        //wait
        WebDriverWait wait = new WebDriverWait(driver, 30);
            
        //locate promotional element
        WebElement discountText = product.findElement(By.xpath("//div[@class='promotions-text']"));
        
            if(discountText.isDisplayed()) {
                
                System.out.println("enter if");
                
                //locate buy now button
                WebElement buyNow = product.findElement(By.xpath("//a[text()='BUY NOW']"));
                
                JavascriptExecutor js = (JavascriptExecutor) driver;
                js.executeScript("arguments[0].click();", buyNow);
                
            }else {
                System.out.println("No products with discount");
            }
        
        }
        
                
        // return class object
        return new WithDiscountNavigationPage();        
    }

Error trace:

rg.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

Please help me to fix this.

3 Answers 3

0

The stale element reference error exception occurs because the referenced web element is no longer attached to the DOM. And by looking at the code, I will try to guess the reason.

you have List<> article say on Page A Now you are iterating through this list and for let's say for 1st product, you found BUY NOW link, and you clicked on it. It will navigate you to say Page B Now when you are iterating to the 2nd product, you are actually on Page B where there is no reference to product, so you won't able to perform any actions and will get StaleElementReferenceException

You have to write a code to move back to Page A the retrieve list again and then visit unvisited products.

Hope this answer helps you to find a solution.

Cheers!

0

Agree with @krishna:

Design something like :

try{
   // your_steps_to_perform_action
}
catch(){
   // print_your_exception_take_action
}
finally {
   // Navigate_back_to_page_A
}

and understand more detail on stale element reference exception visit my answer

0

The "Stale Element Reference Exception" occurs when an element is no longer available in the DOM tree due to some changes in the page. To overcome this issue, you can wrap the element interaction within a try-catch block and re-fetch the element inside the catch block. You can also use WebDriverWait with expected_conditions.element_to_be_clickable to wait for the element to become clickable before clicking.

Here's an example implementation in Java using Selenium:

import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Main {
   public static void main(String[] args) {
      // Create a new instance of the Chrome driver
      WebDriver driver = new ChromeDriver();
      WebDriverWait wait = new WebDriverWait(driver, 30);

      // Navigate to the website
      driver.get("https://www.example.com");

      // Find all products
      List<WebElement> products = driver.findElements(By.cssSelector("article.commerce-product--catalog"));

      // Loop through all products
      for (WebElement product : products) {
         // Check if the product has a discount
         WebElement discount = product.findElement(By.cssSelector(".promotions-block"));
         if (discount != null) {
            // Click on the first product with discount
            product.findElement(By.cssSelector(".buy-now-button a")).click();

            // Wait until the product page is loaded
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#product-details")));

            // Break the loop
            break;
         }
      }

      // Close the browser
      driver.quit();
   }
}

This code first locates all the products using the CSS selector .commerce-product--phones.commerce-product--catalog. It then loops through each product, checking for the existence of a .promotions-text element within each product. If it exists, it means the product is on discount, so it finds the product link using the CSS selector .commerce-product--catalog__hover-text and clicks on it. The code then breaks out of the loop to navigate to the product page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.