Properly synchronizing your code with the state of the browser has long been the biggest issue testers face when testing a dynamic website.
It is often discussed that hard coding
#sleep is a bad practice.
Besides being an indication that your test suite doesn’t have sufficient maturity, there are specific technical
frustrations that come with hard coding sleeps. The biggest issue is that you are having to balance the concern
of how long is long enough with having an additional and typically unnecessary set of 30 second sleeps
scattered everywhere throughout your code.
Selenium Waits - Implicit & Explicit
Selenium has two approaches to synchronization. The first is “implicit wait.” Presumably this feature was inspired by the early versions of Watir which did a better job of automatically waiting for elements. Using implicit waits means telling the driver to apply a global value for how long to wait when attempting to locate an element if it can’t find the element. The idea behind implicit waits is good, but there are two main issues with this form of implementation, so Watir does not recommend and does not provide direct access for setting them.
- The wait happens during the locate instead of when trying to act on the element. This makes it impossible to immediately query the state of an element before it is there.
- Implicit waits by themselves will not be sufficient to handle all of the synchronization issues in your code. The combination of delegating waiting responsibilities to the driver and leveraging polling in the code (explicit waits) can cause weirdness that is difficult to debug.
The second and recommended approach to waiting in Selenium is to use explicit waits. This retains responsibility for synchronization with your code. In this approach your code will continuously check to see if the supplied condition is met, and continue with the next piece of the code when so. Watir waiting approaches all leverage this idea of polling for the desired output from a supplied condition
When Present and When Enabled
Prior to Watir 6.0, the best way to ensure that the code waited for the browser to be ready was to insert a
#when_enabled method before the action.
The problem here is that you should never be using
#set if you aren’t sure the element will be there or
enabled, so these
#when_present calls are philosophically redundant.
As such, Watir 6.0 deprecated
#when_enabled and every action call on an element
effectively executes this logic by default.
Note that Watir does its automatic waiting when taking actions, not when attempting to locate. This provides additional flexibility for querying the state of an element without needing unnecessary waits.
Watir Wait and Waitable Modules
Waitable is the module that is included by
This module provides access to two main methods:
#wait_while. As of Watir 6, both of these methods
:message keyword parameters. Note that the
:interval keyword was added in Watir 6.1 to
allow reducing how often the condition is polled, and as of Watir 6.12 you can use a
Proc instance value for
:message if that is preferred to a
String). Then as always, a block is passed in to establish what
condition needs to be met.
#wait_until will execute the block until a truthy result is returned, and
#wait_while will execute the block until a falsy result is returned.
Note that it is encouraged to use
#to_proc syntax when possible:
The default timeout for Watir’s Waits is 30 seconds. You can pass in the
:timeout keyword parameter to
any of the wait methods, or you can change the global default with:
Wait Until Present and Wait While Present
As of 6.15
#wait_until_present are deprecated. For versions 6.2 through 6.14
these methods had subtly different behavior from
This is no longer the case and these methods should no longer be used.