Reputation: 1087
I have created the following method:
public void waitAndClickElement(WebElement element) throws InterruptedException {
try {
Boolean elementPresent = this.wait.until(ExpectedConditions.elementToBeClickable(element)).isEnabled();
if (elementPresent == true && element.isDisplayed()) {
element.click();
System.out.println("Clicked on the element: " + element.getText());
}
} catch (StaleElementReferenceException elementUpdated) {
Boolean elementPresent = wait.until(ExpectedConditions.stalenessOf(element));
if (elementPresent == true) {
WebElement staleElement = element;
staleElement.click();
System.out.println("Clicked on the 'Stale' element: " + element.getText());
}
} catch (NoSuchElementException e) {
System.out.println("Exception! - Could not click on the element: " + element.getText() + ", Exception: "+ e.toString());
throw (e);
} finally {
}
}
But I Still seem to get the following exception below:
Expected condition failed: waiting for element (Proxy element for: DefaultElementLocator 'By.xpath: //a[text()='Exchange Now »']') to become stale (tried for 20 second(s) with 500 MILLISECONDS interval)
But the same method will work on let's say 18 out of 20 builds, any ideas?
thanks for you help
Upvotes: 3
Views: 16647
Reputation: 25542
The direct answer to your question is that you are waiting for an already stale element to become stale. I'm not sure what your intent was there.
Your function is overly complex and won't work as you think it might.
If an element is clickable it's also enabled and displayed, so you don't need to check all three. If the element is throwing a StaleElementReferenceException
, it's not going to become "unstale."
I would recommend you replace your current function with the below.
public void waitAndClickElement(By locator)
{
try
{
this.wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
}
catch (TimeoutException e)
{
System.out.println("Count not click element <" + locator.toString() + ">");
}
}
Pass the locator instead of the element instead of the element itself, that will simplify a lot of things. If the element exists and is clickable, it will be clicked. If it does not exist or never becomes clickable, it will throw a TimeoutException
which you can catch.
Also, writing element.toString()
is going to write some ID for the element which is not going to be human readable or meaningful. You're better off to write locator.toString()
which will return the type of locator, e.g. By.cssSelector: #hplogo
.
Upvotes: 1
Reputation: 4586
If you change site with another driver.get("http://completely.different.site.com/");
, this element will be stale (no more in DOM). Staleness means that the element in DOM is not accessible.
Upvotes: 1