¿Cómo hacer que Selenium espere hasta que un elemento esté presente?

3 minutos de lectura

Avatar de usuario de Steve Chambers
steve cámaras

Estoy tratando de hacer que Selenium espere un elemento que se agregue dinámicamente al DOM después de cargar la página. Intenté esto:

fluentWait.until(ExpectedConditions.presenceOfElement(By.id("elementId"));

En caso de que ayude, aquí está fluentWait:

FluentWait fluentWait = new FluentWait<>(webDriver) {
    .withTimeout(30, TimeUnit.SECONDS)
    .pollingEvery(200, TimeUnit.MILLISECONDS);
}

Pero arroja un NoSuchElementException. Parece que presenceOfElement espera que el elemento esté allí, por lo que es defectuoso. Esto debe ser pan y mantequilla para Selenium, y no quiero reinventar la rueda… ¿Hay alguna alternativa, idealmente sin rodar la mía? Predicate?

Avatar de usuario de Petr Mensik
petr mensik

tienes que llamar ignoring con una excepción para ignorar mientras el WebDriver esperará.

FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
        .withTimeout(30, TimeUnit.SECONDS)
        .pollingEvery(200, TimeUnit.MILLISECONDS)
        .ignoring(NoSuchElementException.class);

Consulte la documentación de FluidoEspere para más información. Pero tenga en cuenta que esta condición ya está implementada en Condiciones esperadaspor lo que debe utilizar:

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

*Menos versiones de Selenium:

withTimeout(long, TimeUnit) has become withTimeout(Duration)
pollingEvery(long, TimeUnit) has become pollingEvery(Duration)

Entonces el código se verá así:

FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
        .withTimeout(Duration.ofSeconds(30)
        .pollingEvery(Duration.ofMillis(200)
        .ignoring(NoSuchElementException.class);

Se puede encontrar un tutorial básico para esperar aquí.

  • o debería ser o debería ser si está utilizando java 8 le daría un error de compilación.

    – Shek

    5 de mayo de 2017 a las 3:44

  • NO está implementado en ExpectedCondition… está en WebDriverWait. public WebDriverWait (controlador de WebDriver, reloj del reloj, durmiente del durmiente, tiempo de espera prolongado en segundos, tiempo de espera prolongado del sueño) { super (controlador, reloj, durmiente); this.withTimeout(timeOutInSeconds, TimeUnit.SECONDS); this.pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS); this.ignoring(NotFoundException.class); este.controlador = controlador; }

    – Sugat Mankar

    17 de junio de 2017 a las 3:57


avatar de usuario de bhupendra
bhupendra

Usar:

WebDriverWait wait = new WebDriverWait(driver, 5)
wait.until(ExpectedConditions.visibilityOf(element));

Puede usar esto como un tiempo antes de cargar toda la página, el código se ejecuta y arroja un error. El tiempo es en segundos.

Déjame recomendarte usar seleniuro biblioteca. Permite escribir pruebas mucho más concisas y legibles. Puede esperar la presencia de elementos con una sintaxis mucho más corta:

$("#elementId").shouldBe(visible);

Aquí hay un proyecto de muestra para probar la búsqueda de Google:
https://github.com/selenide-examples/google

  • ¿No hay posibilidad de que esto se transfiera a Python?

    – franklin

    13/02/2016 a las 18:00

  • Está portado a Python. Consulte la biblioteca de Python “Selene”.

    – Andrei Solntsev

    21 de febrero de 2017 a las 21:42

Avatar de usuario de Ashwini
Ashwini

public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {

    FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
        .pollingEvery(pollingSec, TimeUnit.SECONDS)
        .ignoring(NoSuchElementException.class, TimeoutException.class).ignoring(StaleElementReferenceException.class);

    for (int i = 0; i < 2; i++) {
        try {
            //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title="We are processing through trillions of data events, this insight may take more than 15 minutes to complete."]")));
        fWait.until(ExpectedConditions.visibilityOf(element));
        fWait.until(ExpectedConditions.elementToBeClickable(element));
        } catch (Exception e) {

        System.out.println("Element Not found trying again - " + element.toString().substring(70));
        e.printStackTrace();

        }
    }

    return element;

    }

FluentWait arroja una excepción NoSuchElementException en caso de confusión

org.openqa.selenium.NoSuchElementException;     

con

java.util.NoSuchElementException

en

.ignoring(NoSuchElementException.class)

¿Ha sido útil esta solución?