Following Lance Ivy's excellent post (http://codelevy.com/articles/2007/11/05/selenium-and-ajax-requests), here's an easy way to write Selenium tests for Ajax requests when you're not using Prototype directly, but using Ajax4JSF or RichFaces.


Add this to your user-extensions.js:


/
Registers with the a4j library to record when an Ajax request
finishes.

Call this after the most recent page load but before any Ajax requests.

Once you've called this for a page, you should call waitForA4jRequest at
every opportunity, to make sure the A4jRequestFinished flag is consumed.
/
Selenium.prototype.doWatchA4jRequests = function() {
var testWindow = selenium.browserbot.getCurrentWindow();
// workaround for Selenium IDE 1b2 bug, see
// http://clearspace.openqa.org/message/46135
if (testWindow.wrappedJSObject) {
testWindow = testWindow.wrappedJSObject;
}
testWindow.A4J.AJAX.AddListener({
onafterajax: function() {Selenium.A4jRequestFinished = true}
});
}

/

If you've set up with watchA4jRequests, this routine will wait until
an Ajax request has finished and then return.
*/
Selenium.prototype.doWaitForA4jRequest = function(timeout) {
return Selenium.decorateFunctionWithTimeout(function() {
if (Selenium.A4jRequestFinished) {
Selenium.A4jRequestFinished = false;
return true;
}
return false;
}, timeout);
}

Selenium.A4jRequestFinished = false;

Instead of using pauses or waitForCondition (writing some esoteric javascript test to detect that the Ajax call ended), you can then write something as simple as:


<tr>
<td>watchA4jRequests</td>
<td></td>
<td></td>
</tr>

... (command triggering the ajax call) ...

<tr>
<td>waitForA4jRequest</td>
<td>10000</td>
<td></td>
</tr>
</pre>


For Selenium beginners, the Javascript code has to be placed in a file named user-extensions.js and passed as an attribute to the Selenium Server command line option "-user-extensions <file>". When using Selenium IDE, it can be set in the options menu (don't forget to close the IDE and restart it for this to be taken into account).