I was trying to automate the following scenario:
The steps I've followed to script this scenario:
All the bestsellers has the same xpath:
//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span
So I've implemented this a list of WebElements as follows:
List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
I've implemented the clicking on a link and adding to the cart using loop in 3 ways as follows:
for(WebElement product: bestsellers) {
product.click();
clickOnAddToCartButton();
driver.navigate().back();
}
for(int i=0; i<bestsellers.size(); i++) {
System.out.println(bestsellers.size());
bestsellers.get(i).click();
clickOnAddToCartButton();
driver.navigate().back();
}
Iterator<WebElement> i = bestsellers.iterator();
while(i.hasNext()) {
WebElement product = i.next();
wait.until(ExpectedConditions.elementToBeClickable(product));
product.click();
clickOnAddToCartButton();
driver.navigate().back();
}
There are 3 elements in the list 'bestsellers' When I had run the script. When the loop is executed, the first element is getting clicked and added to the cart and the driver navigates back to the results page. Then I'm getting staleElementReferenceException using the above 3 ways.
Update: I've implemented the scenario as follows:
for(int i=0; i<bestsellers.size(); i++) {
System.out.println("Current :" + i);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")));
driver.findElements(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")).get(i).click();
clickOnAddToCartButton();
//clickOnViewCart();
try {
wait.until(ExpectedConditions.elementToBeClickable(cartButton));
}catch(TimeoutException e) {
wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
}
if(i==(bestsellers.size()-1)) {
try {
wait.until(ExpectedConditions.elementToBeClickable(cartButton));
cartButton.click();
break;
}catch(TimeoutException e) {
wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
viewCartButton.click();
break;
}
}
driver.navigate().back();
The moment you click on the element or back() in the browser the element reference will updated in the selenium so you can not point to the elements with the old references and which led to the StatleElementException
.
Consider this approach when you have to iterate through multiple elements interaction.
List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(int i=0; i<bestsellers.size(); i++) {
System.out.println("Current Seller " + i);
// here you are getting the elements each time you iterate, which will get the
// latest element references
driver.findElements(By.xpath("xpath of bestsellers")).get(i).click();
clickOnAddToCartButton();
driver.navigate().back();
}