16

I use Selenium 2 in C# to automate testing of our web sites. When building non-Ajax functionality, using webDriver.FindElement(By.Id("element-id")) to find elements on a page works fine, but when doing jQuery Ajax calls this doesn't work because it tries to find the element before the ajax request has finished.

How do I tell Selenium to wait until the jQuery Ajax has completed?

1
  • I'm finding issues with this that the Wait's are not working for on one particular page I am testing. Did you ever get a working solution for this? I have made multiple waits and field checks on the page but nothing has worked yet.
    – MichaelF
    Commented Sep 23, 2011 at 15:39

5 Answers 5

13

The class you are looking for is the WebDriverWait class that you can find here (C#): http://code.google.com/p/selenium/source/browse/trunk/dotnet/src/WebDriver.Support/UI/WebDriverWait.cs

I created an extension method to make it easier to use that looks something like this:

public static class BrowserExtensions
{
    public static T WaitUntil<T>(this IWebDriver browser, Func<IWebDriver, T> condition, int timeout = 5)
    {
        var wait = new WebDriverWait(browser, new TimeSpan(0, 0, timeout));
        return wait.Until(condition);
    }
}

You can then use it like this:

var element = webDriver.WaitUntil(x => x.FindElement(By.Id("element-id")));

Note that this does not guarantee that the element is visible when you get it back!

Also I should probably mention that I have experienced problems using the WebDriverWait class and I think it could use some work to make it more stable.

3
  • I use WebDriverWait extensively and don't recall any stability issues. In Selenium2 beta2, there were definitely issues with sendKeys, so I used WebDriverWait to prevent the script from changing focus until the field contents match the sendKeys text. Using beta3, I haven't encountered any more stability problems with FirefoxDriver or InternetExplorerDriver.
    – John
    Commented May 7, 2011 at 3:37
  • The WebDriverWait class is pretty bare-bones. That said, it would be interesting to know (in another, more appropriate forum) what you're finding about it that's "unstable".
    – JimEvans
    Commented May 19, 2011 at 19:24
  • I do use wait with success most of the time, but I do find the timings on some JQuery pages is not quite right and I either end up with errors on the field I am trying to capture as its caught but then not there. Either I end up with Element is not displayed or Element is no longer valid. JQuery definitely takes work with Web Driver to get things just right.
    – MichaelF
    Commented Sep 23, 2011 at 15:41
9

A possibly more generic solution to this problem is to wait for the jquery to complete. You can do this with a function like this:

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);
    }
}

2
  • This is awesome. I'm ripping all the Thread.Sleep() out of the tests for my AJAX-heavy web application under test now, and this seems to be working.
    – Aaron
    Commented Nov 1, 2013 at 21:29
  • Thanks! I wrote up an equivalent in python: (mind the whitespace removal) class jquery_to_complete(object): def __init__(self): pass def __call__(self, driver): isjQueryComplete = driver.execute_script("return jQuery.active == 0") return isjQueryComplete Commented Feb 22, 2018 at 20:37
1

Fairly ceertain that there is a Wait class that you can access. From the docs:

public abstract class Wait extends java.lang.Object

A utility class, designed to help the user automatically wait until a condition turns true. Use it like this:

new Wait("Couldn't find close button!") { boolean until() { return selenium.isElementPresent("button_Close"); } };

1

I actually wrote my own wait_for_element method on the page objects for my selenium tests. You will need:

  • Success check function
    return element.isVisible()
  • A function to define what you are getting
    webDriver.FindElement(By.Id("element-id"))
  • Length of time prepared to wait and how often to check

This was all written before the Wait class was added to selenium 2/webdriver. I have not yet had a chance to use the Wait class, does anyone know if it is any good? I noticed one answer said selenium2 might need to work on it a bit

0

A similar question was asked on Stack Overflow with an excellent answer if you can consider using he PageObject model.

Using PageFactory to init elements on AJAX pages

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.