In my test project, I have a static class that contains a number of methods for basic interactions with WebElements. I have two separate methods for clicking a WebElement, one that uses the WebElement.click() method:
public static void click(WebElement element, WebDriverWait w) {
if (element == null) {
return;
}
try {
w.until(ExpectedConditions.elementToBeClickable(element)).click();
} catch (TimeoutException ex) {
Assert.fail("Test failed, because element with locator: " element.toString().split("->")[1] " was not found on the page or unavailable");
}
}
and one that uses the Actions.click(WebElement).build().perform() method:
public static void click(WebElement element, Actions a, WebDriverWait w) {
if (element == null) {
return;
}
try {
a.click(w.until(ExpectedConditions.elementToBeClickable(element))).build().perform();
} catch (TimeoutException ex) {
Assert.fail("Test failed, because element with locator: " element.toString().split("->")[1] " was not found on the page or unavailable");
}
}
I also have a method for finding and then clicking an option from a menu:
public void selectItem(IMenuButton button) {
for (WebElement item : w.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("*[role='menuitem']")))) {
if (item.findElement(By.tagName("span")).getText().trim().equalsIgnoreCase(button.getButton())) {
// This throws StaleElementReferenceException
Interaction.click(item, a, w);
// This works
Interaction.click(item, w);
return;
}
}
Assert.fail("No menu item found for: " button.getButton());
}
When I use Interaction.click(item, w), it works, but Interaction.click(item, a, w) throws StaleElementReferenceException, and I can't figure out why. I need the method that uses Actions.click() in case the option needs to be scrolled into view. Any ideas?
- Selenium 4
- Chromedriver 99
- Java
CodePudding user response:
Usually, when you scroll down or up - the DOM changes. StaleElementReferenceException means that an element you once found has been moved or deleted. When going over elements inside a loop, very often elements inside a dropdown or scrollView, you need to find them all over again. Otherwise you will get this exception over and over again.
Try to do this:
try {
Interaction.click(item, a, w);
} catch (StaleElementReferenceException sere) {
// re-find the item by ID, Xpath or Css
item = driver.findElementByID("TheID");
//click again on the element
Interaction.click(item, a, w);
}
