WebDriver - Warten Sie mit Java auf ein Element

79

Ich suche nach etwas Ähnlichem, um waitForElementPresentzu überprüfen, ob ein Element angezeigt wird, bevor ich darauf klicke. Ich dachte, dass dies durch getan werden kann implicitWait, also habe ich Folgendes verwendet:

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

und dann auf klicken

driver.findElement(By.id(prop.getProperty(vName))).click();

Leider wartet es manchmal auf das Element und manchmal nicht. Ich habe eine Weile gesucht und diese Lösung gefunden:

for (int second = 0;; second++) {
            Thread.sleep(sleepTime);
            if (second >= 10)
                fail("timeout : " + vName);
            try {
                if (driver.findElement(By.id(prop.getProperty(vName)))
                        .isDisplayed())
                    break;
            } catch (Exception e) {
                writeToExcel("data.xls", e.toString(),
                        parameters.currentTestRow, 46);
            }
        }
        driver.findElement(By.id(prop.getProperty(vName))).click();

Und es hat gut gewartet, aber bevor es abgelaufen ist, musste es 10 mal 5, 50 Sekunden warten. Ein bisschen viel. Also habe ich das implizite Warten auf 1 Sekunde eingestellt und bis jetzt schien alles in Ordnung zu sein. Denn jetzt warten einige Dinge 10 Sekunden vor dem Timeout, andere nach 10 Sekunden.

Wie decken Sie das Warten auf das in Ihrem Code vorhandene / sichtbare Element ab? Jeder Hinweis ist spürbar.

Tom
quelle

Antworten:

154

So mache ich das in meinem Code.

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));

oder

wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));

um genau zu sein.

Siehe auch:

Ashwin Prabhu
quelle
2
Vielen Dank! Wenn ich nur früher über diese Klasse Bescheid wüsste, wäre mein Leben einfacher :)
Tom
Wie kann ich Ihren Code in dieses Format integrieren? @FindBy(how = How.ID, using = "signup-button") WebElement signUpButton;Außerdem bekomme ich immer noch eine NPE mit Ihrem Code. Sieht so aus, als würde versucht, elementToBeClickable zu erhalten. Wie können wir diese Methode verwenden, wenn das Element nicht geladen ist?
HelloWorldNoMore
10

Sie können Explicit Wait oder Fluent Wait verwenden

Beispiel für explizites Warten -

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,20);
WebElement aboutMe;
aboutMe= wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("about_me")));     

Beispiel für fließendes Warten -

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)                            
.withTimeout(20, TimeUnit.SECONDS)          
.pollingEvery(5, TimeUnit.SECONDS)          
.ignoring(NoSuchElementException.class);    

  WebElement aboutMe= wait.until(new Function<WebDriver, WebElement>() {       
public WebElement apply(WebDriver driver) { 
return driver.findElement(By.id("about_me"));     
 }  
});  

Überprüfen Sie dieses TUTORIAL für weitere Details.

Anuja Jain
quelle
1
Diese Methode ist veraltet.
JGFMK
5

Wir haben viele Rennbedingungen mit elementToBeClickable. Siehe https://github.com/angular/protractor/issues/2313 . Etwas in dieser Richtung funktionierte einigermaßen gut, auch wenn es ein wenig brutale Gewalt war

Awaitility.await()
        .atMost(timeout)
        .ignoreException(NoSuchElementException.class)
        .ignoreExceptionsMatching(
            Matchers.allOf(
                Matchers.instanceOf(WebDriverException.class),
                Matchers.hasProperty(
                    "message",
                    Matchers.containsString("is not clickable at point")
                )
            )
        ).until(
            () -> {
                this.driver.findElement(locator).click();
                return true;
            },
            Matchers.is(true)
        );
andrej
quelle
-5

Die obige wait-Anweisung ist ein schönes Beispiel für explizites Warten.

Als explizite Wartezeiten gelten intelligente Wartezeiten, die auf ein bestimmtes Webelement beschränkt sind (wie oben im x-Pfad erwähnt).

Wenn Sie explizite Wartezeiten verwenden, teilen Sie WebDriver im Grunde genommen mit, dass es maximal X Einheiten (was auch immer Sie als timeoutInSeconds angegeben haben) warten soll, bevor es aufgibt.

Satender
quelle
5
Fügen Sie Ihrer Antwort ein Code-Snippet hinzu, da andere Benutzer die Antworten möglicherweise anders sortieren und sich der Kontext für "Oben" für sie möglicherweise ändert.
Devraj Gadhavi
Es ist 5 Jahre her und wartet immer noch auf ein Code-Snippet, sodass dies für andere sinnvoll sein kann, die nach Informationen zu diesem Thema suchen.
Caperneoignis
Wenn jemand mehr über diese Antwort erfahren möchte. guru99.com/implicit-explicit-waits-selenium.html
Murtaza Haji