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

Ran*_*ber 8 javascript ajax jquery watin

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

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

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

Ran*_*ber 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 );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的代码有一个问题 - 如果网站没有jQuery支持(如我的情况) - 你可能想先"注入"它.只需在"监视脚本"之前添加此代码即可.const string jquerry = @"var element1 = document.createElement('script'); element1.src ='http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js'; element1.type = '文本/ JavaScript的'; document.getElementsByTagName( '头')[0] .appendChild(元素1);"; browser.Eval(jquerry); (2认同)

Bap*_*net 6

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

$.ajax({url:"/"}); $.ajax({url:"/"})
Run Code Online (Sandbox Code Playgroud)

并在.ajaxStart.ajaxCompletehandler方法中添加一些日志记录,你可以看到.ajaxStart只有一次调用.ajaxComplete处理程序和处理程序两次.所以ajaxRequestCount会变得消极,所有的设计都被搞砸了.

如果你想保留你的设计,我建议你使用.ajaxSend而不是.ajaxStart.

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

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

希望这可以帮助.