Wait for an Ajax call to complete with Selenium 2 WebDriver

C#AjaxSeleniumSelenium Webdriver

C# Problem Overview


I'm using Selenium 2 WebDriver to test an UI which uses AJAX.

Is there a way to make the driver to wait for a bit that the Ajax request will complete.

Basically I have this :

d.FindElement(By.XPath("//div[8]/div[3]/div/button")).Click();
// This click trigger an ajax request which will fill the below ID with content.
// So I need to make it wait for a bit.
            
Assert.IsNotEmpty(d.FindElement(By.Id("Hobbies")).Text);

C# Solutions


Solution 1 - C#

If you're using jQuery for your ajax requests, you can wait until the jQuery.active property is zero. Other libraries might have similar options.

public void WaitForAjax()
{
    while (true) // Handle timeout somewhere
    {
        var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
        if (ajaxIsComplete)
            break;
        Thread.Sleep(100);
    }
}

Solution 2 - C#

You could also use the Selenium explicit wait here. Then you don't need to handle timeout yourself

public void WaitForAjax()
{
    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
    wait.Until(d => (bool)(d as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"));
}

Solution 3 - C#

var wait = new WebDriverWait(d, TimeSpan.FromSeconds(5));
var element = wait.Until(driver => driver.FindElement(By.Id("Hobbies")));

Solution 4 - C#

Java solution based on Morten Christiansens answer

public void WaitForAjax() throws InterruptedException
{

    while (true)
    {
    	
    	Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
        if (ajaxIsComplete){
            break;
        }
        Thread.sleep(100);
    }
}

Solution 5 - C#

Just a little improvement by adding a timeout parameter:

internal static void WaitForAllAjaxCalls(this ISelenium selenium, IWebDriver driver, int timeout = 40)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        while (true)
        {
            if (sw.Elapsed.Seconds > timeout) throw new Exception("Timeout");
            var ajaxIsComplete = (bool)driver.ExecuteScript("return jQuery.active == 0");
            if (ajaxIsComplete)
                break;
            Thread.Sleep(100);
        }            
    }

Solution 6 - C#

Just small improvement:

//Wait for Ajax call to complete
  public void WaitForAjax1() throws InterruptedException
    {

        while (true)
        {
            if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
                break;
            }
            Thread.sleep(100);
        }
    }

Solution 7 - C#

Here is my code:

public static void WaitForCommission (WebDriver driver) throws Exception {
	for (int second = 0;; second++) {
		if (second >= 30) fail("timeout");
		try { 
			if (IsElementActive(By.id("transferPurposeDDL"), driver)) 
				break; 
			} catch (Exception e) {}
		Thread.sleep(1000);
	}
}

private static boolean IsElementActive(By id, WebDriver driver) {
	WebElement we =  driver.findElement(id);		
	if(we.isEnabled())
		return true;
	return false;
}

This code is really work.

Solution 8 - C#

If you are using Graphene you can use this:

Graphene.waitModel().until((Predicate<WebDriver>) input -> (Boolean) ((JavascriptExecutor) input).executeScript("return jQuery.active == 0"));

Solution 9 - C#

The “XML Http Request” is the protocol used to send Ajax requests to the server and so the presence of such a request indicates an Ajax based operation in progress.

There are a number of browser plugins that allow you to monitor XML Http Requests sent by the browser. I personally use the Firebug plugin for Firefox which is a very useful tool. Once installed Firebug displays a Bug-like icon at the bottom right corner of the browser window. Clicking on the bug-like icon launches Firebug as shown in the image above. Select the “Net” and then “XHR” to launch the XHR console where all XML HTTP Requests sent by the browser will be displayed.

Avoid using thread.sleep() as much as possible. Here is a piece of code that accepts wait time as input and runs a stop watch for the specified time.

You may set the input time in seconds to 30 to start with.

protected void WaitForAjaxToComplete(int timeoutSecs)
        {

            var stopWatch = new Stopwatch();

            try
            {
                while (stopWatch.Elapsed.TotalSeconds < timeoutSecs)
                {

                    var ajaxIsComplete = (bool)(WebDriver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
                    if (ajaxIsComplete)
                    {
                        break;
                    }

                }
            }
            //Exception Handling
            catch (Exception ex)
            {
                stopWatch.Stop();
                throw ex;
            }
            stopWatch.Stop();

        }

Solution 10 - C#

If you use Coypu you can Check if an element exists after an AJAX call and then you can click it:

private void WaitUntilExistsThenClick(string selectorId)
{
    var searchBoxExists = new State(() => browser.FindId(selectorId).Exists());
    if (browser.FindState(searchBoxExists) == searchBoxExists)
    {                
        browser.FindId(selectorId).Click();
    }
}       

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOmuView Question on Stackoverflow
Solution 1 - C#Morten ChristiansenView Answer on Stackoverflow
Solution 2 - C#MilaView Answer on Stackoverflow
Solution 3 - C#Hakan HastekinView Answer on Stackoverflow
Solution 4 - C#sherifView Answer on Stackoverflow
Solution 5 - C#Victor HugoView Answer on Stackoverflow
Solution 6 - C#Pavan TView Answer on Stackoverflow
Solution 7 - C#AntonView Answer on Stackoverflow
Solution 8 - C#Markus HeberlingView Answer on Stackoverflow
Solution 9 - C#Chethan S GView Answer on Stackoverflow
Solution 10 - C#OlegGuyView Answer on Stackoverflow