Selenium 2 WebDri等待Ajax调用完成
我正在使用Selenium 2 WebDriver来测试使用AJAX的UI。
有没有一种方法可以使驱动程序稍稍等待Ajax请求将完成。
基本上我有这个:
d.FindElement(By.XPath("//div[8]/div[3]/div/button")).Click();
// This click trigger an ajax request which will fill the below ID with content.
// So I need to make it wait for a bit.
Assert.IsNotEmpty(d.FindElement(By.Id("Hobbies")).Text);
10个解决方案
75 votes
如果您对ajax请求使用jQuery,则可以等到jQuery.active属性为零。 其他库可能具有类似的选项。
public void WaitForAjax()
{
while (true) // Handle timeout somewhere
{
var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
if (ajaxIsComplete)
break;
Thread.Sleep(100);
}
}
Morten Christiansen answered 2020-01-06T18:19:59Z
41 votes
您也可以在这里使用Selenium显式等待。 这样就无需自己处理超时
public void WaitForAjax()
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
wait.Until(d => (bool)(d as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"));
}
Mila answered 2020-01-06T18:20:19Z
15 votes
var wait = new WebDriverWait(d, TimeSpan.FromSeconds(5));
var element = wait.Until(driver => driver.FindElement(By.Id("Hobbies")));
Hakan Hastekin answered 2020-01-06T18:19:39Z
7 votes
基于Morten Christiansens的Java解决方案
public void WaitForAjax() throws InterruptedException
{
while (true)
{
Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
if (ajaxIsComplete){
break;
}
Thread.sleep(100);
}
}
sherif answered 2020-01-06T18:20:40Z
3 votes
通过添加一个超时参数只是一点点改进:
internal static void WaitForAllAjaxCalls(this ISelenium selenium, IWebDriver driver, int timeout = 40)
{
Stopwatch sw = new Stopwatch();
sw.Start();
while (true)
{
if (sw.Elapsed.Seconds > timeout) throw new Exception("Timeout");
var ajaxIsComplete = (bool)driver.ExecuteScript("return jQuery.active == 0");
if (ajaxIsComplete)
break;
Thread.Sleep(100);
}
}
Victor Hugo answered 2020-01-06T18:21:00Z
2 votes
这是我的代码:
public static void WaitForCommission (WebDriver driver) throws Exception {
for (int second = 0;; second++) {
if (second >= 30) fail("timeout");
try {
if (IsElementActive(By.id("transferPurposeDDL"), driver))
break;
} catch (Exception e) {}
Thread.sleep(1000);
}
}
private static boolean IsElementActive(By id, WebDriver driver) {
WebElement we = driver.findElement(id);
if(we.isEnabled())
return true;
return false;
}
这段代码确实有效。
Anton answered 2020-01-06T18:21:24Z
2 votes
只是很小的改进:
//Wait for Ajax call to complete
public void WaitForAjax1() throws InterruptedException
{
while (true)
{
if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
break;
}
Thread.sleep(100);
}
}
Pavan T answered 2020-01-06T18:21:44Z
1 votes
如果您正在使用石墨烯,则可以使用以下方法:
Graphene.waitModel().until((Predicate) input -> (Boolean) ((JavascriptExecutor) input).executeScript("return jQuery.active == 0"));
Markus Heberling answered 2020-01-06T18:22:03Z
1 votes
“ XML Http请求”是用于将Ajax请求发送到服务器的协议,因此,此类请求的存在表示正在进行的基于Ajax的操作。
有许多浏览器插件可让您监视浏览器发送的XML Http请求。 我个人使用了适用于Firefox的Firebug插件,这是一个非常有用的工具。 安装完成后,Firebug在浏览器窗口的右下角显示类似Bug的图标。 单击类似错误的图标将启动Firebug,如上图所示。 选择“ Net”,然后选择“ XHR”以启动XHR控制台,其中将显示浏览器发送的所有XML HTTP请求。
尽可能避免使用thread.sleep()。 这是一段接受等待时间作为输入并在指定时间运行秒表的代码。
您可以将输入时间(以秒为单位)设置为30开始。
protected void WaitForAjaxToComplete(int timeoutSecs)
{
var stopWatch = new Stopwatch();
try
{
while (stopWatch.Elapsed.TotalSeconds < timeoutSecs)
{
var ajaxIsComplete = (bool)(WebDriver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
if (ajaxIsComplete)
{
break;
}
}
}
//Exception Handling
catch (Exception ex)
{
stopWatch.Stop();
throw ex;
}
stopWatch.Stop();
}
Chethan S G answered 2020-01-06T18:22:38Z
1 votes
如果使用Coypu,则可以在AJAX调用后检查元素是否存在,然后可以单击它:
private void WaitUntilExistsThenClick(string selectorId)
{
var searchBoxExists = new State(() => browser.FindId(selectorId).Exists());
if (browser.FindState(searchBoxExists) == searchBoxExists)
{
browser.FindId(selectorId).Click();
}
}
OlegGuy answered 2020-01-06T18:22:58Z