In my test project, I have a static class that contains a number of methods for basic interactions with WebElement
s. 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?
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);
}