What is AJAX?
Ajax is a combination of different web development techniques which run in a user’s browser and exchange data with a webserver to update a webpage or parts of a webpage. As the name AJAX stands for Asynchronous JavaScript and XML, AJAX uses XMLHttpRequest calls to request data from a server and JavaScript to display the data. The purpose of using AJAX calls is to interact with the user. In other words, the user side establishes a connection and communicates with the server side of the application. This makes the applications interactive to the users. XML not only transfers data in XML format but JSON and data in plain text can also be transferred.
But when is the connection made?
Actions like clicking or moving the mouse can trigger a reaction. The XMLHttpRequest is sent to the server side of the application. The data is then fetched and transmitted to the user side of the application which, by using JavaScript, is displayed on the browser. This entire process is carried out asynchronously, which means that the part of the page is updated without loading the entire page during the process of data retrieval.
AJAX can be both synchronous and asynchronous. While asynchronous calls do not require you to reload the page to retrieve the data, synchronous calls require a page refresh which keeps the user waiting until the data is loaded, and a response is received from the web server.
Google’s search suggestion tool is one of the best examples of AJAX Calls. When you open https://www.google.com/ and start typing ‘hello’ you will see 10 other different words displayed below. AJAX calls get data for each letter you type in the search bar.
Why is it important to handle AJAX calls?
Automating AJAX pages can be difficult since we do not know the time it takes for the page to get updated. Estimating the exact time for the AJAX call to be completed is crucial since estimating less time might incur an error, and factoring in more time might be increasing the overall execution time of the test. This is why handling AJAX calls is vital.
Below are some of the solutions to handle AJAX calls:
1. Using sleep (ms)
sleep () is a traditional method that is being used in the test scripts. But using Thread.sleep () might not be a practical approach as we do not know the accurate time taken to complete the AJAX call. For instance, if Thread.sleep (5), then Selenium Webdriver waits 5 seconds for the element that you are trying to locate on the web page. If the time taken by the AJAX call is less than 5 seconds, then the script moves to the next step and if the time taken by the AJAX call is more than 5 seconds then the script would fail returning an error. Waiting for long time, i.e., 60 seconds might pass the test, but it increases the overall execution time of the test.
sleep (milliseconds)
2. Implicit Wait
Implicit Wait is applicable for the entire browser session, which implies we don’t have to declare the wait each time. Once the implicit wait is declared it does not need to be invoked again, and is active throughout through the end of the script. The default time in Selenium for implicit wait is ‘0’ seconds but it can be modified accordingly. Selenium Webdriver waits for the specified time if the element is not available immediately. Selenium Webdriver throws ‘NoSuchElementException’ if the element is not found during the specified time. The one drawback with Implicit Wait is that the overall execution time of the test will be increased since this wait is used throughout the browser session.
@driver.manage.timeouts.implicit_wait = 5
3. Explicit Wait
Selenium Webdriver tries to locate an element on a web page for a specified amount of time before retuning an error. Explicit Wait is used to locate only specific elements on the web page which are updated by AJAX calls. If Selenium Webdriver could not locate the elements in the time specified, then it returns ‘ElementNotVisibleException’. Unlike Implicit Wait, Explicit Wait is not applicable to the entire browser session. If the time specified for Explicit Wait is 30 seconds and the element is found in 5 seconds, then Selenium Webdriver continues to the next step without waiting for 30 seconds.
element = @driver.find_element(attribute: 'attribute_value’)
wait = Selenium::WebDriver::Wait.new(timeout: 30)
wait.until { element.displayed? }
4. Fluent Wait
In AJAX web applications there might be a few elements which could take different times to load at different instances. Using Explicit Wait every time to check such elements might be difficult. Fluent Wait can be used to check for the element at certain intervals of time until a maximum time. If the element is not found within the maximum specified time, it throws ‘ElementNotVisibleException’.
element = @driver.find_element(attribute: 'attribute_value’)
wait = Selenium::WebDriver::Wait.new(timeout: 30, interval: 5, message: 'Timed out after 30 sec', ignore: 'NoSuchElementException')
Fluent Wait takes 3 input parameters. First is the time with an integer data type, second is the time interval which also has an integer data type, and the third is to specify what to ignore, which in this case is an exception and a String data type. You can also add any relevant optional error prompt, such as ‘Timed out after 30 sec’ .
5. Custom Wait
Custom Wait (as the name suggests) is a custom wait time that can be built by creating a method and adding a loop to any of the above-mentioned waits as per the requirement.
def webdriver_wait (element)
element_present = false
retries ||= 0
while !element_present
wait = Selenium::WebDriver::Wait.new(timeout: 5)
element_present = wait.until { element.displayed? }
break if (retries += 1) > 5
end
return element_present
end