Test Synchronisation in Selenium | Selenium Automation
Most of the time test script will because of application takes to
load the web page due to this element will not be loaded to perform
the actions specified in the script. If two or more components are
working together in parallel at the same pace or
rate, synchronisation comes into play.
We see it in almost every application whenever the screen changes it
takes a few milliseconds (or seconds) to load, and if you do not
manage the proper synchronisation in your code then you might
face the dreaded “ElementNotVisibleException” or “NoSuchElementException” exceptions. This is because the screen hasn’t finished loading and
is not synchronised with your test code. That is, your test code
is over eager and starts trying to perform an action on an element
that hasn’t been loaded yet. To avoid this we need to implement
proper synchronisation in our automation script.
Broadly there are two types synchronisation:
1) Unconditional synchronisation,
2) Conditional synchronisation
Now let’s discuss each of them in detail.
1) Unconditional synchronisation:
Unconditional Synchronisation is also known as Static Synchronization or Static Wait.
As the name suggests, it specifies a particular fixed (static) time to
wait before starting the execution. Here WebDriver(or any program) will
wait the specified amount of time and then it will resume the execution.
During this wait, it will not perform any action, that is big drawback
of this unconditional synchronisation.
Sometimes you put this wait with 10 seconds to make sure
element get displayed, if element loaded and displayed within 2 seconds
also still it waits for 10 seconds. Due to this our automation script
execution may take longer.
The standard example of Unconditional Synchronisation is
below:
try{
Thread.sleep(5000);
} catch(InterruptedException e)
{
System.out.println( e);
}
Here the Thread.sleep(5000) function would take 5000
ms to execute.
Key to note is that this wait will be absolute, even if the
underlying condition you were waiting on has been met. For example,
you may put in a wait for 3 seconds waiting for the screen to load.
Even if that screen loads in 2 seconds, the system will still wait for
the additional second. The converse is also true - Sometimes the wait
finishes before the underlying operation and execution
proceeds.
In test automation, for example, limited network connectivity
may slow the mobile application response time and a screen change may
now take 5 seconds while the script only waits 3 seconds. Due to this,
we will face “ElementNotVisibleException” or
“NoSuchElementException” exceptions.
So unconditional synchronisation or static wait is not the
preferred way to deal with dynamic responses.
However it is a viable strategy to use it when you are working
with some 3rd party interfaces and where you can not identify the
underlying condition you need to wait on OR you are sure about the
response time.
2) Conditional synchronisation:
Conditional synchronization depends on some underlying condition. So in
addition to a specified absolute time to wait, the condition is also
passed into the method. Here the script(or program) will resume
execution as soon as the condition is met - or, in the event the
condition isn’t met, it will resume after the specified time.
Selenium provides 3 types of conditional synchronisation.
- Implicit wait
- Explicit wait
- Fluent wait
1) Implicit wait:
Implicit wait tells the webdriver object to poll the DOM for the
specified amount of time while trying to find the element before
throwing an “ElementNotVisibleException” or “NoSuchElementException”
exceptions.
The big advantage of using Implicit wait is it’s lifespan. As we
apply Implicit wait on the Webdriver object, it will be valid for
the webdriver object’s lifespan.
Below is the code to apply the Implicit wait of 10 seconds on the
Webdriver object.
<
//Define WebDriver
WebDriver driver = new ChromeDriver();
//Set implicit wait upon WeDriver
Driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
NOTE: Ideally you should set the implicit wait as soon as you initialise
the WebDriver.
Please remember that Implicit wait works with only driver.findElement()
and driver.findElements() methods - it won’t work for other
methods.
Let’s look at a simple example for better understanding.
You want to click on the Login button on the home screen but the home
screen itself takes some to appear when the Selenium script runs.
So ideally you need to specify a condition that Selenium should locate
the Login Button element(on the home screen) within 10 seconds after
starting the script and if the element is not present (or the home screen
has not appeared) after 10 seconds, only then throw Exceptions.
You can write the following statement after writing the above (webdriver
initialisation and set implicit wait of 10 sec.) code:
You will notice that we don’t need to specify anything else to the code
as we already added the 10 seconds implicit wait to the WebDriver object.
Now
it will be polling the DOM for 10 seconds until the Login Button is found
and as soon as the button is found, it will be clicked.
However there are a few limitations to using Implicit wait:
-
As you know it’s only useful for driver.findElement() and
driver.findElements() methods - we can’t check other
conditions. For example if you want to wait until a particular button is
displayed on the screen as well as on the DOM, you can’t check it with
Implicit wait. There is a chance that the particular button is in the DOM
but it’s hidden or it’s not visible on the screen, so in that case
Implicit wait executes successfully but would not give us the accurate
answer about the element’s visibility.
- There is a chance that the time for the implicit wait isn’t enough. For example as we mentioned earlier where we’re waiting 5 seconds but limited network connectivity causes the screen to take 10 seconds to load. In that case Implicit wait will break.
2) Explicit wait:
driver.findElement() & driver.findElements() - These
limitations are resolved by the Explicit wait.
Explicit waits are the best synchronisation methods for dynamic responses
in the application.
Explicit wait informs the WebDriver to wait
- Until the specified condition is met OR
- The specified time has elapsed
...before throwing the “ElementNotVisibleException” or
“NoSuchElementException” exceptions.
And if the WebDriver is able to meet the condition within the specified
amount of time then the code will get executed.
In explicit wait we need to tell the WebDriver object to wait for a
specific condition using the ExpectedConditions class. So, actually this
wait is specific to a particular single element rather than the whole
WebDriver object (unlike implicit wait).
The WebDriverWait class will call
the ExpectedCondition every 500 milliseconds by default
until the output is True. So if you have given 10 seconds of
timeout, ExpectedCondition would be called 20 times at
500 milliseconds intervals to check if the condition has been met.
Now let’s take one simple example to understand the use of Explicit
wait.
In almost all mobile applications when you perform a Login it takes
some time to load the dashboard or home screen and its elements. For
example purposes, let’s say there is a menu button on the dashboard
screen. You can use an Explicit wait with the condition of wait till
menu button element is visible:
(ExpectedCondtions.visibilityOf(<menu_button_element>)) on Dashboard screen.
When we initialise new object of WebDriverWait class, we need to pass 2
parameters:
- WebDriver object.
- Number of seconds
There are many conditions are defined in
ExpectedConditions class, but we can list down a few popular
one’s:
Condition Name
|
Purpose
|
elementToBeClickable(By locator)
Example:
ExpectedConditions.elementToBeCli
ckable(By.id(“loginButton”));
|
An expectation for checking an element is visible and enabled
such that you can click it.
In this method you need to pass the object of By class.
|
elementToBeClickable(WebElement element)
Example:
ExpectedConditions.elementToBeCli
ckable(driver.findElement(By.id("me nubutton")));
|
An expectation for checking an element is visible and enabled
such that you can click it. In this method you need
to pass the object of WebElement class.
|
presenceOfElementLocated(By locator)
|
An expectation for checking that an element is present on the
DOM of a page. This does not necessarily mean that the element
is visible.
|
visibilityOfElementLocated(By locator)
|
An expectation for checking that an element is either invisible
or not present on the DOM.
|
elementToBeSelected(WebElement element)
|
An expectation for checking if the given element is
selected.
|
numberOfElementsToBe(By locator, java.lang.Integer
number)
|
An expectation for checking number of WebElements with given
locator.
|
titleIs(java.lang.String title)
|
An expectation for checking the title of a page.
|
textToBePresentInElement(WebEle ment element, java.lang.String
text)
|
An expectation for checking if the given text is present in the
specified element.
|
|
|
3) Fluent wait:
Fluent wait is part of WebDriverWait, The only difference is it’s more
configurable than Explicit wait.
You can configure the:
1. 1) Pollfrequency : The is the Time Interval to check whether the expected condition for
the webelement is met or not. So if poll frequency is 1 second and total
wait time is 10 seconds, fluent will check if the condition is met or
not at every 1 second for a maximum of 10 times.
2. 2) IgnoretheException : If you want to ignore a specific exception such as NoSuchElementExceptions while searching for an element.
3. 3) Maximumwaittime : The total maximum amount of time to wait for a condition is met before
throwing an exception.
Below is the example of Fluent wait:
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(Duration.ofSeconds(1));
wait.ignoring(NoSuchElementException.class);
wait.withTimeout(Duration.ofSeconds(10));
Which types of Wait you should use When?
Wait Type
|
Purpose
|
Implicit
|
When you need to apply common wait without any condition.
|
Explicit
|
When you need to test expected condition for an element
|
Fluent
|
When you need to test expected condition for an element after a
specific amount of time every x seconds/minutes
|
No comments:
Post a Comment
If any suggestions or issue, please provide