Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How and when to implement refreshed(ExpectedCondition<T> condition) of Selenium WebDriver?

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:

  1. When refreshed should be used?
  2. What should be the code for something part of following code:

wait.until(ExpectedConditions.refreshed(**something**));

Can someone please explain this with an example?

like image 675
Alpha Avatar asked Jan 19 '15 14:01

Alpha


2 Answers

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.

Example:

<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!

like image 135
ddavison Avatar answered Oct 20 '22 02:10

ddavison


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.

like image 43
HaC Avatar answered Oct 20 '22 01:10

HaC