如何使用Selenium Webdriver检测Web服务何时完成

时间:2016-07-20 01:26:54

标签: ajax asp.net-mvc web-services selenium-webdriver

我尝试进行一些智能验证,以确定在通过Selenium WebDriver执行自动化时网页文档何时完成加载。

将IJavaScriptExecutor.ExecuteScript()与WebDriverWait()一起使用已被证明非常有用。

我首先等待文件告诉我它已加载:

.ExecuteScript("return document.readyState == 'complete'");

我接下来等待所有AJAX库(如jQuery和Dojo)告诉我他们处于非活动状态:

.ExecuteScript("return jQuery.active == '0'");
.ExecuteScript("return Ajax.activeRequestCount == '0'");
.ExecuteScript("return dojo.io.XMLHTTPTransport.inFlight.length == '0'");

此时我仍然注意到在ajax检查开始之前加载的东西,仍在运行(屏幕上的微调器用数据行填充表格等)。我跟踪了其中一个,并在下面放了一个粗略的调用堆栈。

除了等待元素存在之外还有什么方法可以智能地告诉这个(.asmx)Web服务何时完成?它来自ASP.NET应用程序,并通过生成的代理类调用Web方法。我还可以看到访问Sys.Net的客户端代码,如果这有助于或可以用于进行某些检测。

// Target Web Page

// called from a script tag at the ending body tag
$("#@fillArea").bind({
    "select_node.jstree": function (e, data) {
        setTimeout(function() {
            FillList();
        }, 1);

        return true;
    }
});

    // web service called by FillList()
    Abc.Api.MyService.Fill(listParams, onFillSuccess, onFailure, param);

        // web service code for Fill()
        [WebService(Namespace = "http://abc.alphabet.com/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1]
        [ScriptService]
        public class ListService
        {
            [WebMethod(EnableSession = true)]
            [ScriptMethod(UseHttpGet = true)]
            public string Fill(ListParams listParams)
            {
                // get database data
                // return html markup
            }
        }

已编辑:一个解决方案发现了如何检测Microsoft AJAX Library的AJAX流量

在document.ready =='完成'

之后,会立即插入以下代码来为其添加事件。
((IJavaScriptExecutor)driver).ExecuteScript
(
    @"MsftAjaxRequestCount = 0;

    Sys.Net.WebRequestManager.add_invokingRequest
    (
        function onInvoke(sender, args)
        {
            MsftAjaxRequestCount++;
        }
     );

    Sys.Net.WebRequestManager.add_completedRequest
    (
        function onComplete(sender, args)
        {
            MsftAjaxRequestCount--;
        }
    );"
);

以下代码检查是否插入了这个新变量的值以及另一个检查其他AJAX库的

.ExecuteScript("return MsftAjaxRequestCount == '0'");

这很有效。但是有一个轻微的竞争条件。有时,事件接线很晚,事件不会被触发,或者导致值变为-1。这是因为Selenium Webdriver的GotoUrl()在document.readyState完成之前不会返回。

GotoUrl()可以在完成之前异步返回以尽早连接事件吗?关于这个的任何其他想法?

1 个答案:

答案 0 :(得分:0)

OP回答了大部分OP问题。答案将根据AJAX库的使用情况而有所不同。

要以不同的速度(document.readyState ==加载或交互或完成)从GotoUrl()返回,可以使用Selenium页面加载策略。 "正常"当"完成","渴望"时返回当"互动"时返回和"无"马上回来。

使用C#的FireFox驱动程序的示例如下所示。

var profile = new FireFoxProfile();
profile.SetPreference("webdriver.load.strategy", "eager");

var driver = new FireFoxDriver(profile);