Ajax: The Most Wanted

Your test scripts are failing randomly every time they run? You see a lot of StaleElementReferenceExceptions in your console log? A lot of ElementNotFoundExceptions? A lot of pressure from your boss?

Well, most likely, Ajax is responsible for all of these.

What is Ajax
Its full name: Asynchronous JavaScript and XML. Sounds pretty academic, right(:=)? Well, in plain English, Ajax is just a new way for a web page to communicate with the server without having to reload the entire page.

Pre-AJAX, the traditional way of data retrieving from server will block users from interacting with the page till response is back and the whole page is re-painted. Remember this good old sign?

“Yo… I am still waiting for the server response…You can do nothing but just stare at me hohoho…”
Here is how data is retrieved from server traditionally:
Figure 2: Traditional Way

Traditional web applications transmit information to/from the server using synchronous requests. What does this mean? Let’s say that you fill out a form, hit submit, then a request is sent out to the server, and then you will have to wait, till browser gets the response & repaint the whole page.

While With AJAX, when you hit submit, JavaScript will make a request to the server, and wait for the response. But you as a user don’t have to wait for the response. You can continue using the web, and browser will update the section of screen automatically when it gets the server response. Thus the word ‘Asynchronous’, thus the word ‘non-blocking’. No more staring at ‘loading’ sign.

As a user you would never even notice anything, as if the whole data-retrieving is done in the background. Pretty neat, right?

The following chart explains how data is retrieved via Ajax:

Figure 1: AJAX

Comparing to the traditional way, Ajax:

  • is faster
  • refreshing page is non-blocking
  • only updates the section of page that needs to be updated.

Ajax enhances application responsiveness greatly, and have thus gained great popularity. Rarely any modern web application is not using AJAX.

Is my APP using AJAX?
Easy to find out: Go to your web site in Firefox, install firebug and open it when you play with the page, you can view all ajax calls like this: in firebug console, go to net –> xhr, all ajax calls are there:

Figure 3: View ajax in browser console

So Ajax is terrific! Why you are blaming it?
Ajax is all good for web, but means ‘headache’ for automation engineers, really.

Suppose that we have 2 drop-down fields on our web page: Country and City.

Figure 1: Dropdown populated via ajax call

When user chooses a country from first drop down, an ajax call will be triggered to fetch all the cities of the chosen country, and then the 2nd field will be updated with new city list.

User chooses an country
–> Ajax call is initiated
–> Browser is waiting for server’s response
–> browser gets response
–> browser begin to re-render city dropdown list
–> Page repainting is done, city dropdown is updated
–> Then user can choose a city

For automation, suppose that we have a test case like this:
1. Choose a country
2. Choose a city
3. Verify that some statistic info are shown for the chosen city.
Pseudo code would be like:

new Select(country).selectByIndex(1);
new Select(driver.findElement(By.name(“city”))).selectByIndex(1);
//THEN do verification here.

Would this code work? 1 out of 1000 times maybe. But most time you will get exceptions on step 2. Why? cos when the code execution reaches step 2, the browser might still wait for the server response to update city field, or maybe browser just starts to repainting the field but re-painting is not done yet. Alas, because of this ajax call, your code will never work.

if we tries to interact with those elements that are affected by ajax calls before the ajax call is complete and repainting is done, we will get StaleElementReferenceException:

Figure 3: Ajax Pitfall
Figure 3: Element becomes stale after ajax call is triggered

Is this clear?

Why Element Reference Gone ‘Stale’?
First of all, what is a WebElement? It is a reference to an element in the DOM.

When we first located this element, we got the element and stored a reference to it. But by the time we go interact with it, if an ajax call is triggered and the browser is refreshing the section of the page where your element is in, the reference becomes stale, and the bomb of StaleElementReferenceException is detonated.

So there is a tiny tiny hole between ‘find’ and ‘interact’, and if ajax call falls into this hole, and the DOM is updated in this small hole of execution, we are in trouble.

The faster the browser is, the faster DOM updating begins, the quicker the old elements become stale, and the more likely you will get StaleElementException. So, ajax + network speed + machine speed, will cause your cases fail at different places randomly. And this is why you see this exception happens much more frequently in Chrome, comparing with Firefox and IE. And this also makes Chrome the best choice to test-run your code.

How shall we handle ajax in automation? see my next blog

Leave a Reply

Your email address will not be published. Required fields are marked *