Handling AJAX with automation frameworks
posted by Bryan on
In running functional automation testing, it has always been difficult to know whether the AJAX call has finished. Most people just put a Thread.Sleep() in the code, but it clutters up things and isn't accurate. To handle this appropriately, we found a way to watch for those JQuery AJAX calls and drive the automation accordingly.
First, I have only tested this with JQuery. I found articles talking about the .NET AjaxToolkit, but that didn't apply to me.
Second, we are using 2 different automation frameworks. WatiN and Webdriver/Selenium2. Both frameworks give us the ability to inject javascript on the page. This is vital to making this solution work.
Prior to a Click() event in your automation, you need to run a javascript command.
$(document).bind(\"ajaxStart\", function() {$(\"body\").append(\"<div id="ajaxhidden" style="display:none;"></div>\");}).bind(\"ajaxStop\", function() {$('#ajaxhidden').remove();});
This call will insert a hidden DIV on the page when the "ajaxStart" event is fired.
When the Click() is fired, if an AJAX call is initiated, this script will run, inserting that hidden div. The automation will then just check to see if the hidden DIV is present. As long as the DIV is on the page, it will wait until the AJAX call has finished. When done, it removes the hidden DIV.
Well, what if the click doesn't initiate an AJAX call. That's okay. 90% of the time, it causes a page refresh, thus wiping out the injected javascript. No harm, no foul.
There are some times where a Click() event occurs and is not related to either scenario, such as clicking a check box or radio button. We added some additional logic to not run the javascript multiple times if it was already there.
It is working fantastic! Very pleased.
After the Click() event is done, ajax or not, we unbind the event.
$(document).unbind(\"ajaxStart\").unbind(\"ajaxStop\");
For WatiN + IE, WebDriver + FF, this worked great. For WatiN + FF, we had to replace 2 strings. We changed "$" to "window.$". Also, "(document)", to "(doc)". For WebDriver + IE, I've had problems running it but those issues have been fixed in the Trunk. I'm still running the 2.0 Beta 1 version. As for WebDriver + Chrome, it still isn't working but I'm working on it.
Update to this... We have also found that if you just check the count of active queries through javascript using "return jQuery.active > 0", that seems to work fantastic. This was tested on WebDriver + Chrome, but it should work on any of those platforms.