关于java:Selenium WebDriver – 测试元素是否存在

Selenium WebDriver - Test if element is present

有没有一种方法可以测试元素是否存在?任何findelement方法都将以异常结束,但这不是我想要的,因为它可能是一个元素不存在,这是正常的,这不是测试的失败,因此异常不能是解决方案。

我发现了这篇文章:Selenium C WebDriver:等待元素出现但这是给C的,我不太擅长。有人能把代码翻译成Java吗?对不起,伙计们,我在Eclipse中试用过,但是我没有把它放进Java代码中。

这是代码:

1
2
3
4
5
6
7
8
9
10
11
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);
    }
}


findElements代替findElement

如果没有找到匹配的元素而不是异常,findElements将返回空列表。

要检查元素是否存在,可以尝试此操作

1
Boolean isPresent = driver.findElements(By.yourLocator).size() > 0

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


对于一个只查找元素并确定其是否存在的私有方法,该如何处理:

1
2
3
4
5
6
7
8
private boolean existsElement(String id) {
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        return false;
    }
    return true;
}

这很容易,而且能完成任务。

编辑:你甚至可以更进一步,以By elementLocator作为参数,如果你想通过id以外的东西找到元素,就可以消除问题。


我发现这对于Java是有效的:

1
2
3
WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);


1
2
3
4
5
6
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);
}

我也有同样的问题。对于我来说,根据用户的权限级别,某些链接、按钮和其他元素将不会显示在页面上。我的套件的一部分是测试应该缺失的元素是否缺失。我花了好几个小时想弄清楚。我终于找到了完美的解决方案。

它的作用是告诉浏览器查找基于指定的任何和所有元素。如果结果是0,这意味着没有找到基于规范的元素。然后让代码执行一个if语句,让我知道没有找到它。

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

1
2
3
4
5
6
7
8
public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User's permission properly hidden");
    }
}

根据您的测试需要,您还可以选择其他路径。

下面的代码片段检查页面上是否存在非常具体的元素。根据元素的存在,我让测试执行if-else。

如果元素存在并显示在页面上,我会让console.write通知我并继续。如果有问题的元素存在,我就不能执行我需要的测试,这是需要设置这个元素的主要原因。

如果元素不存在,并且不显示在页面上。我在if-else中有else执行测试。

1
2
3
4
5
6
7
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.
}

我知道我对手术的反应有点晚了。希望这能帮助到别人!


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

  • WebDriver变量。//假设驱动程序变量为驱动程序。
  • 要检查的元素。应通过方法提供。//ex:by.id("id")。
  • 时间限制(秒)。
  • 示例:waitForelementPresent(driver,by.id("id"),10);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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;
        }


    用Java编写以下函数/方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    protected boolean isElementPresent(By by){
            try{
                driver.findElement(by);
                return true;
            }
            catch(NoSuchElementException e){
                return false;
            }
        }

    在断言期间使用适当的参数调用方法。


    通过在try catch语句之前缩短selenium超时,可以使代码运行得更快。

    我使用以下代码检查元素是否存在。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    protected boolean isElementPresent(By selector) {
        selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
        logger.debug("Is element present"+selector);
        boolean returnVal = true;
        try{
            selenium.findElement(selector);
        } catch (NoSuchElementException e){
            returnVal = false;
        } finally {
            selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
        }
        return returnVal;
    }


    如果您在Ruby中使用rspec webdriver,那么可以使用这个脚本,假定一个元素确实不应该存在,并且它是一个通过的测试。

    首先,从类rb文件中首先编写这个方法

    1
    2
    3
    4
    5
    6
    7
    8
    class Test
     def element_present?
        begin
            browser.find_element(:name,"this_element_id".displayed?
            rescue Selenium::WebDriver::Error::NoSuchElementError
                puts"this element should not be present"
            end
     end

    然后,在规范文件中,调用该方法。

    1
    2
    3
    4
    5
      before(:all) do    
        @Test= Test.new(@browser)
      end

     @Test.element_present?.should == nil

    如果元素不存在,规范将通过,但是如果元素存在,它将抛出一个错误,测试失败。


    这对我很有用:

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


    我在Java中发现的最简单的方法是:

    1
    2
    3
    List<WebElement> linkSearch=  driver.findElements(By.id("linkTag"));
    int checkLink=linkSearch.size();
    if(checkLink!=0){  //do something you want}


    要找到某个特定元素是否存在,我们必须使用findElements()方法而不是findElement()。

    1
    2
    3
    4
    5
    int i=driver.findElements(By.xpath(".......")).size();
    if(i=0)
    System.out.println("Element is not present");
    else
    System.out.println("Element is present");

    这对我有用……如果我错了,建议我……


    您可以尝试隐式等待:

    1
    2
    3
    4
    WebDriver driver = new FirefoxDriver();
    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
    driver.Url ="http://somedomain/url_that_delays_loading";
    IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

    `

    或者您可以尝试显式等待一个:`

    1
    2
    3
    4
    5
    6
    7
    IWebDriver driver = new FirefoxDriver();
    driver.Url ="http://somedomain/url_that_delays_loading";
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
        {
            return d.FindElement(By.Id("someDynamicElement"));
        });

    `

    explicit将在某些操作之前检查元素是否存在。隐式等待可以在代码的每个位置调用。例如,在一些Ajax操作之后。

    更多信息请访问Seleniumhq页面


    给出我的代码片段。因此,下面的方法检查页面上是否存在随机的web元素"创建新应用程序"按钮。请注意,我使用的等待时间是0秒。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public boolean isCreateNewApplicationButtonVisible(){
        WebDriverWait zeroWait = new WebDriverWait(driver, 0);
        ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']"));
        try {
            zeroWait.until(c);
            logger.debug("Create New Application button is visible");
            return true;
        } catch (TimeoutException e) {
            logger.debug("Create New Application button is not visible");
            return false;
        }
    }

    我会使用Scala(旧代码)好的"Java 5月8日与此类似的代码":

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    object SeleniumFacade {

      def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = {
        val elements = maybeParent match {
          case Some(parent) => parent.findElements(bySelector).asScala
          case None => driver.findElements(bySelector).asScala
        }
        if (elements.nonEmpty) {
          Try { Some(elements(withIndex)) } getOrElse None
        } else None
      }
      ...
    }

    那么,

    1
    val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement))

    应该这样做:

    1
    2
    3
    4
    5
    6
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        //do what you need here if you were expecting
        //the element wouldn't exist
    }


    1
    2
    3
    public boolean isElementDisplayed() {
            return !driver.findElements(By.xpath("...")).isEmpty();
        }

    就我个人而言,我总是选择上述答案的混合,并创建一个使用size()<0建议的可重用静态实用程序方法:

    1
    2
    3
    4
    5
    6
    public Class Utility {
       ...
       public static boolean isElementExist(WebDriver driver, By by) {
          return driver.findElements(by).size() < 0;
       ...
    }

    这是整洁,可重复使用,可维护…所有的好东西;—)