如何等待从WatiN完成jQuery Ajax请求?

时间:2010-03-03 23:07:44

标签: javascript jquery ajax watin

我正在编写WatiN测试以测试Ajax Web应用程序,并遇到了Ajax请求的计时问题。

在页面上的操作触发Ajax请求后,我希望WatiN等到请求完成后再验证页面是否正确更新。

我觉得该解决方案将涉及评估JavaScript以注册$.ajaxStart$.ajaxComplete的处理程序,以跟踪请求是否正在进行中。我很快就会深入研究,但想知道其他人是否已经解决了这个问题。看起来它似乎是Ajax测试的常见问题。

3 个答案:

答案 0 :(得分:18)

我已经创建了一些WatiN Browser扩展方法来解决这个问题,但我仍然对其他解决方案感兴趣。

InjectAjaxMonitor方法创建一个javascript全局变量,该变量附加到ajaxStart和ajaxComplete事件以跟踪正在进行的请求的数量。

每当您需要等待AJAX​​请求完成后才能继续,您可以拨打browserInstance.WaitForAjaxRequest();


public static class BrowserExtensions
{
    public static void WaitForAjaxRequest( this Browser browser )
    {
        int timeWaitedInMilliseconds = 0;
        var maxWaitTimeInMilliseconds = Settings.WaitForCompleteTimeOut*1000;

        while ( browser.IsAjaxRequestInProgress()
                && timeWaitedInMilliseconds < maxWaitTimeInMilliseconds )
        {
            Thread.Sleep( Settings.SleepTime );
            timeWaitedInMilliseconds += Settings.SleepTime;
        }
    }

    public static bool IsAjaxRequestInProgress( this Browser browser )
    {
        var evalResult = browser.Eval( "watinAjaxMonitor.isRequestInProgress()" );
        return evalResult == "true";
    }

    public static void InjectAjaxMonitor( this Browser browser )
    {
        const string monitorScript =
            @"function AjaxMonitor(){"
            + "var ajaxRequestCount = 0;"

            + "$(document).ajaxSend(function(){"
            + "    ajaxRequestCount++;"
            + "});"

            + "$(document).ajaxComplete(function(){"
            + "    ajaxRequestCount--;"
            + "});"

            + "this.isRequestInProgress = function(){"
            + "    return (ajaxRequestCount > 0);"
            + "};"
            + "}"

            + "var watinAjaxMonitor = new AjaxMonitor();";

        browser.Eval( monitorScript );
    }
}

答案 1 :(得分:6)

此解决方案不能很好地工作,因为.ajaxStart仅针对第一个Ajax请求被调用,而每次ajax请求完成时都会调用.ajaxComplete。如果你在控制台中运行这个简单的代码:

$.ajax({url:"/"}); $.ajax({url:"/"})

并在.ajaxStart.ajaxComplete处理程序方法中添加一些日志记录,您可以看到.ajaxStart处理程序只会被调用一次而.ajaxComplete处理程序将被调用两次。因此,ajaxRequestCount将变为负面,并且所有设计都被搞砸了。

如果您想保留设计,我建议您使用.ajaxSend代替.ajaxStart

另一个解决方案是使用.ajaxStop而不是.ajaxComplete,但这样做,你不需要ajaxRequestCount,你只需要一个布尔值来说明是否有ajax请求在场景后面运行。

可以找到非常有用的信息:http://api.jquery.com/category/ajax/global-ajax-event-handlers/

希望这有帮助。

答案 2 :(得分:3)

我在使用WatiN进行一些测试时遇到了这个问题。我发现在version 1.1.0.4000 of WatiN(2007年5月2日发布(2009年12月20日最新版本为2.0 RC2))中,声称在测试中添加了更好的处理Ajax的支持:

  

更好地支持AJAX测试   启用网站,此版本补充说   您工具箱的其他选项。

     

添加了一个等待的新方法   直到一些属性有一定的   值。这可能很方便   你需要等待的情况   直到元素的值得到   更新。

示例:

// Wait until some textfield is enabled
textfield.WaitUntil("disable", false.ToSting, 10);
// Wait until some textfield is visible and enabled
textfield.WaitUntil(new Attribute("visibile", new BoolComparer(true)) && new Attribute("disabled", new BoolComparer(false)));

有关详细信息,请参阅link to the release notes

我还没有详细研究过,所以我不知道它在哪些情况下可能有用。但是,如果有人遇到这个问题,可能值得一提。