As a wanderer in automation worlds and a big fan of Selenium, I’m always eager to explore tools as much as possible. The most exciting thing about this hobby is that you can usually find out the beauty and the ugly of them and then challenge yourself to solve tools’ problems.
Selenium Wait Command you already know
One of the essential skills to master in Selenium is the use of the Wait commands. But ironically, this important skill is not for writing better scripts but for dealing with the timing issue in Selenium automation. And as you already know, that is due to the emergence of front end technologies such as Javascript or Ajax, which cause elements on web pages not available for interacting at predictable time intervals.
Anyway, let’s dive into the details of those Wait techniques, especially the disadvantages I have experienced with them, which I believe might be good for you to know.
Let’s take a look at the overview chart of Selenium Waits below:
I will use this website to make an example for this post.
Implicit Wait
The implicit wait will tell the WebDriver to wait for a certain amount of time when trying to find an element(s) if they are not immediately available before it throws a NoSuchElementException message. It is the global wait for all driver.findelement instances with the default setting are 0. This means that any find element on the page could take the time of implicit wait is set for.
Implicit wait comes in handy as it’s easy for applying and adjusting. However, this type of approach is a game of guess since the execution time depends heavily on many external factors such as browser performance, network performance, or application server performance. No one can tell how long to wait is optimized as waiting too long leads to waste while being too short leads to more likelihood of failure.
In the above example script, the value of the implicit wait is given as 30 seconds. If an element or elements are not immediately available on the web page, the wait command will trigger and wait until the WebDriver can find the web elements and continue the next steps. After 30 seconds, if the web element(s) could not be found, it raises an exception message, and the test will fail.
Implicit Wait methods take two arguments:
- Time — Amount of time to wait before throwing an exception.
- Unit — Time unit, which could be SECONDS, MILLISECONDS, MINUTES, etc.
I do not recommend using implicit waits in the automation scripts, especially in the new front-end technologies such as Javascript or Ajax, where each action does not reload the page or render it again. Example with the below the web page, after navigating to the homepage, the element //*[@id =”pageContent”] will show the text value as:
Hello, this is a demo for a Tutorialzine tutorial. To test it, click some of the buttons above. Have a nice stay!
After click on “Page 1” button, the value of //*[@id =”pageContent”] has changed to below content without reloading the element or web page.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam feugiat neque vel metus sodales auctor sed et arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus cursus tellus ac urna sollicitudin viverra.
If we use implicit wait in this case, the wait command will not trigger as the element //*[@id =”pageContent”] is present , and it will get an element text and executing the assert command, it is not the value that we are expecting after a click on Page 1 button (actual this is the value before that), it will lead to an incorrect value between expectation and the actual one.
As the above result, the implicit wait does not work in my case when the web element is visible on the web page, but the content inside has changed with Ajax technology, so let me move to the next waiting method with Explicit.
Explicit Wait
The explicit wait is used to wait for specific conditions or the maximum time exceeded before throwing an ElementNotVisibleException.
This is kind of an intelligent solution as it will wait for dynamically loaded Ajax elements with the wait conditions. However, it can be only applied for a specified element, and you need to do this for case by case. The more intelligent and optimized for timing in comparison with implicit wait has its own price with “unnecessary” code everywhere in your automation scripts.
There are two main ways to implement Explicit Waits : WebDriverWait and FluentWait.
In the above example, instead of using implicit wait , I will use the WebDriverWait with the condition as ExpectedConditions.textToBePresentInElementLocated
After clicking on Page 1, if there is no expected message displayed, the WebDriver will wait for the textToBePresentInElementLocated before moving to the next steps. In this case, the assert keyword will execute “after” the expected content has loaded, and the asserted result will Pass.
The following Expected Conditions can be used:
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvaliableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- presenceOfAllElementsLocatedBy()
- presenceOfElementLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleContains()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
Beside WebDriverWait , you can implement Explicit with FluentWait , both are classes and implements the Wait interface.
The fluent wait can be considered an advanced explicit wait as you can specify the polling interval and exceptions to ignore along with the maximum wait time. Moreover, you can also return the wanted elements in one line of code rather than one line for waiting and another for element retrieving as in explicit wait. Being that flexible and convenient, this type of wait that I have used the most. However, fluent wait still has the same problems as mentioned in explicit technique: the waiting code is everywhere. Even if you wrap those codes into some common functions or places, it’s still there waiting as a slowly exploded boom.
Time is gold and why I try to find an alternative solution
No one can deny the effectiveness of Wait for tackling the timing issue, but everyone has to suffer the poor efficiency of this solution as well. This is because of the overhead scripting and maintenance effort, the unpredictability and instability of the automation execution, which eventually cost me a lot of time to make every just fine.
I bet that as automation engineers, we all suffer the hard times to adjust the Wait limit to make everything work in the daytime at the office but then all the test cases fail during overnight execution. Automated testing turns out not to make testing faster and more reliable but even slower and not trustworthy. Many cases that I have seen that teams decide to go back to manual testing in order to achieve their deadlines rather than keep moving with automated testing.
Furthermore, a huge amount of effort for automation that I’ve spent is for building a framework to mitigate the scripting and maintenance effort for implementing the Wait approach. Even though it can be reused in most of my projects but it can never come to a “perfect” state that I imagine it should be. My team members still make mistakes, overuse Wait command as the silver bullet and at the end of the day we still have the spend overhead effort to fix the problem of another problem and can never totally focus on the automation business.
Feeling tired of sticking to the all mighty Wait solution. I feel that I should stop depend on that approach only and look out to other solution that I make my life better
Smart Wait — The radical solution to Selenium timing issue
After a long time struggling with the timing issue, I figured out that the right solution for that problem must satisfy two essential conditions. Firstly, that solution has to deal with the dynamic nature of web page loading. And secondly, the solution should not introduce any overhead effort.
Just recently, when I came across the Smart Wait function in Katalon Studio version 7 (www.katalon.com). This feature appears to match with the two conditions I mentioned above.
- Deal with dynamic web page loading directly : I see that the Smart Wait works with the Ajax loading content, I have tested the same test cases with the Smart Wait option and it looks good.
- Smart Wait internally captures all AJAX requests and DOM modifications. It would attempt to wait until all AJAX requests are completed so that all the submitted and requested information on the page are ready. Then every short period of time, Smart Wait would compare the previously captured DOM state against the current state to make sure that the displayed information on the page is not going through a mutation.
- No code : The Smart Wait will be enabled as a default setting without more scripting required, you can turn it ON or OFF by going to the Project menu > Settings > Execution and Enable / Disable the Default Smart Wait option.
One of the trade-offs when using any kind of wait is the increase in the execution time. This certainly applies to Smart Wait as well, although given the increased instability of the test and that stability is more important, it is a reasonable exchange. Another limitation is that Smart Wait does not specifically check for conditions such as invisibilityOfElement or textToBePresentInElement such as the case in Explicit Wait. This is by design because these conditions are better made explicit. If your website already has a monitoring library that also captures AJAX requests, then it may come into conflict with Smart Wait.
Although having certain limitations, this is a very promising approach because it alleviates some of the frequently observed problems with Selenium such as elements being acted on when they are not ready.
Conclusion
The Implicit method is fast and easy to implement. However, the execution time depends heavily on many external factors and not working correctly in the new technology with Ajax or JavaScript.
Explicit methods are more flexible and allow you to wait for specific conditions or the maximum time exceeded but it can be only applied for a specified element, you need to do this for case by case and require more code.
Smart Wait in Katalon Studio effectively solves the wait issue without coding required, it saves a great amount of time in the setup stage and works perfectly with Ajax or JavaScript pages. Despite having some limitations, I believe that the Smart Wait feature would be improved in the very next releases of Katalon Studio.
You can download Katalon Studio and try it out yourself.
If you know any other solutions to handle Selenium Wait Commands, please comment below. Thanks for reading!
Top comments (0)