Selenium WebDriver - 测试元素是否存在

tes*_*ter 153 java selenium selenium-webdriver

有没有办法测试元素是否存在?任何findElement方法都会以异常结束,但这不是我想要的,因为它可能是一个元素不存在而且没关系,这不是测试的失败,因此异常不能成为解决方案.

我发现这篇文章:Selenium c#Webdriver:等到元素存在 但是这是C#而我不是很擅长.任何人都可以将代码翻译成Java吗?我很抱歉,我在Eclipse中尝试过但是我没有把它直接用到Java代码中.

这是代码:

public static class WebDriverExtensions{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds){

        if (timeoutInSeconds > 0){
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }

        return driver.FindElement(by);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 259

findElements而不是findElement.

findElements 如果找不到匹配的元素而不是异常,则返回空列表.

要检查元素是否存在,您可以尝试这样做

Boolean isPresent = driver.findElements(By.yourLocator).size() > 0
Run Code Online (Sandbox Code Playgroud)

如果找到至少一个元素,则返回true,如果不存在则返回false.

  • 这将增加运行测试所需的大量时间.你无法在任何地方使用这种技术. (32认同)
  • @Droogans - 我不会为你的考试增加时间.它不会的原因是因为默认的隐式等待仍然是0.如果你增加了默认的隐式等待,那么我同意它会,但这似乎不是这里的情况. (6认同)
  • 这给了NoSuchElementFound异常,这很可惜,因为我希望使用它来避免在给定实例中捕获该异常。 (3认同)
  • 更简单的方法是使用: if(driver.getPageSource().contains("A text in page")){} 如果页面包含此文本,则条件将为 true,否则将为 false,您可以编写代码因此。 (3认同)
  • 很好,打电话给 djangofan!我通过将驱动程序超时的隐式等待更改为零,然后将其更改回之前的值,成功地使用了此策略。 (2认同)
  • 有人可以向我解释一下为什么我们还需要“presenceOfElementLocated()”方法,如果它抛出“NoSuchElementException”(根据下面的答案)。如果这个方法甚至无法正常检查元素是否存在,那么它还有什么意义呢? (2认同)

Den*_*nis 51

那个简单地查找元素并确定它是否存在的私有方法怎么样:

private boolean existsElement(String id) {
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

这将是非常容易的,并完成工作.

编辑:你甚至可以更进一步,并采取By elementLocatoras参数,如果你想通过id以外的东西找到元素,消除问题.

  • 好吧,我必须说使用Exceptions来规范程序流程并不是最好的方法. (40认同)
  • 是的,这是要走的路.不明白为什么人们忽略这种方式,并计算匹配元素,看看结果是否为0. (3认同)
  • ??这是你的建议!如果您的测试希望找不到元素,那么这是一个很好的方法。如您所示,仅返回null和assert.isnull或isnotnull,这是测试事物是否存在的一种有意义的方式。 (2认同)
  • 如果我误解了这个问题"有没有办法测试元素是否存在?" 错了,我很高兴知道为什么你的意见不同,这是否是一个合理的答案. (2认同)

小智 14

我发现这适用于Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);
Run Code Online (Sandbox Code Playgroud)

  • 如果在任何特定尝试中找不到该元素,则"presenceOfElementLocated"将抛出异常.为避免这种情况,在第一行和第二行之间添加一个`wait.ignoring(NoSuchElementException.class);`语句. (17认同)

Red*_*ins 7

public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds)
{
    WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
    wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds
    return driver.findElement(by);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到过同样的问题.对我来说,根据用户的权限级别,页面上不会显示某些链接,按钮和其他元素.我的套件的一部分是测试缺少应该丢失的元素.我花了好几个小时试图解决这个问题.我终于找到了完美的解决方案.

这样做,告诉浏览器查找指定的任何和所有元素.如果结果0,则表示没有找到基于规范的元素.然后我让代码执行一个if语句让我知道它没有找到.

这是C#,因此需要进行翻译Java.但不应该太难.

public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User's permission properly hidden");
    }
}
Run Code Online (Sandbox Code Playgroud)

根据您的测试需要,还可以采用另一种方法.

以下代码段正在检查页面上是否存在非常特定的元素.根据元素的存在,我有测试执行if else.

如果元素存在并显示在页面上,我已经console.write让我知道并继续前进.如果有问题的元素存在,我就无法执行我需要的测试,这是需要设置它的主要原因.

如果元素不存在,则不显示在页面上.我在if else执行测试中的else.

IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE"));
//if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement
if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){
    //script to execute if element is found
} else {
    //Test script goes here.
}
Run Code Online (Sandbox Code Playgroud)

我知道我对OP的回应有点迟了.希望这有助于某人!


小智 5

试试这个:调用这个方法并传递3个参数:

  1. WebDriver变量.//假设driver_variable为驱动程序.
  2. 你要检查的元素.应该从By方法提供.// ex:By.id("id")
  3. 时限以秒为单位.

示例:waitForElementPresent(driver,By.id("id"),10);

public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {

        WebElement element; 

        try{
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 

            WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
            element = wait.until(ExpectedConditions.presenceOfElementLocated(by));

            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait
            return element; //return the element
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null; 
    }
Run Code Online (Sandbox Code Playgroud)