Selenio espere hasta que el documento esté listo


133

¿Alguien puede decirme cómo puedo hacer que el selenio espere hasta que la página se cargue por completo? Quiero algo genérico, sé que puedo configurar WebDriverWait y llamar a algo como 'buscar' para que espere, pero no voy tan lejos. Solo necesito probar que la página se carga correctamente y pasar a la página siguiente para probar.

Encontré algo en .net pero no pude hacerlo funcionar en Java ...

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

¿Alguna idea de alguien?


¿Por qué no quieres usar esperar?
Amey

77
¿Quieres decir espera explícita? Lleva mucho tiempo, estoy probando unas 10k páginas.
Girish

2
Quiero decir, agregar una espera de reparación puede no ser una buena idea si estoy probando una gran cantidad de enlaces, ¿verdad?
Girish

10
Es inútil esperar un número fijo de segundos. Eso es adivinar.
Anders Lindén

Dado que el JavaScript de una página puede ejecutar cualquier código genérico, es imposible escribir un programa para esperar su finalización. Es una forma del problema de detención ( en.wikipedia.org/wiki/Halting_problem ). Cualquier solución aquí tendrá que hacer compromisos o basarse en supuestos de la página web subyacente.
Speedplane

Respuestas:


83

Prueba este código:

  driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

El código anterior esperará hasta 10 segundos para cargar la página. Si la carga de la página excede el tiempo, arrojará el TimeoutException. Capturas la excepción y haces tus necesidades. No estoy seguro de si se cierra la carga de la página después de la excepción lanzada. No probé este código todavía. Solo quiero probarlo.

Esta es una espera implícita. Si configura esto una vez, tendrá el alcance hasta que la instancia del controlador web se destruya.

Vea la documentación paraWebDriver.Timeouts para más información.


3
Gracias, entonces, ¿qué sucede aquí si la página se carga antes de 10 segundos, todavía esperará 10 segundos para ejecutar la siguiente línea después de la carga?
Girish

No, si su página se carga antes de 10 segundos significa que terminará la condición de espera y ejecutará la línea anterior.
Manigandan

3
Esto se utiliza cuando espera cargas de página que tardan demasiado en agotar el tiempo de espera y arrojan excepciones, no espera inmediatamente una carga de página o establece una mejor política de carga. El valor predeterminado es el tiempo infinito, por lo que las cargas de su página nunca arrojan excepciones y Selenium siempre intenta esperar a que se carguen por completo.
Petr Janeček

19
El problema con este método es que es posible que el DOM no sea completamente accesible a pesar de que la espera implícita previamente devolvió un objeto WebElement. Luego, si intenta hacer clic en el elemento, obtendrá una excepción de elemento obsoleto. Entonces, esta respuesta no es del todo segura.
djangofan

3
¿Cómo se relaciona este tiempo de espera con la espera de que se cargue un documento?
Anders Lindén

90

Su solución sugerida solo espera DOMreadyState señale complete. Pero Selenium por defecto intenta esperar a esos (y un poco más) en las cargas de página a través de driver.get()yelement.click() métodos . Ya están bloqueando, esperan a que la página se cargue por completo y deberían funcionar correctamente.

El problema, obviamente, son los redireccionamientos a través de solicitudes AJAX y scripts en ejecución: Selenium no puede atraparlos, no espera a que terminen. Además, no puede atraparlos de manera confiable readyState: espera un poco, lo que puede ser útil, pero indicará completemucho antes de que se descargue todo el contenido de AJAX.

No existe una solución general que funcione en todas partes y para todos, por eso es difícil y todos usan algo un poco diferente.

La regla general es confiar en WebDriver para que haga su parte, luego usar esperas implícitas, luego usar esperas explícitas para los elementos que desea afirmar en la página, pero hay muchas más técnicas que se pueden hacer. Debe elegir el (o una combinación de varios de ellos) que mejor funcione en su caso, en su página probada.

Vea mis dos respuestas con respecto a esto para obtener más información:


20
Eso es incorrecto, Selenium no espera ni bloquea las element.click()llamadas.
hwjp

3
@hwjp ¿Quieres elaborar más? Los JavaDoc dicen lo contrario : "Si esto hace que se cargue una nueva página, este método intentará bloquear hasta que la página se haya cargado".
Petr Janeček

