Wie kann ich mit Selenium WebDriver prüfen, ob ein Element vorhanden ist? [duplicate]

Lesezeit: 7 Minuten

Benutzeravatar von Ralph
Ralf

Wie kann ich überprüfen, ob ein Element mit dem Webtreiber vorhanden ist?

Ist Try-Catch wirklich der einzig mögliche Weg?

boolean present;
try {
   driver.findElement(By.id("logoutLink"));
   present = true;
} catch (NoSuchElementException e) {
   present = false;
}

  • @Michael Freidgeim: Bevor Sie jemanden beschuldigen, eine doppelte Frage geschrieben zu haben, überprüfen Sie bitte das Erstellungsdatum der Frage, um zu entscheiden, welches das Duplikat ist.

    – Ralf

    29. April 2016 um 7:36 Uhr


  • Ich mache dir keine Vorwürfe. Es ist nur eine Art Haushaltsführung, ähnliche Fragen miteinander zu verknüpfen. Siehe Soll ich dafür stimmen, eine doppelte Frage zu schließen, obwohl sie viel neuer ist und aktuellere Antworten enthält? “Wenn die neue Frage eine bessere Frage ist oder bessere Antworten hat, dann stimmen Sie dafür, die alte als Duplikat der neuen zu schließen.”

    – Michael Freigeim

    29. April 2016 um 13:26 Uhr


Benutzeravatar von Mike Kwan
Mike Kwan

Sie könnten alternativ Folgendes tun:

driver.findElements(By.id("...")).size() != 0

Das erspart den fiesen try/catch

PS:

Oder genauer gesagt von @JanHrcek hier

!driver.findElements(By.id("...")).isEmpty()

  • Dies ist mein Ansatz: if(driver.findElements().Count() > 0)

    – Ali CAKIL

    12. April um 9:48 Uhr

Benutzeravatar von Edd
Edd

Ich stimme Mikes Antwort zu, aber es gibt eine implizite Wartezeit von 3 Sekunden, wenn keine Elemente gefunden werden, die ein-/ausgeschaltet werden können, was nützlich ist, wenn Sie diese Aktion häufig ausführen:

driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
boolean exists = driver.findElements( By.id("...") ).size() != 0
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

Wenn Sie dies in eine Hilfsmethode einfügen, sollte die Leistung verbessert werden, wenn Sie viele Tests ausführen.

  • Da der implizite Timeout 3 Sekunden, aber auch ein anderer Wert sein kann, sollte man den alten Wert erst speichern und dann evtl. zurücksetzen. Aber leider kann man den Wert setzen, aber nicht lesen — coole API

    – Ralf

    9. Januar 2012 um 15:02 Uhr

  • Es scheint, dass die standardmäßige implizite Wartezeit 0 ist, (seleniumhq.org/docs/04_webdriver_advanced.html) Wenn Sie es also nicht länger konfiguriert haben, sollte dies nicht erforderlich sein.

    – Andreas M

    24. Mai 2012 um 9:43 Uhr

  • @Ralph gibt es eine Möglichkeit, den aktuellen Wert zu erhalten?

    – Tim Büthe

    20. September 2012 um 16:19 Uhr

  • Zuerst stellt man es irgendwo auf, man sollte es selbst verstauen. Der Standardwert ist ebenfalls angegeben.

    – szab.kel

    24. Oktober 2014 um 22:16 Uhr

Benutzeravatar von Brantley Blanchard
Brantley Blanchard

Wie im Kommentar angegeben, ist dies in C # nicht Java, aber die Idee ist dieselbe. Ich habe dieses Problem ausgiebig untersucht und letztendlich ist das Problem, dass FindElement immer eine Ausnahme zurückgibt, wenn das Element nicht vorhanden ist. Es gibt keine überladene Option, mit der Sie null oder irgendetwas anderes erhalten können. Deshalb bevorzuge ich diese Lösung gegenüber anderen.

  1. Das Zurückgeben einer Liste von Elementen und das anschließende Überprüfen, ob die Listengröße 0 ist, funktioniert, aber Sie verlieren auf diese Weise die Funktionalität. Sie können kein .click() auf eine Sammlung von Links anwenden, selbst wenn die Sammlungsgröße 1 ist.
  2. Sie könnten behaupten, dass das Element existiert, aber das stoppt oft Ihre Tests. In einigen Fällen muss ich auf einen zusätzlichen Link klicken, je nachdem, wie ich zu dieser Seite gelangt bin, und ich möchte darauf klicken, falls vorhanden, oder anderweitig fortfahren.
  3. Es ist nur langsam, wenn Sie das Timeout nicht festlegen driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));
  4. Es ist eigentlich sehr einfach und elegant, sobald die Methode erstellt wurde. Durch die Nutzung FindElementSafe Anstatt von FindElementich “sehe” den hässlichen Try/Catch-Block nicht und kann einen einfachen verwenden Existiert Methode. Das würde in etwa so aussehen:

    IWebElement myLink = driver.FindElementSafe(By.Id("myId"));
    if (myLink.Exists)
    {
       myLink.Click();
    }
    

So erweitern Sie IWebElement & IWebDriver

IWebDriver.FindElementSafe

    /// <summary>
    /// Same as FindElement only returns null when not found instead of an exception.
    /// </summary>
    /// <param name="driver">current browser instance</param>
    /// <param name="by">The search string for finding element</param>
    /// <returns>Returns element or null if not found</returns>
    public static IWebElement FindElementSafe(this IWebDriver driver, By by)
    {
        try
        {
            return driver.FindElement(by);
        }
        catch (NoSuchElementException)
        {
            return null;
        }
    }

