检查DOM是否静止不动

时间:2014-02-13 09:16:30

标签: c# javascript jquery dom watin

有一个相当有趣的问题。我会提供一些背景知识,因为很多人可能会问为什么有人需要这样的东西。

背景信息

必须为大型复杂的.net Web表单应用程序进行单元(集成)测试。 目前使用visual studio 2010,nunit,watin 2.1,ie9。已经有一些相当复杂的单元测试,但它们很慢,不太可靠主要是因为时间问题。因此,必须将执行时间从许多小时缩短到更合理的时间并保持可靠性。

当前问题

我在等待异步请求完成时遇到一些问题。 (这需要从屏幕上获取更新页面以进行测试。)目前的情况如下:

//Function is called after making an async request to wait for DOM to be updated
    public static void WaitForAsyncPostBackToComplete(this Browser browser)
    {
        int waited = 0;
        bool isInPostback = true;
        while (isInPostback)
        {
            if (waited > AjaxWaitTime)
            {
                throw new Exception(string.Format(
                    "Looks like Ajax reqest timed out. Test waited {0} milliseconds.",
                    waited));
            }
            isInPostback = IsInPostback(browser);
            if (isInPostback)
            {
                // Request is not completed, wait a bit for next polling.
                Thread.Sleep(AjaxSleepTime);
                waited += AjaxSleepTime;
            }
        }
        // IMPORTANT: Wait for DOM to be actually updated???
        Thread.Sleep(300);
    }

    // Check if something is in postback now.
    private static bool IsInPostback(Browser browser)
    {
        string function =
            "(  typeof(Sys) === undefined " +
            "|| Sys == undefined || Sys == 'undefined' || Sys==null " +
            "|| typeof(Sys.WebForms) === undefined " +
            "|| Sys.WebForms==null || Sys.WebForms==undefined|| Sys.WebForms=='undefined'" +
            "|| typeof(Sys.WebForms.PageRequestManager) === undefined) " +
            "|| Sys.WebForms.PageRequestManager==null || Sys.WebForms.PageRequestManager==undefined|| Sys.WebForms.PageRequestManager=='undefined'" +
            "? true " +
            ": Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack();";

        string result = browser.EvalSafely(function);
        return Convert.ToBoolean(result);
    }

所以我经常汇集以检查是否使用IsInPostback()函数完成了ajax请求。这看起来非常快速可靠。

但是我认为IsInPostback()表示在实际插入DOM之前一切都已完成。这意味着我们得到了答案,但我们需要一些时间将其插入此处。因此,我需要那个丑陋的Thread.Sleep(300)行来等待DOM更新。我想通过某种方式确定何时更准确,更可靠地更新DOM来消除这条线。

真正的问题

有没有什么好方法可以确定在IE9中加载DOM并且异步疯狂正在进行?我一直在考虑简单地将整个DOM变为变量(如果DOM正在改变它甚至可以工作)并轮询以检查变量。如果没有像过去50ms那样进行任何更改,我可能会停止等待。有什么好方法可以做这样的事吗?

欢迎任何想法......

2 个答案:

答案 0 :(得分:1)

您可以从javascript设置'Ajax Requests Completed Flag'并在C#中进行检查 的 HTML:

<input type='hidden' id='hdnRequestCompletedFlag' value='0' />

<强>使用Javascript:

var NoOfCompletedRequests = 0;
var NoOfRequests = 10; // Your number of requests.
$.ajax({
    ...,
    success: function( data ) { // This function same for all the ajax requests.
        NoOfCompletedRequests++;
        if(NoOfCompletedRequests == NoOfRequests)
            $('#hdnRequestCompletedFlag').val('1');
    }
});

<强> C#:

private static bool IsInPostback(Browser browser)
{
    string function =
        "(  typeof(Sys) === undefined " +
        "|| Sys == undefined || Sys == 'undefined' || Sys==null " +
        "|| typeof(Sys.WebForms) === undefined " +
        "|| Sys.WebForms==null || Sys.WebForms==undefined|| Sys.WebForms=='undefined'" +
        "|| typeof(Sys.WebForms.PageRequestManager) === undefined) " +
        "|| Sys.WebForms.PageRequestManager==null || Sys.WebForms.PageRequestManager==undefined|| Sys.WebForms.PageRequestManager=='undefined'" +
        "? true " +
        ": Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack();";

    string result = browser.EvalSafely(function);
    return Convert.ToBoolean(result) && (hdnRequestCompletedFlag.Value == '1');
}

答案 1 :(得分:0)

这个问题已经很老了,但它仍然有一些观点,所以我想考虑在这个问题上添加一些事情。

在阅读了一些文档(对于这种特定情况不是很详细)并做了一些实验后,我得出结论Sys.WebForms.PageRequestManager.getInstance()。get_isInAsyncPostBack();只有在DOM更新完成后,方法才会退出(返回true)。

然而事实证明,使用这种高精度的方法非常困难,因为在ASP.NET Web Forms中我们并没有完全控制生成的JS。因此,如果由于嵌套更新面板而在一次用户操作后有多个请求,或者存在一些延迟更新或执行JavaScript时出现一些不一致,则这种方法不是100%稳定。

最后可能有两种可能的部分解决方案:

  1. 接受这种方法在100%的情况下不能准确地工作并处理更高的抽象级别。
  2. 在此函数之上添加其他图层(为了更好地处理连续多个AJAX请求或延迟请求)并将其与较小的等待时间相结合。
  3. 无论哪种方式,似乎没有明确的答案在100%的案例中都有效,而且线程中没有明确的等待。

    这个问题非常具体,可能无法获得将来可以接受的任何答案,但我认为它包含了一些有趣的观点,因此我将在这里留下问题并接受这些问题。