Improve your UI Test Automation Performance with Dynamic Wait

When we write our UI test automation, we probably write our test like this open the web page, input something on web page, click to continue, assert the result appears and so on. From one test step to another test step, that’s what ideally we want from our test automation, running smoothly between one test step to the another without any delay.

But unfortunately, that is not always the cases, the website that we test might not always run smoothly, there might be some wait that need to happen before we could continue to our next steps. This wait could happen intentionally like example if we press a button there might be some process that need 1–2 seconds before it could continue, or this could also happen unintentionally like maybe the internet connection having some delay that slow down the response from our web. And there is still many other more factors that could happens when we run our UI automation test, especially if our test run on remote server.

So in that situation, we might need some wait function to pause our automation for a while before continuing, In Java there is a quite popular function called Thread.sleep() where you could use this to pause your thread for a while, or if you use Serenity framework for your automation, you might know a function called waitABit() which act the same way as Thread.sleep(). Can both of this functions do wait for our automation? Yes. Is it the best way to wait on test automation? Not really. Here is why…

Illustration of static vs dynamic wait

Imagine there are 2 robots called Robot X and Robot Y, both of this robots are programmed to do some test for 1 hour on some factory. This factory have a unique door, where the door will open at some random time between 07:00 A.M. — 08:00 A.M. every day, so at Monday the door could open at 07:10 A.M. or maybe at Tuesday it could be open at 07:45 A.M., and so on, where ate worst the door could be open at 08:00 A.M.

While both robots are programmed to do the same task, they are programmed differently when waiting for the door to open. Robot X is programmed to wait exactly 1 hour, so every day it will go the door and wait for an hour, and enter the door exactly ate 08:00 A.M., then Robot X do it’s 1 hour task and finish at 09:00 A.M. every day. But Robot Y is different, it’s programmed to check whether door is open or not every 5 min, so if at Monday the door open at 07:15 A.M. Robot Y will enter the door after 3 times check and finish it’s task at 08:15 A.M. or if at Wednesday the door open at 07:30 A.M. it will finish it task at 08:30 A.M.

From this examples we could see that while Robot X always finish it’s task at 09:00 A.M. every day, Robot Y could adapt and finish it’s task faster depending on when the door will be open. This also applied to test automation, if we used static wait like Thread.sleep(), our automation will always take the longest time to finish it’s task, but if we use a dynamic wait where we check the condition that need to be check every certain interval, we could achieved a much better time with our automation.

Thankfully Selenium provided dynamic wait, there are 3 types of wait, which are Implicit, Explicit, and Fluent Wait:

  • Implicit Wait: driver will be waiting when the DOM finding any elements, it will check whether the element is found or not within a certain frequency until the timeout we defined.
  • Explicit Wait: driver will be waiting for the condition that we defined, it will also check the condition within certain frequency until the specified timeout.
  • Fluent Wait: it’s mostly the same with Explicit Wait, we could define the frequency when checking the condition and also we could ignore an exception that could be thrown when searching for the element.

Implicit wait is the most simple dynamic wait, we don’t need to declare any conditions to be wait, only the timeouts of when finding elements and Implicit wait only need to be declare once and it will be applied for the whole test until it’s done. If you need to check for certain condition, it’s better to use Explicit wait where you could define the condition that want to be wait, and if you want to be more detail you could use Fluent wait to define the frequency when checking the condition.

The condition here is already provided by the Selenium, it’s under a class called ExpectedConditions. This class provides many conditions and I am listing couple of them over here:

  • elementToBeClickable()
  • presenceOfElementLocated()
  • visibilityOf()
  • and many more…

You could also define your own ExpectedCondition, if the condition provided by Selenium is not what you needed.

Code example when using each wait:

If you are using Serenity framework along with your Selenium, Serenity also provided Implicit and Explicit Wait that could be used

In the Serenity version to declare the Implicit wait we are using a function called setImplicitTimeout, the function will appear within the class that extends PageObject class from Serenity.

For the Explicit Wait, notice that we don’t need need to declare any new WebDriverWait or something related, we only need to called a function withTimeoutOf to declare the timeout duration and waitFor to check the condition. You could also use waitFor directly without using the withTimeoutOf function, the default timeout will be 2 second when using waitFor function directly.

With dynamic wait you could improve your automation, especially when the DOM load time is not always as expected. Rather than using a static wait like Thread.sleep, it’s better to check whether the element is ready or not within a certain frequency, so that it could handle the random load time that might occurs on the web page.

I hope this article could give your more insight for your automation, thanks for reading it.

Reference:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store