mac example chrome java selenium webdriver selenium-webdriver

java - example - Espera carga de página en Selenium



selenium webdriver python (30)

¿Cómo hacer que Selenium 2.0 espere a que se cargue la página?


En general, con Selenium 2.0, el controlador web solo debe devolver el control al código de llamada una vez que haya determinado que la página se ha cargado. Si no lo hace, puede llamar a waitforelemement , que completa el ciclo de findelement llamadas hasta que se encuentra o se agota el tiempo de espera (se puede establecer el tiempo de espera).


Espere explícitamente o espera condicional en esta espera hasta que se dé esta condición.

WebDriverWait wait = new WebDriverWait(wb, 60); wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

Esto esperará por cada elemento web durante 60 segundos.

Use implícitamente la espera para la espera de cada elemento en la página hasta ese momento dado.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Esto esperará por cada elemento web durante 60 segundos.


Esto parece ser una seria limitación de WebDriver. Obviamente, la espera de un elemento no implicará que la página se cargue, en particular, el DOM se puede construir completamente (estado de inicio) en el que JS todavía se está ejecutando y las imágenes y CSS aún se están cargando.

Creo que la solución más sencilla es establecer una variable JS en el evento onload después de que todo se haya inicializado y comprobar y esperar esta variable JS en Selenium.


Implementación de Ruby:

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


La forma más sencilla es esperar un elemento que aparecerá en la página cargada.

Si desea hacer clic en algún botón una vez que se haya cargado la página, puede utilizar esperar y hacer clic en:

await().until().at.most(20, TimeUnit.Seconds).some_element.isDisplayed(); // or another condition getDriver().find(some_element).click;


La mejor manera de esperar a que se carguen las páginas cuando se usan los enlaces de Java para WebDriver es usar el patrón de diseño del objeto de página con PageFactory. Esto le permite utilizar el AjaxElementLocatorFactory que para ponerlo simplemente actúa como una espera global para todos sus elementos. Tiene limitaciones en elementos como buzones o transiciones complejas de javascript, pero reducirá drásticamente la cantidad de código necesario y acelerará los tiempos de prueba. Un buen ejemplo se puede encontrar en este blogpost. Se supone una comprensión básica de Core Java.

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html


La mejor manera que he visto es utilizar la stalenessOf fija de stalenessOf esperada, para esperar a que la página antigua se vuelva obsoleta.

Ejemplo:

WebDriver driver = new FirefoxDriver(); WebDriverWait wait = new WebDriverWait(driver, 10); WebElement oldHtml = driver.findElement(By.tagName("html")); wait.until(ExpectedConditions.stalenessOf(oldHtml));

Espera diez segundos hasta que la etiqueta HTML antigua se vuelva obsoleta y, a continuación, lanza una excepción si no sucede.


La respuesta de Imran se repitió para Java 7:

WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver wdriver) { return ((JavascriptExecutor) driver).executeScript( "return document.readyState" ).equals("complete"); } });


Llamar debajo de la función

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


Me sorprende que los predicados no fueran la primera opción, ya que normalmente sabe con qué elemento (s) interactuará en la página que está esperando para cargar. Mi enfoque siempre ha sido desarrollar predicados / funciones como waitForElementByID(String id) y waitForElemetVisibleByClass(String className) , etc., y luego usarlos y reutilizarlos donde sea que los necesite, ya sea para cargar una página o cambiar el contenido de la página. Esperando que.

Por ejemplo,

En mi clase de prueba:

