¿Cómo puedo verificar si una página está cargada por completo o no en el controlador web?

Estoy escribiendo algunos códigos Java Webdriver para automatizar mi aplicación. ¿Cómo puedo verificar correctamente si la página se ha cargado o no? La aplicación también tiene algunas llamadas Ajax.

He declarado una espera implícita para WebDriver.

Puede establecer una variable de JavaScript en su WepPage que se establece una vez que se ha cargado. Podrías ponerlo en cualquier lugar, pero si estás usando jQuery, $(document).onReady no es un mal lugar para comenzar. De lo contrario, puede colocarlo en una etiqueta en la parte inferior de la página.

La ventaja de este método en comparación con la comprobación de la visibilidad del elemento es que usted conoce el estado exacto de la página después de que se ejecuta la instrucción de wait .

MyWebPage.html

 ... All my page content ...  

Y en tu prueba (ejemplo C #):

 // The timespan determines how long to wait for any 'condition' to return a value // If it is exceeded an exception is thrown. WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5.0)); // Set the 'condition' as an anonymous function returning a boolean wait.Until(delegate(IWebDriver d) { // Check if our global variable is initialized by running a little JS return (Boolean)((IJavaScriptExecutor)d).ExecuteScript("return typeof(window.TestReady) !== 'undefined' && window.TestReady === true"); }); 

Fragmento de ready2use simple, que funciona perfectamente para mí

 static void waitForPageLoad(WebDriver wdriver) { WebDriverWait wait = new WebDriverWait(wdriver, 60); Predicate pageLoaded = new Predicate() { @Override public boolean apply(WebDriver input) { return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete"); } }; wait.until(pageLoaded); } 

Sé que esta publicación es vieja. Pero después de recostackr todo el código de arriba, hice un buen método (solución) para manejar ajax en ejecución y páginas regulares. El código está hecho solo para C # (ya que el Selenio es definitivamente el más adecuado para C # Visual Studio después de un año de problemas).

El método se usa como un método de extensión, lo que significa que es simple; que puede agregar más funcionalidades (métodos) en este caso, al objeto IWebDriver. Importante es que debe definir: ‘this’ en los parámetros para usarlo.

La variable de tiempo de espera es la cantidad de segundos que esperará el controlador de web, si la página no responde. Usando los espacios de nombres ‘Selenium’ y ‘Selenium.Support.UI’ es posible ejecutar una parte de javascript que devuelve un booleano, ya sea que el documento esté listo (completo) y si jQuery está cargado. Si la página no tiene jQuery, el método lanzará una excepción. Esta excepción está ‘atrapada’ por el manejo de errores. En el estado de captura, el documento solo se comprobará para ver si está listo, sin verificar jQuery.

 public static void WaitUntilDocumentIsReady(this IWebDriver driver, int timeoutInSeconds) { var javaScriptExecutor = driver as IJavaScriptExecutor; var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)); try { Func readyCondition = webDriver => (bool)javaScriptExecutor.ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)"); wait.Until(readyCondition); } catch(InvalidOperationException) { wait.Until(wd => javaScriptExecutor.ExecuteScript("return document.readyState").ToString() == "complete"); } } 

Recientemente, cuando estaba lidiando con una aplicación AJAX / RIA, ¡estaba teniendo el mismo problema! Y utilicé la espera implícita, con un tiempo de alrededor de 90 segundos. Espera hasta que el elemento esté disponible … Entonces, lo que podemos hacer para asegurarnos de que esa página se cargue por completo es:

agregue una statement booleana, verificando si la condición (una parte particular del elemento) está presente y asígnela a una variable, verifique la condición y solo cuando sea verdadera, “¡haga las acciones necesarias!” … En de esta manera, me di cuenta, ambas esperas se podrían utilizar …

Ex:

 @Before { implicit wait statement} @Test { boolean tr1=Driver.findElement(By.xpath("xx")).isEnabled/isDisplayed; if (tr1==true && ____)//as many conditions, to make sure, the page is loaded { //do the necessary set of actions... driver.findElement(By.xpath("yy")).click(); } } 

¡¡Espero que esto ayude!! Está en etapa de implementación, para mí también …

Así es como lo arreglaría, usando un fragmento de código para darle una idea básica:

 public class IFrame1 extends LoadableComponent { private RemoteWebDriver driver; @FindBy(id = "iFrame1TextFieldTestInputControlID" ) public WebElement iFrame1TextFieldInput; @FindBy(id = "iFrame1TextFieldTestProcessButtonID" ) public WebElement copyButton; public IFrame1( RemoteWebDriver drv ) { super(); this.driver = drv; this.driver.switchTo().defaultContent(); waitTimer(1, 1000); this.driver.switchTo().frame("BodyFrame1"); LOGGER.info("IFrame1 constructor..."); } @Override protected void isLoaded() throws Error { LOGGER.info("IFrame1.isLoaded()..."); PageFactory.initElements( driver, this ); try { assertTrue( "Page visible title is not yet available.", driver.findElementByCssSelector("body form#webDriverUnitiFrame1TestFormID h1") .getText().equals("iFrame1 Test") ); } catch ( NoSuchElementException e) { LOGGER.info("No such element." ); assertTrue("No such element.", false); } } /** * Method: load * Overidden method from the LoadableComponent class. * @return void * @throws null */ @Override protected void load() { LOGGER.info("IFrame1.load()..."); Wait wait = new FluentWait( driver ) .withTimeout(30, TimeUnit.SECONDS) .pollingEvery(5, TimeUnit.SECONDS) .ignoring( NoSuchElementException.class ) .ignoring( StaleElementReferenceException.class ) ; wait.until( ExpectedConditions.presenceOfElementLocated( By.cssSelector("body form#webDriverUnitiFrame1TestFormID h1") ) ); } .... 

Puede tomar una captura de pantalla y guardar la página renderizada en una ubicación y puede verificar la captura de pantalla si la página se cargó completamente sin imágenes rotas.

A continuación se muestra un código de mi clase BasePageObject para esperas:

 public void waitForPageLoadAndTitleContains(int timeout, String pageTitle) { WebDriverWait wait = new WebDriverWait(driver, timeout, 1000); wait.until(ExpectedConditions.titleContains(pageTitle)); } public void waitForElementPresence(By locator, int seconds) { WebDriverWait wait = new WebDriverWait(driver, seconds); wait.until(ExpectedConditions.presenceOfElementLocated(locator)); } public void jsWaitForPageToLoad(int timeOutInSeconds) { JavascriptExecutor js = (JavascriptExecutor) driver; String jsCommand = "return document.readyState"; // Validate readyState before doing any waits if (js.executeScript(jsCommand).toString().equals("complete")) { return; } for (int i = 0; i < timeOutInSeconds; i++) { TimeManager.waitInSeconds(3); if (js.executeScript(jsCommand).toString().equals("complete")) { break; } } } /** * Looks for a visible OR invisible element via the provided locator for up * to maxWaitTime. Returns as soon as the element is found. * * @param byLocator * @param maxWaitTime - In seconds * @return * */ public WebElement findElementThatIsPresent(final By byLocator, int maxWaitTime) { if (driver == null) { nullDriverNullPointerExeption(); } FluentWait wait = new FluentWait<>(driver).withTimeout(maxWaitTime, java.util.concurrent.TimeUnit.SECONDS) .pollingEvery(200, java.util.concurrent.TimeUnit.MILLISECONDS); try { return wait.until((WebDriver webDriver) -> { List elems = driver.findElements(byLocator); if (elems.size() > 0) { return elems.get(0); } else { return null; } }); } catch (Exception e) { return null; } } 

Métodos de apoyo:

  /** * Gets locator. * * @param fieldName * @return */ public By getBy(String fieldName) { try { return new Annotations(this.getClass().getDeclaredField(fieldName)).buildBy(); } catch (NoSuchFieldException e) { return null; } }