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

3

15

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?

Transfusion answered 19/1, 2015 at 14:25 Comment(1)
Very good question! I would like to see a wise answer of this question.Moreland
P
11

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!

Parrakeet answered 19/1, 2015 at 15:4 Comment(4)
Yes, I have been writing selenium tests for a while now and never had to use that. But, can you at least show a high level implementation of that though?Moreland
Appreciate that @ sircapsalotMoreland
According to the documentation here: selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/… the ExpectedCondition.refreshed() expects another ExpectedCondition, and not a WebElement as in your example. Could you explain or update your example? Thanks.Hypophysis
@sircapsalot the above issue is a common one, whenever a developer uses a 'AutoPostBack="true"' , you do fall in the sort of situation. SeeDustan
S
12

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.

Sapir answered 27/6, 2017 at 22:42 Comment(1)
This is really good, was facing the same with search results.Bulbiferous
P
11

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!

Parrakeet answered 19/1, 2015 at 15:4 Comment(4)
Yes, I have been writing selenium tests for a while now and never had to use that. But, can you at least show a high level implementation of that though?Moreland
Appreciate that @ sircapsalotMoreland
According to the documentation here: selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/… the ExpectedCondition.refreshed() expects another ExpectedCondition, and not a WebElement as in your example. Could you explain or update your example? Thanks.Hypophysis
@sircapsalot the above issue is a common one, whenever a developer uses a 'AutoPostBack="true"' , you do fall in the sort of situation. SeeDustan
E
0

Should be like this

wait.until(ExpectedConditions.refreshed(ExpectedConditions.presenceOfElementLocated(By.id("myBtn"))));
Examen answered 17/5, 2023 at 1:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.