Hoe te wachten tot een element aanwezig is in Selenium?

Ik probeer Selenium te laten wachten op een element dat dynamisch wordt toegevoegd aan de DOM nadat de pagina is geladen. Probeerde dit:

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

In het geval dat het helpt, hier is fluentWait:

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

Maar het gooit een NoSuchElementException– het lijkt erop dat presenceOfElementverwacht dat het element daar is, dus dit is gebrekkig. Dit moet brood en boter zijn voor Selenium en ik wil het wiel niet opnieuw uitvinden… kan iemand een alternatief voorstellen, idealiter zonder mijn eigen Predicatete rollen?


Antwoord 1, autoriteit 100%

Je moet ignoringmet uitzondering aanroepen om te negeren terwijl de WebDriverwacht.

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

Zie de documentatie van FluentWaitvoor meer info. Maar pas op dat deze voorwaarde al is geïmplementeerd in ExpectedConditionsdus je zou moeten gebruiken

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

*Update voor nieuwere versies van Selenium:

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

De code ziet er dus als volgt uit:

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

Een basishandleiding voor wachten vindt u hier.


Antwoord 2, autoriteit 20%

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

u kunt dit gebruiken als enige tijd voordat het laden van de hele pagina code wordt uitgevoerd en worpen en fouten. tijd is in seconden


Antwoord 3, autoriteit 4%

Laat me je aanraden de Selenide-bibliotheek te gebruiken.
Het maakt het schrijven van veel beknoptere en leesbare tests mogelijk. Het kan wachten op de aanwezigheid van elementen met een veel kortere syntaxis:

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

Hier is een voorbeeldproject voor het testen van Google Zoeken:
https://github.com/selenide-examples/google


Antwoord 4

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;
    }

Other episodes