55
cf algunas conversaciones que he tenido en la lista de correo parece que es inexacto selenium puede bloquear las llamadas .get donde solicita explícitamente una URL, pero no hace nada especial en las llamadas de clic, porque no puede decir si ha hecho clic en un hipervínculo "real" o en uno que será interceptado por javascript. ..
hwjp

44
Enlace a un error al comienzo de la discusión de la lista de correo. Incluso los documentos equivocan: "Si click () [...] se realiza enviando un evento nativo, entonces el método * no * esperará"
hwjp

44
Por lo tanto, todo se activa si el navegador está utilizando "eventos nativos". Y parece que la mayoría de ellos, por defecto: code.google.com/p/selenium/wiki/… (por lo que diría que esos documentos son engañosos en el mejor de los casos. Hará ping a la lista de correo).
hwjp

61

Esta es una versión Java funcional del ejemplo que dio:

void waitForLoad(WebDriver driver) {
    new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

Ejemplo para c #:

public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
  wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}

1
Amigo, estoy copiando / pegando esto. Este fragmento es simplemente brillante. ¿Por qué no pensé en esto? La verdad es que más de un par de globos oculares siempre conducen a una buena solución. Gracias.
luis.espinal

2
¿Puede poner esto en la versión java 1.7 compatible ya que las expresiones lambda no son compatibles
Vkrams

3
Versión Java 1.7: wait.until (nuevo Predicate <WebDriver> () {public boolean apply (WebDriver driver) {return ((JavascriptExecutor) driver) .executeScript ("return document.readyState"). Equals ("complete");} });
luQ

1
Si alguien quiere usar la solución de @IuQ entonces, Predicate tiene importaciónimport com.google.common.base.Predicate
Knu8

Probé esta idea en una aplicación de prueba de VB. Trabaja la mayor parte del tiempo. A veces aparece este error: System.InvalidOperationException: error de JavaScript (UnexpectedJavaScriptError) en OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Response errorResponse) La aplicación de prueba hace clic en el enlace del menú del nivel 2, luego llama a WaitObj.UntilC (Función (D ( D, InternetExplorerDriver) .ExecuteScript ("return document.readyState") = "complete"). Creo que el error se debe a que el navegador descarga la página actual y no es un objeto de documento. Tal vez espere 1/2 segundo antes de hacer "return document.readystate? Ideas?
CoolBreeze

12

Aquí está mi intento de una solución completamente genérica, en Python:

Primero, una función genérica de "espera" (use un WebDriverWait si lo desea, los encuentro feos):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Luego, la solución se basa en el hecho de que el selenio registra un número de identificación (interno) para todos los elementos de una página, incluido el <html>elemento de nivel superior . Cuando una página se actualiza o carga, obtiene un nuevo elemento html con una nueva ID.

Entonces, suponiendo que desea hacer clic en un enlace con el texto "mi enlace", por ejemplo:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Para obtener más ayuda Pythonic, reutilizable, genérica, puede hacer un administrador de contexto:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

Y luego puede usarlo en casi cualquier interacción de selenio:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Creo que es a prueba de balas! ¿Qué piensas?

Más información en una publicación de blog al respecto aquí


Enfoque muy interesante. Un desafío es si esto puede funcionar en la carga inicial de la página, después de que se inicie el navegador por primera vez. No hay garantía de que el estado inicial del navegador tenga alguna página cargada. Además, en Java, no veo que tengamos una 'identificación' en el objeto; supongo que no quiere decir que el selenio inserte un atributo de identificación html. Agregaré más a esta respuesta una vez que haya explorado más esta opción. ¡Gracias por la publicacion!
Lukus

@hwjp Utilizo esta solución muchas veces con excelentes resultados, pero parece que no funciona en un caso. Explicación completa del problema. stackoverflow.com/q/31985739/4249707
El Ruso

7

Tuve un problema similar. Necesitaba esperar hasta que mi documento estuviera listo, pero también hasta que todas las llamadas de Ajax hubieran terminado. La segunda condición resultó ser difícil de detectar. Al final verifiqué las llamadas activas de Ajax y funcionó.

Javascript:

return (document.readyState == 'complete' && jQuery.active == 0)

Método completo de C #:

private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
    var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
    var wait = new WebDriverWait(WebDriver, timeout);            

    // Check if document is ready
    Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
        .ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
    wait.Until(readyCondition);
}

