WebDriver tricks #3
Intro
It’s common case for dynamic pages to show / hide some elements basing on user’s actions. But covering them with stable WebDriver tests could be sometimes cumbersome. I’ll try to explain couple of techniques helping to deal with that sort of web pages.
Case #1
First approach I’d like to describe is rendering all the elements on page load but set CSS display
property to none
and later set it to empty or block
to make element visible.
In this case we can’t just check visibility by using webDriver.findElement(…)
since it will return valid element but we don’t know if it visible or not.
Fortunately WebElement
interface has method isDisplayed()
, however obvious solution webDriver.findElement(…).isDisplayed()
could be erroneous because JavaScript code that changes element visibility works with delays.
To overcome such problems we can use WebDriverWait
class.
WebDriverWait webDriverWait = new WebDriverWait(webDriver, 10L);
WebElement visibleElement = webDriverWait.until(new Function<Webdriver, WebElement>() {
@Override
public WebElement apply(WebDriver webDriver) {
WebElement we = webDriver.findElement(...);
return we.isDisplayed() ? we : null;
}
});
The code periodically finds element and checks its visibility.
When element exist and visible it will be returned by until(..)
method.
To check if element is invisible at the moment we can use similar approach just negating the condition in the function body
Case #2
There’s another option for dealing with show/hide certain parts of the page.
Your code can create required HTML on the fly while showing and remove elements from DOM while hiding.
To check element visibility we can use approach described above. But for checking if the part of the page is not shown to customer
we can’t use that because there’s no elements in DOM and if we try to use findElement(…)
we will get the exception.
Issue could be solved by using WebDriverWait
findElements(…)
method that doesn’t throw an exception but return empty list if no elements found.
WebDriverWait webDriverWait = new WebDriverWait(webDriver, 10L);
webDriverWait.until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver webDriver) {
return webDriver.findElements(...).size() == 0;
}
});
Code periodically searches for elements matching criteria and return true when no elements found.