driverWait.until(textIsPresent("expectedText");

En mi clase de prueba padre:

protected Predicate<WebDriver> textIsPresent(String text){ final String t = text; return new Predicate<WebDriver>(){ public boolean apply(WebDriver driver){ return isTextPresent(t); } }; } protected boolean isTextPresent(String text){ return driver.getPageSource().contains(text); }

Si bien esto parece mucho, se encarga de verificar repetidamente para usted y el intervalo para la frecuencia con la que se realiza la verificación se puede establecer junto con el tiempo de espera final antes de que se agote el tiempo de espera. Además, reutilizará dichos métodos.

En este ejemplo, la clase padre definió e inició el WebDriver driver y el WebDriver driver WebDriverWait driverWait .

Espero que esto ayude.


Mi forma simple:

long timeOut = 5000; long end = System.currentTimeMillis() + timeOut; while (System.currentTimeMillis() < end) { if (String.valueOf( ((JavascriptExecutor) driver) .executeScript("return document.readyState")) .equals("complete")) { break; } }


Puede eliminar la línea System.out . Se añade para fines de depuración.

WebDriver driver_; public void waitForPageLoad() { Wait<WebDriver> wait = new WebDriverWait(driver_, 30); wait.until(new Function<WebDriver, Boolean>() { public Boolean apply(WebDriver driver) { System.out.println("Current Window State : " + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))); return String .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")) .equals("complete"); } }); }


Puede esperar explícitamente a que aparezca un elemento en la página web antes de poder realizar cualquier acción (como element.click ())

driver.get("http://somedomain/url_that_delays_loading"); WebElement myDynamicElement = (new WebDriverWait(driver, 10)) .until(new ExpectedCondition<WebElement>(){ @Override public WebElement apply(WebDriver d) { return d.findElement(By.id("myDynamicElement")); }});

Esto es lo que usé para un escenario similar y funciona bien.


Puede probar este código para que la página se cargue por completo hasta que se encuentre el elemento.

public void waitForBrowserToLoadCompletely() { String state = null; String oldstate = null; try { System.out.print("Waiting for browser loading to complete"); int i = 0; while (i < 5) { Thread.sleep(1000); state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString(); System.out.print("." + Character.toUpperCase(state.charAt(0)) + "."); if (state.equals("interactive") || state.equals("loading")) break; /* * If browser in ''complete'' state since last X seconds. Return. */ if (i == 1 && state.equals("complete")) { System.out.println(); return; } i++; } i = 0; oldstate = null; Thread.sleep(2000); /* * Now wait for state to become complete */ while (true) { state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString(); System.out.print("." + state.charAt(0) + "."); if (state.equals("complete")) break; if (state.equals(oldstate)) i++; else i = 0; /* * If browser state is same (loading/interactive) since last 60 * secs. Refresh the page. */ if (i == 15 && state.equals("loading")) { System.out.println("/nBrowser in " + state + " state since last 60 secs. So refreshing browser."); driver.navigate().refresh(); System.out.print("Waiting for browser loading to complete"); i = 0; } else if (i == 6 && state.equals("interactive")) { System.out.println( "/nBrowser in " + state + " state since last 30 secs. So starting with execution."); return; } Thread.sleep(4000); oldstate = state; } System.out.println(); } catch (InterruptedException ie) { ie.printStackTrace(); } }


Puede usar el siguiente método existente para configurar el tiempo para pageeLoadTimeout en el siguiente ejemplo, si la página tarda más de 20 segundos en cargarse, entonces se lanzará una excepción a la recarga de página.

WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)


Puede usar este fragmento de código para cargar la página:

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

O puede usar el camarero para que se cargue cualquier elemento y se haga visible / haga clic en esa página, lo más probable es que se cargue al final de la carga como:

Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement)); var element = GlobalDriver.FindElement(By.XPath(xpathOfElement)); var isSucceededed = element != null;


Puedes usar esperar. Básicamente hay 2 tipos de espera en selenio.

  • Espera implícita
  • Espera explícita

- espera implícita

Esto es muy simple, por favor vea la sintaxis a continuación:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Espera explícita

Espere explícitamente o espera condicional en esta espera hasta que se produzca una condición determinada.

WebDriverWait wait = new WebDriverWait(driver, 40); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Puede usar otras propiedades como visblityOf() , visblityOfElement()


Si desea esperar a que se cargue un elemento específico, puede usar el método isDisplayed() en un RenderedWebElement :

// Sleep until the div we want is visible or 5 seconds is over long end = System.currentTimeMillis() + 5000; while (System.currentTimeMillis() < end) { // Browsers which render content (such as Firefox and IE) return "RenderedWebElements" RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m")); // If results have been returned, the results are displayed in a drop down. if (resultsDiv.isDisplayed()) { break; } }

(Ejemplo de la Guía de introducción de 5 minutos )