¿Hay algo así como document.readyState == 'complete' && jQuery.active == 0para reaccionar?
Rain9333

7
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));

4

Para C # NUnit, debe convertir WebDriver a JSExecuter y luego ejecutar el script para verificar si el estado document.ready está completo o no. Verifique el siguiente código para referencia:

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

Esto esperará hasta que se cumpla la condición o se agote el tiempo de espera.


3

Para la carga inicial de la página, he notado que "Maximizar" la ventana del navegador prácticamente espera hasta que se complete la carga de la página (incluidas las fuentes)

Reemplazar:

AppDriver.Navigate().GoToUrl(url);

Con:

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

de uso:

OpenURL(myDriver, myUrl);

Esto cargará la página, esperará hasta que se complete, maximice y enfóquese en ella. No sé por qué es así, pero funciona.

Si desea esperar la carga de la página después de hacer clic en el siguiente o cualquier otro activador de navegación de página que no sea "Navegar ()", la respuesta de Ben Dyer (en este hilo) hará el trabajo.


1

Echa un vistazo al marco web de tapices . Puede descargar el código fuente allí.

La idea es señalar que la página está lista por el atributo html del cuerpo. Puede usar esta idea para ignorar casos complicados de demandas.

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

Y luego cree la extensión de Selenium webdriver (de acuerdo con el marco de tapices)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

Use la extensión ElementIsDisplayed escrita por Alister Scott .

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

Y finalmente crear prueba:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

1

La respuesta de Ben Dryer no se compiló en mi máquina ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait").

Versión de Java 8 de trabajo:

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

Versión de Java 7:

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1

Intenté este código y me funciona. Llamo a esta función cada vez que me muevo a otra página

public static void waitForPageToBeReady() 
{
    JavascriptExecutor js = (JavascriptExecutor)driver;

    //This loop will rotate for 100 times to check If page Is ready after every 1 second.
    //You can replace your if you wants to Increase or decrease wait time.
    for (int i=0; i<400; i++)
    { 
        try 
        {
            Thread.sleep(1000);
        }catch (InterruptedException e) {} 
        //To check page ready state.

        if (js.executeScript("return document.readyState").toString().equals("complete"))
        { 
            break; 
        }   
      }
 }

1

En Nodejs puedes conseguirlo a través de promesas ...

Si escribe este código, puede estar seguro de que la página está completamente cargada cuando llegue al ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Si escribe este código, navegará y el selenio esperará 3 segundos ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

De la documentación de Selenium:

this.get (url) → Thenable

Programa un comando para navegar a la URL dada.

Devuelve una promesa que se resolverá cuando el documento haya terminado de cargarse .

Documentación de selenio (Nodejs)


1

La espera para el evento document.ready no es la solución completa a este problema, porque este código aún se encuentra en una condición de carrera: a veces, este código se activa antes de que se procese el evento click, por lo que este regresa directamente, ya que el navegador no ha comenzado cargando la nueva página todavía.

Después de algunas búsquedas, encontré una publicación en Obay, la cabra de prueba , que tiene una solución para este problema. El código C # para esa solución es algo como esto:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

