How to Use WaitForAjax in Ocaramba for Reliable AJAX Synchronization
WaitForAjax is an IWebDriver extension method that pauses test execution until all jQuery AJAX requests finish by polling the jQuery.active counter, using a configurable timeout to prevent race conditions.
The WaitForAjax method in the accenture/ocaramba framework solves the synchronization challenges inherent in testing modern web applications that load data asynchronously. This utility blocks further test execution until the Document Object Model (DOM) reaches a stable state after AJAX operations, ensuring that subsequent element lookups or assertions do not fail due to timing issues. By leveraging JavaScript execution against the browser's jQuery instance, WaitForAjax provides a deterministic way to handle dynamic content loading without arbitrary Thread.Sleep calls.
WaitForAjax Implementation and Source Code
Core Logic in WebDriverExtensions.cs
The WaitForAjax extension method is implemented in OcarambaLite/Extensions/WebDriverExtensions.cs. It provides two overloads: a parameter-less version that uses the default medium timeout, and a version that accepts a custom timeout value in seconds.
The method creates a WebDriverWait instance that repeatedly executes the JavaScript expression return jQuery.active == 0 until it returns true or the timeout expires. When no AJAX requests are active, the counter equals zero and the wait condition is satisfied.
// https://github.com/accenture/ocaramba/blob/master/OcarambaLite/Extensions/WebDriverExtensions.cs#L71-L82
public static void WaitForAjax(this IWebDriver webDriver)
{
WaitForAjax(webDriver, BaseConfiguration.MediumTimeout);
}
public static void WaitForAjax(this IWebDriver webDriver, double timeout)
{
try
{
new WebDriverWait(webDriver, TimeSpan.FromSeconds(timeout)).Until(
driver =>
{
var javaScriptExecutor = driver as IJavaScriptExecutor;
return javaScriptExecutor != null
&& (bool)javaScriptExecutor.ExecuteScript("return jQuery.active == 0");
});
}
catch (InvalidOperationException)
{
Logger.Error(CultureInfo.CurrentCulture, "Invalid Operation Exception");
}
}
Timeout Configuration via BaseConfiguration.cs
The default timeout value originates from BaseConfiguration.MediumTimeout, defined in OcarambaLite/BaseConfiguration.cs. This property reads the mediumTimeout value from the appsettings.json configuration file and converts it to a double representing seconds.
// https://github.com/accenture/ocaramba/blob/master/OcarambaLite/BaseConfiguration.cs#L302-L313
public static double MediumTimeout
{
get
{
double setting = Convert.ToDouble(Builder["appSettings:mediumTimeout"], CultureInfo.InvariantCulture);
Logger.Trace(CultureInfo.CurrentCulture, "Gets the mediumTimeout from settings file '{0}'", setting);
return setting;
}
}
Practical Usage Patterns
Basic Usage with Default Timeout
Call WaitForAjax() immediately after any user action that triggers an asynchronous request. The method automatically applies the MediumTimeout value from your configuration file.
// After clicking a button that loads data via AJAX
this.Driver.GetElement(saveButton).Click();
this.Driver.WaitForAjax(); // Waits for BaseConfiguration.MediumTimeout seconds
Specifying Custom Timeouts
For operations known to take longer, pass an explicit timeout value or use predefined constants like BaseConfiguration.LongTimeout or BaseConfiguration.ShortTimeout.
// Wait up to 60 seconds for complex data operations
this.Driver.WaitForAjax(BaseConfiguration.LongTimeout);
Page Object Implementation Examples
The Ocaramba test suite demonstrates WaitForAjax integration in several page objects within the Ocaramba.Tests.PageObjects namespace.
SlowResourcesPage.cs This page object implements a custom timeout method for resources that load slowly (approximately 30 seconds).
// https://github.com/accenture/ocaramba/blob/master/Ocaramba.Tests.PageObjects/PageObjects/TheInternet/SlowResourcesPage.cs
public class SlowResourcesPage : ProjectPageBase
{
public SlowResourcesPage(DriverContext driverContext) : base(driverContext) { }
public void WaitForIt(int timeout)
{
this.Driver.WaitForAjax(timeout);
}
}
FormAuthenticationPage.cs
After injecting a password value via JavaScript, this page calls WaitForAjax to ensure background validation completes before proceeding.
// Located in FormAuthenticationPage.cs
public void EnterPassword(string password)
{
this.Driver.GetElement(passwordField).SendKeys(password);
this.Driver.WaitForAjax(); // Ensures validation AJAX completes
}
DynamicControlsPage.cs This example uses the long timeout constant for elements that require extended wait times.
// Located in DynamicControlsPage.cs
public void WaitForIt()
{
this.Driver.WaitForAjax(BaseConfiguration.LongTimeout);
}
Important Limitations and Framework Compatibility
jQuery Dependency
WaitForAjax functions exclusively on pages that load the jQuery library. The method relies on the global jQuery.active property, which tracks the number of active AJAX requests. If your application uses native fetch, XMLHttpRequest, or frameworks like Angular or React without jQuery, this method will not work.
Alternatives for Non-jQuery Applications
For applications not using jQuery, implement custom wait conditions or use other synchronization methods available in WebDriverExtensions.cs. The WaitForAngular method provides similar functionality for Angular applications, while custom implementations can poll window.fetch counters or specific DOM attributes indicating loading states.
Summary
- WaitForAjax is an extension method in
OcarambaLite/Extensions/WebDriverExtensions.csthat synchronizes tests with jQuery AJAX operations. - The method polls
jQuery.active == 0via JavaScript execution until the condition is met or a timeout occurs. - Default timeouts are configured in
BaseConfiguration.MediumTimeoutand sourced fromappsettings.json. - Use
this.Driver.WaitForAjax()for default timeouts or pass a custom double value for specific timing requirements. - This method requires jQuery; it cannot synchronize with native
fetchorXMLHttpRequestcalls in non-jQuery applications.
Frequently Asked Questions
What does the WaitForAjax method do in Ocaramba?
WaitForAjax blocks test execution until all active jQuery AJAX requests on the current page have completed. It executes return jQuery.active == 0 in the browser context repeatedly until the condition returns true, indicating no pending asynchronous operations remain.
Where is the WaitForAjax extension method defined?
The method is defined in OcarambaLite/Extensions/WebDriverExtensions.cs within the accenture/ocaramba repository. It extends the IWebDriver interface, making it available on any driver instance throughout your test project.
How do I change the default timeout for WaitForAjax?
Modify the mediumTimeout value in your appsettings.json file, which BaseConfiguration.MediumTimeout reads at runtime. Alternatively, call the overload WaitForAjax(double timeout) and pass a specific value such as BaseConfiguration.LongTimeout or a literal number of seconds.
Does WaitForAjax work with React or Angular applications?
No. WaitForAjax requires the jQuery library because it depends on the jQuery.active counter. For Angular applications, use the WaitForAngular method from the same extensions class. For React or other modern frameworks using native fetch or XMLHttpRequest, you must implement a custom wait condition that checks application-specific loading indicators.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →