Selenium: How to wait for an element to be displayed / not displayed

In my previous post i talked about how to check whether an element is displayed or not. There are times when tests where such an action is performed fail randomly (sometimes they will pass, other times they won’t). The assumption here is that the element was not displayed within a decent amount of time when there were test failures, but would have appeared later on. Therefore if the test would have waited a little bit before performing the presence check, it would have passed.

In this case many people tend to put a Thread.sleep() line of code before any presence checks, with a hardcoded value for the time (hardcoding for how many seconds the test will wait before attempting an interaction with the element). That is generally a poor practice, especially because – if the element becomes available in a shorter time that the value specified in the sleep method, the test will uselessly wait for the whole amount of time before proceeding. By using several such lines of code within a single test, the test execution time will increase considerably.

Inspired by another post, where i described how to wait for UI events, below are two methods that will help to – wait for an element to be displayed and wait for the element to ‘disappear’. These should be used instead of all the Thread.sleep() lines of code.

Implementation

The first thing you need to consider is the amount of time you are willing to wait for an element to be displayed. Let’s say you store the value for this time in a variable, which you name ‘timeout’. During that time, a check for the presence of the element will be done periodically, until the ‘timeout’ elapses. Now, depending on what you checked for (the presence or absence of the element), if during this time the condition you were expecting was not fulfilled, the code will exit with an Exception. If the condition is met while still in a time range below the value of ‘timeout’, the condition will not be checked anymore. In this case, the check will be fulfilled in an amount of time lower than the defined value for ‘timeout’.
This has two major benefits: you have a better chance of passing the test, since you wait for an adequate time for the condition to be fulfilled; you wait until you have to – you give your test enough time to check for a condition, knowing that beyond that allocated time there is no way the condition could be met.
Let’s say you want to assign a value of 10 seconds to your timeout:

private final int TIMEOUT = 10;
Waitinging for element to be displayed
public void waitUntilElementDisplayed(final WebElement webElement, WebDriver driver) {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
ExpectedCondition elementIsDisplayed = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver arg0) {
  try {
     webElement.isDisplayed();
     return true;
  }
  catch (NoSuchElementException e ) {
    return false;
  }
  catch (StaleElementReferenceException f) {
    return false;
  }
    }
};
wait.until(elementIsDisplayed);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
Waiting for element not to be displayed
public void waitUntilElementNotDisplayed(final WebElement webElement, WebDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
ExpectedCondition elementIsDisplayed = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver arg0) {
  try {
     webElement.isDisplayed();
     return false;
  }
  catch (NoSuchElementException e ) {
    return true;
  }
  catch (StaleElementReferenceException f) {
    return true;
  }
    }
};
wait.until(elementIsDisplayed);
}
Not working for you?

Note: Sometimes when using the above method for waiting for an element to be displayed, you might have the sensation that the method is incorrect, since it might sometimes fail. That is not case, so if it fails, consider one of the following scenarios:

1. You used the method for waiting for the element, it executed successfully, but the next interaction with the element threw an error, saying that element is not there. For this case, the wait method did what it was supposed to (it found the element). However some code that was later executed on the page might have made the element disappear (either remove it from the DOM/HTML or hide it).
2. The above code did not find the element, but you are looking at the page and you see it is there. In this case, check whether you properly created the webelement (did you correctly specify the selector for it?). Also, make sure it is not in an iframe for example, and if it is, that you properly included it in the element definition.
Basically what i am trying to say is that if the above methods do not work in your case, the answer may lie in the implementation behind the page. So if you find that these methods are not working properly for your tests, just use the debug to see exactly how the elements are behaving.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s