2012-03-08 45 views
9

He estado buscando una solución para esto, pero fue en vano. Tengo un botón en el que estoy haciendo clic, que a veces lleva mucho tiempo devolver los datos, y el controlador está agotando el tiempo y solo mata la aplicación, supongo.Selenium Webdriver esperar al elemento clic?

Estoy tratando de usar la clase WebDriverWait para lograr esto, pero el método Click() no está disponible en la forma en que lo estoy usando.

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0)); 

bool clicked = wait.Until<bool>((elem) => 
{ 
    elem.Click(); //Doesn't Work 
    return true; 
}); 

El método ImplicitlyWait() es sólo para esperar a que se carguen los elementos, pero este tiempo de espera en Click(), por lo que no se puede incluso buscar un elemento.

El método SetScriptTimeout() simplemente funciona con la ejecución de javascript, lo que no estoy haciendo.

¿Alguien sabe de una manera de hacer esto?

Respuesta

5

Además de la solución de prestomanifesto, puedo ofrecer una solución menos que ideal para la que implementé para resolver este problema. Resulta que está lanzando una excepción - Sin respuesta, etc ... - así que simplemente lo rodeé en una captura de prueba y luego esperé a que se cerrara la ventana emergente, lo que parece funcionar bien.

Puedes sustituir lo que quieras en tu ciclo, solo asegúrate de poner un contador para que no se repita para siempre.

try 
{ 
    element.Click(); 
} 
catch 
{ 
    cnt++; 
    do 
    { 
     //wait for whatever 
     cnt++; 
     Thread.Sleep(1000); 
     // Wait for 30 seconds for popup to close 
    } while (!string.IsNullOrEmpty(browser.CurrentWindowHandle) && cnt < 30); 
} 
+0

estoy luchando por encontrar una mejor solución, he publicado aquí si puede echarle un vistazo http://stackoverflow.com/questions/12967008/webdriverwait-or-implicitlywait-or-explictlywait-nothing-works –

0

Yo uso este script:

private static void waitUntilScriptFoundAndExecute(String script) { 
    int tries = 0; 
    boolean found = false; 
    do { 
     tries++; 
     try { 
     driver.executeScript(script); 
     found = true; 
     } catch (NoSuchElementException nse) { 
     System.out.println("Wait for script NSE (" + tries + ")"); 
     } catch (WebDriverException wde) { 
     System.out.println("Wait for script WDE (" + tries + ")"); 
     } catch (Exception e) { 
     System.out.println("Wait for script E (" + tries + ")"); 
     } 

     // Waiting 
     if (!found) { 
     System.out.println("Wait for script Not found (" + tries + ")"); 
     waiting(SCRIPT_WAITING_INTERVAL); 
     } 
    } while (!found && tries < MAX_SCRIPT_WAIT_TRIES); 

    if (!found) { 
     System.out.println("Script aborted: " + script); 
    } 
    } 
+0

Esto no funcionará para lo que estoy haciendo, mientras que es útil para buscar un script. Gracias. Finalmente encontré una solución y la publicaré una vez que pueda. Los nuevos usuarios no pueden responder a su propia solución de inmediato. – hacket

+0

Estoy en el mismo tablero ¿Cómo lo arreglaste? ¿Puedes compartir? Edita tu pregunta y pega tu solución. –

5

En lugar de Click se podría tratar de usar SendKeys. A diferencia de Click, SendKeys no espera a que la página termine de cargarse antes de reanudar la ejecución del código. Así que usted puede hacer algo como esto:

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0)); 

elem.SendKeys(Keys.Enter);  
wait.Until<bool>((_driver) => 
{   
    //Check here if results have loaded yet 
    return true; 
}); 

Como nota al margen, estoy bastante seguro de Until toma en un IWebBrowser como una entrada, no un elemento, por lo que no puede hacer clic en elem.

+0

Esta es una buena solución, lamentablemente el envío de ingresar a este botón no funciona. No estoy seguro de por qué ... – hacket

+0

Eso también sucede a veces, especialmente cuando el clic desencadena un evento jQuery. En ese caso, uso 'ExecuteScript' para realizar el clic, algo así como:' driver.ExecuteScript ("$ (arguments [0]); click()", elem); 'Me alegro de que hayas encontrado una solución por el momento. – prestomanifesto

10

intente esto:

WebDriverWait wait = new WebDriverWait(driver , 1000) ; 
wait.until(ExcepctedConditions.elementToBeClickable(ById("element")); 

elemento puede ser Identificación de cualquier elemento presente en la página siguiente se le redirige a. Una vez que la página se carga por completo, comenzará a ejecutar su código.

+0

el problema es que cuando se procesa element.click(), se detiene y espera alrededor de 30 segundos para que vuelva el método .click(). Si no lo hace, arroja una excepción. – hacket

0

Método de extensión RepeatUntil usando LINQ Expresiones Lambda

copiar este código a su proyecto:

public static class SeleniumExtensionMethods 
    { 
     public static IWebElement RepeatUntil<T>(this T obj, 
      Func<T, IEnumerable<IWebElement>> func, 
       Func<IWebElement, bool> compare, 
        int MaxRetry = 20) 
     { 
      //call function to get elements 
      var eles = func(obj); 
      IWebElement element = null; 
      while (element == null && MaxRetry > 0) 
      { 
       MaxRetry-=1; 
       //call the iterator 
       element = IterateCollection(compare, eles); 
       if (element == null) 
       { 
        Thread.Sleep(500); 
        //get new collection of elements 
        eles = func(obj); 
       } 
      }; 

      return element; 
     } 

     private static IWebElement IterateCollection(
      Func<IWebElement, bool> compare, 
      IEnumerable<IWebElement> eles){ 
      IWebElement element = null; 
      eles.ToList().ForEach(
       ele => 
       { 
        //call the comparator 
        var found = compare(ele); 
        if (found) element = ele; 
       }); 
      return element; 
     } 
    } 

acceder a ella con esta sintaxis:

// You can change PageObjectType to IWebDriver or IWebElement so that 
// cb is of any type. 
var element = cb.RepeatUntil<MyPageObjectType>(
    //This is the first function to provide the elements 
    p => p.FindElements(By.ClassName("TreeNode")), 
    //This is the comparator 
    ele => ele.Text == nodeText && ele.Location.Y>YLocation); 

Nota: En el ejemplo anterior, estamos pasando un tipo de objeto de página pero puede cambiar esto a b e de tipo IWebDriver o evento IWebElement. Todo el parámetro de tipo le permite usar esto como un método de extensión para el tipo que especifique.

Tenga en cuenta la flexibilidad del método de extensión en que la persona que llama puede determinar tanto la colección como el comparador.

Cuestiones relacionadas