I was going through methods of ExpectedCondtions
class and found one method: refreshed
I can understand that the method can be used when you get StaleElementReferenceException
and you want to retrieve that element again and this way to avoid StaleElementReferenceException
My above understanding might not be correct hence I want to confirm:
refreshed
should be used?something
part of following code:wait.until(ExpectedConditions.refreshed(**something**));
Can someone please explain this with an example?
According to the source:
Wrapper for a condition, which allows for elements to update by redrawing. This works around the problem of conditions which have two parts: find an element and then check for some condition on it. For these conditions it is possible that an element is located and then subsequently it is redrawn on the client. When this happens a {@link StaleElementReferenceException} is thrown when the second part of the condition is checked.
So basically, this is a method that waits until a DOM manipulation is finished on an object.
Typically, when you do driver.findElement
that object represents what the object is.
When the DOM has manipulated, and say after clicking a button, adds a class to that element. If you try to perform an action on said element, it will throw StaleElementReferenceException
since now the WebElement
returned now does not represent the updated element.
You'll use refreshed
when you expect DOM manipulation to occur, and you want to wait until it's done being manipulated in the DOM.
<body>
<button id="myBtn" class="" onmouseover="this.class = \"hovered\";" />
</body>
// pseudo-code
1. WebElement button = driver.findElement(By.id("myBtn")); // right now, if you read the Class, it will return ""
2. button.hoverOver(); // now the class will be "hovered"
3. wait.until(ExpectedConditions.refreshed(button));
4. button = driver.findElement(By.id("myBtn")); // by this point, the DOM manipulation should have finished since we used refreshed.
5. button.getClass(); // will now == "hovered"
Note that if you perform say a button.click()
at line #3, it will throw a StaleReferenceException since the DOM has been manipulated at this point.
In my years of using Selenium, I've never had to use this condition, so I believe that it is an "edge case" situation, that you most likely won't even have to worry about using. Hope this helps!
The refreshed
method has been very helpful for me when trying to access a search result that has been newly refreshed. Trying to wait on the search result by just ExpectedConditions.elementToBeClickable(...)
returns StaleElementReferenceException
. To work around that, this is the helper method that would wait and retry for a max of 30s for the search element to be refreshed and clickable.
public WebElement waitForElementToBeRefreshedAndClickable(WebDriver driver, By by) {
return new WebDriverWait(driver, 30)
.until(ExpectedConditions.refreshed(
ExpectedConditions.elementToBeClickable(by)));
}
Then to click on the result after searching:
waitForElementToBeRefreshedAndClickable(driver, By.cssSelector("css_selector_to_search_result_link")).click();
Hope this was helpful for others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With