thewaiter: clicking on an element by using waits with Selenium

One of the most common ways of interacting with a page displayed in a browser, in Selenium tests, is clicking on a WebElement. But many times, due to the timing when the click happens, it will fail, since the WebElement that needs to be clicked is not yet available. This might be because some Javascript events have not finished enabling that WebElement, or other similar issues. Making clicks reliable can be done by using WebDriverWait, to wait until the click can actually happen.

The click is done in Selenium in a straightforward manner:

webElement.click();
The wait methods: click

The wait based approach method you can use to enable waiting for the WebElement to be clickable is described below (in two variants, depending if you send the timeout value as parameter or not).

The variant to which you pass the timeout value as int is:

public void click(WebElement element, WebDriver driver, int specifiedTimeout) {
 WebDriverWait wait = new WebDriverWait(driver, specifiedTimeout);
 ExpectedCondition<Boolean> elementIsClickable = arg0 -> {
   try {
      element.click();
      return true;
   } catch (Exception e) {
      return false;
   }
 };
 wait.until(elementIsClickable);
 }

The variant which uses the default timeout value as set in the Waiter class is (based on the previously defined click method):

public void click(WebElement element, WebDriver driver) {
     click(element, driver, TIMEOUT);
 }

What these methods do:

  • within the specified timeout period, every half a second, a click is tried
  • if the click succeeds the wait method exits. The rest of the test will be executed (the one from which you called the click method)
  • if the click failed, an Exception will be thrown. The fail could be caused by one of the following: the WebElement is not yet displayed, the WebElement is not clickable because it is “covered” by another WebElement, the WebElement is not instantiated yet, and so on. Whatever the issue is for the click being unsuccessful, other attempts to click will happen until the timeout period is reached or the click succeeded (within the timeout period).
  • A try/catch mechanism is used for the clicking, because the syntax for the WebDriver wait requires for a boolean value to be passed in the “wait.until” section (and when the click does not work it throws an Exception, and does not return a boolean value).
  • In case the click did not succeed within the allocated timeout period, a TimeoutException is thrown by method.
Example

The best way to show how the ‘click’ methods work, we can create a test that clicks on either a button or a link, somewhere on a page. For that, the first step in the test will be to open the page we are interested in, and then use the ‘click’ method. It will take a WebElement as a parameter, that must be defined in its’ own PageObject class.

In this example, in the PageObject class, called WaiterPage, i defined two WebElements: the first one that defines a search button, and the second one identifies a link on the page:

@FindBy(how = CSS, using = ".search-toggle")
public WebElement searchButton;
@FindBy(how = CSS, using = "#primary-menu li:nth-child(2) a") public WebElement menuLink;

The test class, apart from the actual test, contains the code that opens the browser and initializes the WaiterPage class.

There are two tests in the https://github.com/iamalittletester/learning-project/blob/master/src/test/java/waitertests/ClickTest.java class, one which uses the click method without specified timeout (using the default value of 30 seconds from ‘thewaiter’ library), and one that takes the timeout as parameter. The tests are very basic: open a URL, which happens to be this blog’s URL, then click on the search button at the top of the screen, and then click a link from the top level menu.

The variant with default timeout is:

@Test
public void clickTest() {
waiter.get("https://imalittletester.com", driver);
waiter.click(page.searchButton, driver);
waiter.click(page.menuLink, driver);
}

Each click method from this test will wait for up to 30 seconds for the click to succeed. If the click is not successful during this period, a TimeoutException will be thrown and the test will fail.

The variant with specified timeout is:

@Test
public void clickTestSpecifiedTimeout() {
waiter.get("https://imalittletester.com", driver);
waiter.click(page.searchButton, driver, 5);
waiter.click(page.menuLink, driver, 20);
}

In this test, the first click method will wait up to 5 seconds, while the second click method will wait for up to 20 seconds.

Where to find the code and examples

The GitHub repo of thewaiter library, with a “how to use” documentation:

https://github.com/iamalittletester/thewaiter

The downloadable release version of thewaiter:

https://mvnrepository.com/artifact/com.imalittletester/thewaiter

The library’s javadoc:

http://javadoc.io/doc/com.imalittletester/thewaiter/1.0

The tests that use the methods from this post:

https://github.com/iamalittletester/learning-project/blob/master/src/test/java/waitertests/ClickTest.java

2 thoughts on “thewaiter: clicking on an element by using waits with Selenium”

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.