Espere a que se complete una llamada de Ajax con Selenium 2 WebDriver
selenium-webdriver (9)
Aquí está mi código:
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;
}
Este código es realmente trabajo.
Estoy usando Selenium 2 WebDriver para probar una IU que usa AJAX.
¿Hay alguna manera de hacer que el controlador espere un poco para que se complete la solicitud de Ajax?
Básicamente tengo esto:
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);
La "Solicitud HTTP Http" es el protocolo utilizado para enviar solicitudes Ajax al servidor, por lo que la presencia de dicha solicitud indica una operación basada en Ajax en curso.
Hay una serie de complementos de navegador que le permiten controlar las solicitudes HTTP Http enviadas por el navegador. Yo personalmente uso el plugin Firebug para Firefox, que es una herramienta muy útil. Una vez instalado, Firebug muestra un ícono parecido a un insecto en la esquina inferior derecha de la ventana del navegador. Al hacer clic en el ícono de error se inicia Firebug como se muestra en la imagen de arriba. Seleccione "Net" y luego "XHR" para iniciar la consola XHR donde se mostrarán todas las solicitudes HTTP XML enviadas por el navegador.
Evite usar thread.sleep () tanto como sea posible. Aquí hay un fragmento de código que acepta el tiempo de espera como entrada y ejecuta un cronómetro para el tiempo especificado.
Puede establecer el tiempo de entrada en segundos en 30 para comenzar.
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();
}
Si está utilizando jQuery para sus solicitudes ajax, puede esperar hasta que la propiedad jQuery.active
sea cero. Otras bibliotecas pueden tener opciones similares.
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);
}
}
Si usa Graphene puede usar esto:
Graphene.waitModel().until((Predicate<WebDriver>) input -> (Boolean) ((JavascriptExecutor) input).executeScript("return jQuery.active == 0"));
Solo una pequeña mejora al agregar un parámetro de tiempo de espera:
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);
}
}
Solución Java basada en la respuesta de Morten Christiansens
public void WaitForAjax() throws InterruptedException { while (true) { Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0"); if (ajaxIsComplete){ break; } Thread.sleep(100); } }
También puede usar la espera explícita de Selenio aquí. Entonces no necesitas manejar el tiempo de espera
public void WaitForAjax()
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
wait.Until(d => (bool)(d as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"));
}
Just small improvement
//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);
}
}
var wait = new WebDriverWait(d, TimeSpan.FromSeconds(5));
var element = wait.Until(driver => driver.FindElement(By.Id("Hobbies")));