IWebElement.Existiert

    /// <summary>
    /// Requires finding element by FindElementSafe(By).
    /// Returns T/F depending on if element is defined or null.
    /// </summary>
    /// <param name="element">Current element</param>
    /// <returns>Returns T/F depending on if element is defined or null.</returns>
    public static bool Exists(this IWebElement element)
    {
        if (element == null)
        { return false; }
        return true;
    }

Sie könnten Polymorphismus verwenden, um die IWebDriver-Klasseninstanz von FindElement zu ändern, aber das ist aus Wartungssicht eine schlechte Idee.

  • Es gibt zwei Probleme: 1) falsche Sprache: Java nicht C#, 2) Sie haben den hässlichen Try/Catch-Workaround verwendet (und das war die Frage, ob es einen anderen Weg als diesen hässlichen und langsamen Try/Catch gibt)

    – Ralf

    5. August 2013 um 15:34 Uhr


  • Ja, das ist C#, aber das Konzept ist dasselbe. Try/Catch ist nur hässlich, wenn man es oft machen muss. Deshalb habe ich es in einer separaten Methode gekapselt. Die endgültige Lösung ist eigentlich sehr hübsch. bool existiert = Treiber.FindElementSafe(by).Exists();

    – Brantley Blanchard

    5. August 2013 um 20:07 Uhr

  • Try/Catch ist nicht nur hässlich im Code, sondern langsam zur Laufzeit. Es in einer anderen Methode zu kapseln, behandelt das erste Problem, aber nicht das zweite.

    – Vince Bowdren

    14. April 2015 um 16:01 Uhr

  • lol, UI-Tests sind nicht für Geschwindigkeit bekannt, daher ist es die Spitze der “Agile Testing Pyramid”. Der Bruchteil einer Sekunde, der bei einer Try/Catch-ID verloren geht, wird durch die Zeit in den Schatten gestellt, die zum Abrufen und Rendern einer Seite in Chrome oder einem anderen von Ihnen verwendeten Browser benötigt wird. Wenn Sie sich solche Sorgen um Sekundenbruchteile machen, führen Sie die falsche Art von Tests durch. Ich würde vorschlagen, in diesem Fall mehr Unit-Tests durchzuführen.

    – Brantley Blanchard

    15. April 2015 um 15:47 Uhr

Benutzeravatar von Amstel Bytes
Amstel-Bytes

Das funktioniert bei mir jedes Mal:

    if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
        // Then click on the submit button
    }else{
        // Do something else as submit button is not there
    }

Lotzys Benutzeravatar
Lotzi

Ich habe die Implementierung von Selenium WebDriver erweitert, in meinem Fall HtmlUnitDriver, um eine Methode verfügbar zu machen.

public boolean isElementPresent(By by){}

so was:

  1. Überprüfen Sie, ob die Seite innerhalb eines Timeout-Zeitraums geladen wird.
  2. Sobald die Seite geladen ist, senke ich die implizite Wartezeit des WebDrivers auf einige Millisekunden, in meinem Fall 100 Millisekunden, aber es sollte wahrscheinlich auch mit 0 Millisekunden funktionieren.
  3. Rufen Sie findElements(By) auf. Der WebDriver wartet, auch wenn er das Element nicht findet, nur die Zeit von oben.
  4. Erhöhen Sie die implizite Wartezeit für das zukünftige Laden der Seite

Hier ist mein Code:

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class CustomHtmlUnitDriver extends HtmlUnitDriver {

    public static final long DEFAULT_TIMEOUT_SECONDS = 30;
    private long timeout = DEFAULT_TIMEOUT_SECONDS;

    public long getTimeout() {
        return timeout;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    public boolean isElementPresent(By by) {
        boolean isPresent = true;
        waitForLoad();
        // Search for elements and check if list is empty
        if (this.findElements(by).isEmpty()) {
            isPresent = false;
        }
        // Rise back implicitly wait time
        this.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS);
        return isPresent;
    }

    public void waitForLoad() {
        ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver wd) {
                // This will tel if page is loaded
                return "complete".equals(((JavascriptExecutor) wd).executeScript("return document.readyState"));
            }
        };
        WebDriverWait wait = new WebDriverWait(this, timeout);
        // Wait for page complete
        wait.until(pageLoadCondition);
        // Lower implicitly wait time
        this.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS);
    }
}

Verwendung:

CustomHtmlUnitDriver wd = new CustomHtmlUnitDriver();
wd.get("http://example.org");
if (wd.isElementPresent(By.id("Accept"))) {
    wd.findElement(By.id("Accept")).click();
}
else {
    System.out.println("Accept button not found on page");
}

Benutzeravatar von Peter Mortensen
Peter Mortensen

Schreiben Sie die folgende Methode mit Java:

protected boolean isElementPresent(By by){
    try{
        driver.findElement(by);
        return true;
    }
    catch(NoSuchElementException e){
        return false;
    }
}

Rufen Sie die obige Methode während einer Behauptung auf.

Benutzeravatar von Peter Mortensen
Peter Mortensen

Sie können eine Behauptung aufstellen.

Siehe Beispiel

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

Sie können dies verwenden, das ist nativ:

public static void waitForElementToAppear(Driver driver, By selector, long timeOutInSeconds, String timeOutMessage) {
    try {
        WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
        wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
    } 
    catch (TimeoutException e) {
        throw new IllegalStateException(timeOutMessage);
    }
}

  • Das scheint interessant, aber können Sie erklären, welcher Treiber das ist? Das WebDriver Javadocs zeig das nicht asserts() Methode.

    – acdcjunior

    30. August 2013 um 15:02 Uhr

1436840cookie-checkWie kann ich mit Selenium WebDriver prüfen, ob ein Element vorhanden ist? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy