Outline

Synchronization is one of the most critical issue while we are doing test automation. Synchronization problems generally lead to non-reliable, intermittent, slow and non-stable tests. Thus, we have to do proper synchronization to make our tests fast, robust, and reliable. When we automate a web page, we should not wait too much and should not wait on the wrong point. In this post, I will try to explain Selenium Webdriver’s wait methods and how to work with expected conditions to synchronize your tests properly.

Audience

This post is designed for SW test professionals who have some information about selenium web automation. At the end of this tutorial, you will know how to synchronize your tests correctly.

Prerequisites

Nice to have: Before starting to read this post it is better to read previous selenium tutorials.

Working with WebDriverWait and ExpectedConditions

If we need some synchronization points, we should use Selenium WebDriverWait methods. These methods help us to control our tests. We can wait at any specific point until an expected condition occurs. When that expected condition occurred, our test script goes on running from that point.

Before doing an example, it is better to talk about AJAX pages. AJAX expansion is Asynchronous JavaScript and AJAX allows the web page to retrieve small amounts of data from the server without refreshing the entire page and retrieving that data takes time. Thus, at that point, our test code should also wait. As I told you above, with Selenium WebdriverWait and ExpectedCondition methods, we can wait at any point and then continue the test execution when the element is found/visible. There are many wait.until(ExpectedConditions.anyCondition) methods, but I want to explain the most common ones below.

WebDriverWait Syntax

■ presenceOfElementLocated(locator):

It checks the element presence on the DOM of a page. This does not necessarily mean that the element is visible.

■ visibilityOfElementLocated(locator):

 It is for the element present in the DOM of a page is visible.

■ invisibilityOfElementLocated(locator):

It is for the element present in the DOM of a page is invisible.

■ elementToBeClickable(locator):

It is for the element to be clickable.

 Note: All Expected Conditions are listed on below page.

https://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

► Now, it is time to do an example.

Test site: http://demos.telerik.com/aspnet-ajax/ajaxloadingpanel/functionality/explicit-show-hide/defaultcs.aspx

I want to explain web page and date form functionality. When you select a date, then a loader will occur immediately and after a period of time selected date will be seen on Selected Dates pane. When you deselect the selected date, again a loader will occur and after a period of time selected date will be wiped away from the Selected Dates pane.

synchronization

synchronization

Test Scenario without Synchronization

  1. Go to above URL.
  2. Maximize the window.
  3. Get the selected date text before selecting date. (Before AJAX call)
  4. Print selected date text to the console. (Before AJAX call)
  5. Click 3rd January.
  6. Get the selected date. (After AJAX callThis will be the failing point)
  7. Print selected date text to the console. (After AJAX call)
  8. Check the expected text and actual text.

Selected Text Area CSS Path: #ctl00_ContentPlaceholder1_Label1

3rd January Xpath: .//*

[contains(@class, ‘rcWeekend’)]/a[.=’3′]

Test Code(it will fail):

Console Output:

synchronization

Test Scenario with Synchronization

  1. Go to above URL.
  2. Maximize the window
  3. Declare WebDriverWait for 10 seconds.
  4. Wait until presence of date form container in DOM. (Synchronization Point)
  5. Get the selected date text before selecting date. (Before AJAX call)
  6. Print selected date text to the console. (Before AJAX call)
  7. Click 3rd January.
  8. Wait until invisibility of loader. (Synchronization Point)
  9. Wait until visibility of selected date text. (Synchronization Point – This is not necessary but I added this to show visibilityOfElementLocated)
  10. Get the selected date. (After AJAX call – This time it will not fail. J )
  11. Print selected date text to the console. (After AJAX call)
  12. Check the expected text and actual text.

Date Container CSS Path: .demo-container.size-narrow

Loader CSS Path: .raDiv

Selected Text Area CSS Path: #ctl00_ContentPlaceholder1_Label1

3rd January Xpath: .//*[contains(@class, ‘rcWeekend’)]/a[.=’3′]