`Disparo este método directamente después de driver.navigate.gotourl, para que obtenga una referencia de la página lo antes posible. ¡Diviértete con eso!


1

normalmente cuando el selenio abre una nueva página con un clic o envía u obtiene métodos, esperará hasta que se cargue la página, pero el problema es cuando la página tiene una llamada xhr (ajax), nunca esperará a que se cargue la xhr, por lo que crear un nuevo método para monitorear un xhr y esperarlos será lo bueno.

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)driver).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

if $.active == 0así que no hay una llamada xhrs activa (que solo funciona con jQuery). para la llamada javascript ajax, debe crear una variable en su proyecto y simularla.


0

Puedes escribir algo de lógica para manejar esto. Escribí un método que devolverá WebElementy este método se llamará tres veces o puede aumentar el tiempo y agregar un cheque nulo para WebElementAquí hay un ejemplo

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

0

Ejecuté un código javascript para verificar si el documento está listo. Me ahorró mucho tiempo depurando pruebas de selenio para sitios que tienen representación del lado del cliente.

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

0
public boolean waitForElement(String zoneName, String element, int index, int timeout) {
        WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
        return true;
    }

0

Al igual que Rubanov escribió para C #, lo escribo para Java, y es:

    public void waitForPageLoaded() {
    ExpectedCondition<Boolean> expectation = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
                }
            };
    try {
        Thread.sleep(100);
        WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
        waitForLoad.until(expectation);
    } catch (Throwable error) {
        Assert.fail("Timeout waiting for Page Load Request to complete.");
    }
}

0

En Java le gustará a continuación: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }

1
Sería mejor combinar los comandos JS en uno para no tener que ir a la página dos veces, por ejemploreturn document.readyState == 'loaded' || return document.readyState == 'complete'
JeffC

0

El siguiente código probablemente debería funcionar:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));

0

Si tiene una página lenta o una conexión de red, es probable que ninguno de los anteriores funcione. Los he probado todos y lo único que funcionó para mí es esperar el último elemento visible en esa página. Tomemos, por ejemplo, la página web de Bing. Han colocado un icono de CÁMARA (buscar por botón de imagen) al lado del botón de búsqueda principal que solo es visible después de que se haya cargado la página completa. Si todos hicieron eso, entonces todo lo que tenemos que hacer es usar una espera explícita como en los ejemplos anteriores.


-1
public void waitForPageToLoad()
  {
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
      }
    });//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds

-1

Aquí hay algo similar, en Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }

Tu código no me funciona. ¿Cómo cambio hacer iframe y esperar onload = "javascript: pageload (); functionalPageLoad ();" Cómo recargar la página en Ruby? Me encuentro abriendo el iframe dentro de una página, tengo acceso a él, luego la página se vuelve a cargar y ya no puedo acceder al marco. He leído muchas respuestas con respecto a esperar, dormir, tiempo, cambiar a marco y luego a padre, sin embargo, no puedo alcanzar mi objetivo.
Amanda Cavallaro

1
Parece que su pregunta es principalmente sobre cómo cambiar al iFrame, no sobre esperar la carga de documentos. Sería mejor comenzar una nueva pregunta si no puede encontrar la solución en una pregunta sobre cómo trabajar con iFrames.
esmerilado el

-1

Puede hacer que el hilo se suspenda hasta que se vuelva a cargar la página. Esta no es la mejor solución, porque necesita tener una estimación de cuánto tiempo tarda la página en cargar.

driver.get(homeUrl); 
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();

Creo que Thread.sleep (5000) es a menudo el único método que hace que una prueba funcione, a pesar de todas las recomendaciones en contra de su uso. Ninguna combinación de esperar al elemento funciona para mí, especialmente porque muchos elementos no pueden identificarse hasta que realmente se hayan encontrado.
Steve Staple

-1

Comprobé la carga de la página completa, trabajo en Selenium 3.14.0

    public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
    {
        Until(driver, (d) =>
        {
            Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
            if (!isPageLoaded) Console.WriteLine("Document is loading");
            return isPageLoaded;
        }, timeoutInSeconds);
    }

    public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        try
        {
            webDriverWait.Until(waitCondition);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

-1

Para las personas que necesitan esperar a que aparezca un elemento específico. (usado c #)

public static void WaitForElement(IWebDriver driver, By element)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(element));
}

Entonces, si desea esperar, por ejemplo, si existe una clase = "mensaje de error" en el DOM, simplemente haga lo siguiente:

WaitForElement(driver, By.ClassName("error-message"));

Para id, entonces será

WaitForElement(driver, By.Id("yourid"));


-3

¿Estás usando Angular? Si es así, es posible que el controlador web no reconozca que las llamadas asíncronas han terminado.

Recomiendo mirar Paul Hammants ngWebDriver . El método waitForAngularRequestsToFinish () podría ser útil.


Él no estaba usando Angular. Esta respuesta fue rechazada porque parece que no leyó cuidadosamente la pregunta original.
zelusp

Pero no dejes que los votos te pongan fuera de forma. La gente aquí tiene buenas intenciones. Y la crítica es en realidad una forma de amor (porque si alguien se toma el tiempo de corregir a alguien es porque le importa). Checkout Cómo hacer preguntas de manera inteligente : esas ideas también se aplican a responder preguntas de manera inteligente.
zelusp
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.