it-swarm.com.de

WebDriver: Prüfen ob ein Element existiert?

Wie überprüfe ich, ob ein Element mit dem Webtreiber existiert?

Ist die Verwendung eines Try Catch wirklich der einzig mögliche Weg?

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

Sie könnten alternativ tun:

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

Das spart den bösen Versuch/Fang

214
Mike Kwan

Ich stimme Mikes Antwort zu, aber es gibt eine implizite Wartezeit von 3 Sekunden, wenn keine Elemente gefunden werden, die ein- und ausgeschaltet werden können. Dies ist nützlich, 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 Utility-Methode integrieren, sollte dies die Leistung verbessern, wenn Sie viele Tests ausführen

49
Edd

Wie im Kommentar angegeben, ist dies in C # nicht Java, aber die Idee ist die gleiche. Ich habe dieses Problem eingehend untersucht und letztendlich ist das Problem, FindElement gibt immer eine Ausnahme zurück, wenn das Element nicht ' Es gibt keine überladene Option, mit der Sie null oder etwas anderes abrufen können. Aus diesem Grund bevorzuge ich diese Lösung gegenüber anderen.

  1. Das Zurückgeben einer Liste von Elementen und das Überprüfen, ob die Listengröße 0 ist, funktioniert, aber Sie verlieren auf diese Weise die Funktionalität. Sie können keine .click () -Auflistung von Links erstellen, selbst wenn die Auflistungsgröße 1 ist.
  2. Sie könnten behaupten, dass das Element vorhanden ist, aber dies stoppt häufig 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, wenn sie vorhanden ist, oder auf andere Weise fortfahren.
  3. Es ist nur langsam, wenn Sie das Zeitlimit nicht festlegen driver.Manage (). Timeouts (). ImplicitlyWait (TimeSpan.FromSeconds (0));
  4. Es ist eigentlich sehr einfach und elegant, sobald die Methode erstellt ist. Wenn ich FindElementSafe anstelle von FindElement verwende, sehe ich den hässlichen try/catch-Block nicht und kann eine einfache Exists -Methode verwenden. Das würde ungefähr 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.Exists

    /// <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 dies ist vom Standpunkt der Wartung eine schlechte Idee.

8

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
    }
5
Amstel Bytes

sie können eine Behauptung aufstellen.

siehe das Beispiel

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

sie können dies verwenden, dies ist native:

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);
    }
  }
3
Ran Adler

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 der Assertion auf.

2
Ripon Al Wasim

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 Zeitlimits geladen wurde.
  2. Sobald die Seite geladen ist, reduziere ich die implizite Wartezeit des WebDrivers auf einige Millisekunden. In meinem Fall sollten 100 Mills wahrscheinlich auch mit 0 Mills funktionieren.
  3. wenn Sie findElements (By) aufrufen, wartet der WebDriver nur so lange, bis das Element gefunden wurde.
  4. erhöhen Sie die implizite Wartezeit für das Laden zukünftiger Seiten

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

Verwendungszweck:

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");
}
2
Lotzy
String link = driver.findElement(By.linkText(linkText)).getAttribute("href")

Dadurch erhalten Sie den Link, auf den das Element verweist.

1
user1549161