Test Code (it will pass):

Console Output:

synchronization

Custom ExpectedConditions

Sometimes we need, or we want to use expected conditions rather than built-in expected conditions. These custom expected conditions can make our tests more readable, tidy, and short.

I want to show a sample custom ExpectedCondition class below. It checks “Does an element contain given text until defined WebdriverWait time?”

Method-1: Custom ExpectedCondition by Using Named Class

In above class (named class) you can see that I did below stuff:
–    Implemented ExpectedContion<Boolean> interface.
–    Set FindBy and testToFind values in constructor.
–    Override the apply method to implement “Does the given element contains the given text?” functionality. (We should put our logic in here.)
–    Override the String method because when the test fails, I want to see a more meaningful message. It is shown below.

synchronization

Example: Let’s do the same example that I showed and coded “Working with WebDriverWait and ExpectedConditions” section but now we will use our custom “ElementContainsText” class.

Test website is: http://demos.telerik.com/aspnet-ajax/ajaxloadingpanel/functionality/explicit-show-hide/defaultcs.aspx

Selected Text Area CSS Path: #ctl00_ContentPlaceholder1_Label1

3rd January Xpath: .//*[contains(@class, ‘rcWeekend’)]/a[.=’3′]

Test Scenario with Custom ExpectedCondition by Using Named Class:

  1. Go to above URL.
  2. Maximize the window
  3. Declare WebDriverWait for 10 seconds.
  4. Wait until presence of date form container in DOM. (Synchronization)
  5. Get the selected date text before selecting date. (Before AJAX call)
  6. Print selected date text to the console. (Before AJAX call)
  7. Click 3rd January.
  8. (-) Removed: Wait until invisibility of loader. (We will not use built-in ExpectedCondition)
  9. (+) Added: Use custom named ExpectedCondition (Synchronization)
  10. Get the selected date. (After AJAX call)
  11. Print selected date text to the console. (After AJAX call)
  12. Check the expected text and actual text.
Method-2: Custom ExpectedCondition by Using Anonymous Class

Sometimes you may want to synchronize your test with Adhoc(Inline) ExpectedCondition. This can be done with anonymous class. If you do synchronization in this way, you can still override the apply method, but you cannot use constructor. The anonymous class is located in until () block, and we can write our synchronization logic in apply method.

Example: Now, let’s do the same example that is shown below sections by using an anonymous class. Test scenario, URL, and CSS, XPath paths of the elements are same.

Test Scenario with Custom ExpectedCondition by Using Anonymous Class:

  1. Go to test URL.
  2. Maximize the window
  3. Declare WebDriverWait for 10 seconds.
  4. Wait until presence of date form container in DOM. (Synchronization)
  5. Get the selected date text before selecting date. (Before AJAX call)
  6. Print selected date text to the console. (Before AJAX call)
  7. Click 3rd January.
  8. (-) Removed: Wait until invisibility of loader. (We will not use built-in ExpectedCondition!)
  9. (-) Removed: Use custom named ExpectedCondition class. (We will not use!)
  10. (+) Added: Use custom anonymous ExpectedCondition
  11. Get the selected date. (After AJAX call)
  12. Print selected date text to the console. (After AJAX call)
  13. Check the expected text and actual text.
Method-3: Custom ExpectedCondition by Wrapping Anonymous Class in a Method

Actually, using an anonymous class for synchronization is a kind of hard-coded coding style and it is not so flexible. However, when you encapsulate an anonymous class in a method, your synchronization code will be more flexible and reusable. The sample code is shown below.

Implementation:

Extra Note: Below code is lambda expression of above method. It works only on JAVA 8 JVM installed machines.

How to call wrapped anonymous class:

Example: Same example is done with wrapped anonymous class below. (I do not want to write the SAME scenario again. It is as same as former ones.)

What is Fluent Wait?