Si establece la espera implícita del controlador, luego findElement método findElement en un elemento que espera que esté en la página cargada, el WebDriver sondeará ese elemento hasta que encuentre el elemento o alcance el valor de tiempo de espera.

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

fuente: implicit-waits


También puede comprobar pageLoaded utilizando el código siguiente

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"));


También puede usar la clase: ExpectedConditions para esperar explícitamente a que se muestre un elemento en la página web antes de que pueda realizar cualquier acción.

Puede usar la clase ExpectedConditions para determinar si un elemento es visible:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

Consulte la ExpectedConditions class Javadoc de ExpectedConditions class Javadoc para obtener una lista de todas las condiciones que puede verificar.


Todas estas soluciones están bien para casos específicos, pero tienen al menos uno de los dos problemas posibles:

  1. No son lo suficientemente genéricos: quieren que sepas, con anticipación, que se cumplirá alguna condición específica de la página a la que vas a ir (por ejemplo, se mostrará algún elemento)

  2. Están abiertos a una condición de carrera en la que usas un elemento que está realmente presente en la página antigua así como en la nueva.

Aquí está mi intento de una solución genérica que evite este problema (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__))

A continuación, 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 elemento <html> nivel superior. Cuando una página se actualiza o se carga, obtiene un nuevo elemento html con una nueva identificación.

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 de Pythonic, reutilizable, genérico, 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 puedes usarlo en casi cualquier interacción con selenio:

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

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

Más información en una obeythetestinggoat.com/…


Usa la clase WebDriverWait

También vea here

Puedes esperar mostrar algún elemento. algo como en C #:

WebDriver _driver = new WebDriver(); WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0)); _wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));


Use implícitamente la espera para la espera de cada elemento en la página hasta el momento dado.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

esta espera para cada elemento en la página durante 30 seg.

Otra espera es la espera explícita o la espera condicional en esta espera hasta que se cumpla la condición.

WebDriverWait wait = new WebDriverWait(driver, 40); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

En id. Da la identificación del elemento estático que se muestra de forma difusa en la página, tan pronto como se carga la página.


Utilice una condición if para cualquiera de los elementos presentes.

try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }


obeythetestinggoat.com/… proporciona el siguiente enfoque interesante:

  1. Almacena una referencia a un elemento WebElement desde la página anterior.
  2. Haga clic en el enlace.
  3. Continúe invocando operaciones en WebElement hasta que se StaleElementReferenceException .

Código de muestra:

WebElement link = ...; link.click(); new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) -> { try { link.isDisplayed(); return false; } catch (StaleElementReferenceException unused) { return true; } });


SelenioWaiter :

import com.google.common.base.Function; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; public class SeleniumWaiter { private WebDriver driver; public SeleniumWaiter(WebDriver driver) { this.driver = driver; } public WebElement waitForMe(By locatorname, int timeout){ WebDriverWait wait = new WebDriverWait(driver, timeout); return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname)); } public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) { // TODO Auto-generated method stub return new Function<WebDriver, WebElement>() { @Override public WebElement apply(WebDriver driver) { return driver.findElement(locator); } }; } }

Y para que lo uses :

_waiter = new SeleniumWaiter(_driver); try { _waiter.waitForMe(By.xpath("//..."), 10); } catch (Exception e) { // Error }


Solución NodeJS:

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)


/** * Call this method before an event that will change the page. */ private void beforePageLoad() { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("document.mpPageReloaded=''notYet'';"); } /** * Call this method after an event that will change the page. * * @see #beforePageLoad * * Waits for the previous page to disappear. */ private void afterPageLoad() throws Exception { (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() { @Override public boolean apply(WebDriver driver) { JavascriptExecutor js = (JavascriptExecutor) driver; Object obj = js.executeScript("return document.mpPageReloaded;"); if (obj == null) { return true; } String str = (String) obj; if (!str.equals("notYet")) { return true; } return false; } }); }

Puede cambiar del documento a un elemento, en el caso de que solo se cambie parte de un documento.

Esta técnica se inspiró en la respuesta de sincebasic.


driver.asserts().assertElementFound("Page was not loaded", By.xpath("//div[@id=''actionsContainer'']"),Constants.LOOKUP_TIMEOUT);