我在寫WatiN測試以測試Ajax Web應用程序,並且遇到了Ajax請求的時間問題。如何等待從WatiN完成的jQuery Ajax請求?
在頁面上的操作觸發Ajax請求之後,我想WatiN等待請求完成,然後驗證頁面是否已正確更新。
我有一種感覺,該解決方案將涉及評估JavaScript註冊處理程序爲$.ajaxStart
和$.ajaxComplete
來跟蹤請求是否正在進行。我很快就會深究,但是想看看其他人是否已經解決了這個問題。似乎這將是Ajax測試的常見問題。
我在寫WatiN測試以測試Ajax Web應用程序,並且遇到了Ajax請求的時間問題。如何等待從WatiN完成的jQuery Ajax請求?
在頁面上的操作觸發Ajax請求之後,我想WatiN等待請求完成,然後驗證頁面是否已正確更新。
我有一種感覺,該解決方案將涉及評估JavaScript註冊處理程序爲$.ajaxStart
和$.ajaxComplete
來跟蹤請求是否正在進行。我很快就會深究,但是想看看其他人是否已經解決了這個問題。似乎這將是Ajax測試的常見問題。
我已經創建了幾個WatiN瀏覽器擴展方法來解決這個問題,但我仍然對其他解決方案感興趣。
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);
}
}
因爲.ajaxStart
被稱爲僅第一個Ajax請求該解決方案並不能很好地工作,而.ajaxComplete
是每一個Ajax請求完成時調用。如果您在控制檯中運行這個簡單的代碼:
$.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/
希望這有助於。
好的調用濫用.ajaxStart。這是我解決方案中的一個錯誤。使用.ajaxStop也會更簡單。謝謝! – 2010-12-14 19:58:13
我剛剛在使用WatiN進行一些測試時遇到了這個問題。我發現,它被要求加在測試中處理Ajax的更好的支持,在version 1.1.0.4000 of WatiN(5月2日2007年發佈(最新版本從2009年12月20日)是2.0 RC2):
阿賈克斯 更好的支撐性測試這個版本增加了 一些更多的選擇到你的工具箱。
添加了一個新方法,它將等待 ,直到某個屬性具有某個 值。這可能在 需要等待 直到元素值更新爲 的情況下得心應手。
實施例:
// 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。
我還沒有仔細研究過它,所以我不能告訴它在哪些情況下可能有用或沒有。但認爲如果有其他人遇到這個問題,可以值得一提。
該解決方案運行良好,除非在注入監視器javascript之前開始一個或多個ajax請求(此時計數器不再準確)。 我不知道如何在WatiN的過程中提前注入顯示器。最好的辦法是在運行測試時包含jquery後立即包含監視器。 – 2010-03-09 22:47:36
我將全局ajax事件處理程序放入我的應用程序的主頁面中。此外,我只保留一個semaphone位,而不是一個計數器:http://lebobitz.wordpress.com/2011/03/06/synchronizing-watin-and-ajax-with-jquery/ – 2011-03-11 03:16:54
您的代碼雖然有一個問題 - 如果網站沒有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); – Alex 2012-08-27 15:47:22