FluentWait defines the maximum amount of time to wait for a condition and specifies an interval period to check that status. Also, you can configure the FluentWait to ignore specific types of exceptions such as NoSuchElementExceptions when trying to locate an element on the page. WebdriverWait is developed on top of FluentWait. Thus, with FluentWait we can declare a wait with additional functionalities. FluentWait methods and their meanings are listed below:

Note: Also you can use WebDriverWait with fluently. I want to show a sample syntax below.

The difference between WebDriverWait and FluentWait is,

  • FluentWait can apply ANYTHING (WebElement, String, etc.) and returns anything.
  • WebdriverWait can apply ONLY Webdriver and returns anything

Example: The Same example is written with FluentWait. I found an element with FluentWait, and I also check an ExpectedCondition with FluentWait. You can find the details on comments. (I do not want to write the same scenario again. It is as same as former ones.)

I also suggest some nice references on FluentWait below.

Implicit Wait vs Explicit Wait

“Explicit waits” are simply WebdriverWait and FluentWait with expected conditions. We can define a wait with extra functionalities for a specific condition. Generally, we use built-in ExpectedConditions or our custom ExpectedCondition for elements to become visible, clickable, invisible, etc.

“Implicit wait” is the wait that it waits for a given time period before findelement or findelements methods cannot find the web element on the page and throw an element not found exception. During the implicit wait period, if the element is not available and WebDriver cannot find it, then WebDriver will wait for defined implicit wait time to find that element once again the last time before throwing ElementNotFound exception. Its syntax is shown below.

We defined a wait with 30 seconds timeout period. When we do not designate the timeout period with implicit wait, the default timeout will always be  0. In other words, “Default implicit wait is zero”. This make us to think on our synchronization and make it very explicit, robust and maintainable.

Implicit Wait

Explicit Wait

It is easier to write tests faster with less code but it is RISKY! It needs extra codes (logic) for synchronization and it is more ROBUST!
Default timeout period is 0. You can set timeout with FluentWait or WebDriver Wait and it will wait until ExpectedCondition will meet.
You don’t need to think about ExpectedConditions, you just set timeout period for synchronization. You need to think about certain ExpectedConditions to ensure synchronization.
It is hard to fix synchronization problems later. Your only option is to alter implicit timeout period. You can fix your synchronization problems by changing your ExpectedCondition and timeouts.
If the implicit wait time is too long, sometimes it takes too much time to get feedback when your test has not worked. If you use long implicit wait time, it will wait for the same time for every element. Explicit Wait waits until the ExpectedCondition is going to occur.


Note:
Some web pages are displayed with javascript, the elements of that page already present in the browser DOM, but are not visible. Implicit wait only waits for an element to appear in the DOM, so it returns immediately and at that time, if that element is not visible and if you try to interact with it, you will get NoSuchElementException. You can test any element is visible or clickable with below methods.

Implicit Wait Example

Test site: http://the-internet.herokuapp.com/dynamic_loading/2

Start Button CSS Path: #start>button

Result Text CSS Path: #finish>h4

Test Scenario with Custom ExpectedCondition by Using Named Class:

  1. Go to above URL.
  2. Maximize the window
  3. Define an implicit wait (If you declare a timeout such as 2 seconds, test will fail.)
  4. Find start button.
  5. Click the start button.
  6. Wait result text will appear and find it.
  7. Check result text is “Hello World!”

Test Code:

Synchronization Suggestions

  • Wrap custom wait in a method.
  • If you want to see meaningful messages when your custom wait fails, override toString method to implement more meaningful synchronization error messages.
  • If you use same WebDriver and WebDriverWait then create a wait variable and use it all the test script. Do not repeat to use “new WebDriverWait”. Make your test code more readable.
  • Before interacting any element, please wait it. 😉
  • Try to use explicit wait more rather than implicit wait. It is more robust and less risky.
  • “Right synchronization” makes your test robust and durable! Please pay attention on synchronization while you are coding your automation scripts.