WebDriver:检查元素是否存在?

时间:2011-06-29 13:17:41

标签: java testing webdriver selenium-webdriver

如何检查网络驱动程序中是否存在元素?

使用try catch真的是唯一可行的方法吗?

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

10 个答案:

答案 0 :(得分:207)

您也可以这样做:

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

这节省了令人讨厌的尝试/捕获

答案 1 :(得分:47)

我同意迈克的答案,但是如果没有找到可以打开/关闭的元素,则会有一个隐含的3秒等待,如果您正在执行此操作,这将非常有用:

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

如果您正在运行大量测试

,那么将它放入实用程序方法应该可以提高性能

答案 2 :(得分:7)

正如评论所说,这是在C#而不是Java,但想法是一样的。我已经广泛研究了这个问题,最终问题是,当元素不存在时,FindElement总是返回异常。没有重载选项允许您获取null或其他任何内容。这就是为什么我更喜欢这种解决方案的原因。

  1. 返回一个元素列表,然后检查列表大小是否有效,但是你会失去这种功能。即使集合大小为1,也无法对链接集合执行.click()。
  2. 您可以断言该元素存在但通常会停止您的测试。在某些情况下,我有一个额外的链接点击取决于我如何到达该页面,我想点击它,如果它存在或继续前进。
  3. 如果你没有设置超时 driver.Manage()。超时().ImplicitlyWait(TimeSpan.FromSeconds(0));
  4. 创建方法后,它实际上非常简单和优雅。通过使用 FindElementSafe 而不是 FindElement ,我不会“看到”丑陋的try / catch块,我可以使用简单的 Exists 方法。这看起来像这样:

    IWebElement myLink = driver.FindElementSafe(By.Id("myId"));
    if (myLink.Exists)
    {
       myLink.Click();
    }
    
  5. 以下是如何扩展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;
        }
    

    你可以使用多态来修改FindElement的IWebDriver类实例,但从维护的角度来看这是个坏主意。

答案 3 :(得分:3)

每次都适合我:

    if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
        //THEN CLICK ON THE SUBMIT BUTTON
    }else{
        //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
    }

答案 4 :(得分:2)

你可以做一个断言。

参见示例

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

你可以使用这个本机:

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

答案 5 :(得分:1)

我扩展了Selenium WebDriver实现,在我的案例中是HtmlUnitDriver来公开一个方法

public boolean isElementPresent(By by){}
像这样:

  1. 检查页面是否在超时期限内加载。
  2. 加载页面后,我将WebDriver的隐式等待时间降低到几毫秒,在我的情况下为100毫秒,可能也应该使用0工厂。
  3. 调用findElements(By),WebDriver即使找不到该元素也只会等待上面的时间。
  4. 提升未来页面加载的隐含等待时间
  5. 这是我的代码:

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

    用法:

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

答案 6 :(得分:1)

使用Java编写以下方法:

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

在断言期间调用上述方法。

答案 7 :(得分:0)

String link = driver.findElement(By.linkText(linkText)).getAttribute("href")

这将为您提供元素指向的链接。

答案 8 :(得分:-5)

使用版本2.21.0的selenium-java.jar,你可以这样做;

driver.findElement(By.id("...")).isDisplayed()

答案 9 :(得分:-7)

据我了解,这是使用网络驱动程序的默认方式。