【问题标题】:How to check if element contains specific class attribute如何检查元素是否包含特定的类属性
【发布时间】:2015-12-19 04:52:34
【问题描述】:

如何检查 selenium web 元素是否包含特定的 css 类。

我有这个 html li 元素

<li class="list-group-item ng-scope active" ng-repeat="report in lineageController.reports" ng-click="lineageController.activate(report)" ng-class="{active : lineageController.active == report}">

正如您在类属性中看到的,有一个活动类。

我的问题是我有这个元素,我想根据类属性是否具有“活动”值进行检查,这是比使用 xpath 更优雅的解决方案。

我该怎么做?

【问题讨论】:

    标签: java css selenium selenium-webdriver webdriver


    【解决方案1】:

    假设你已经找到了你的元素并且你想在类属性中检查某个类:

    public boolean hasClass(WebElement element) {
        String classes = element.getAttribute("class");
        for (String c : classes.split(" ")) {
            if (c.equals(theClassYouAreSearching)) {
                return true;
            }
        }
        
        return false;
    }
    

    #编辑 正如@aurelius 正确指出的那样,还有一种更简单的方法(效果不太好):

    public boolean elementHasClass(WebElement element, String active) {
        return element.getAttribute("class").contains(active);
    }
    

    这种方法看起来更简单,但有一个很大的警告:

    正如@JuanMendes 所指出的,如果您要搜索的类名是其他类名的子字符串,您将遇到问题:

    例如class="test-a test-b",搜索class.contains("test")会返回true但应该是false

    #编辑 2 尝试结合两个代码sn-ps:

    public boolean elementHasClass(WebElement element, String active) {
        return Arrays.asList(element.getAttribute("class").split(" ")).contains(active);
    }
    

    这应该可以解决您的警告。

    【讨论】:

    • classes.contains("active") 就够了,谢谢!
    • -1 因为编辑不够好,如果你搜索一个类的子字符串,它会给你误报,例如class="test-a test-b",搜索class.contains("test")会返回true,但它应该是假的
    • 更正:当然应该是.getAttribute("class").matches("^classname .*|.* classname .*|.* classname$|^classname$")
    • @drkthng elementHasClass 方法是多余的。
    • Edit 2 没有有效代码。 split 方法返回一个没有 contains 方法的字符串数组。为了执行此操作,您需要先将数组转换为列表。
    【解决方案2】:

    @drkthng 提供的答案有效,但您可能会遇到类名是另一个类名的子集的情况。例如:

    <li class="list-group-item ng-scope active">text</li>
    

    如果您想找到“项目”类,那么提供的答案将给出误报。你可能想尝试这样的事情:

    public boolean hasClass(WebElement element, String htmlClass) {
        String classes = element.getAttribute("class").split("\\s+");
        if (classes != null) {
            for (String classAttr: classes) {
                if (classAttr.equals(htmlClass)) {
                    return true;
                }
            }
        }
        return false;
    }
    

    【讨论】:

      【解决方案3】:

      使用javascript:classList.contains

       WebElement element = By.id("id");
       String className = "hidden";
       JavascriptExecutor js = (JavascriptExecutor) driver;
       Boolean containsClass = js.executeScript("return arguments[0].classList.contains(arguments[1])", element, className);
      

      【讨论】:

        【解决方案4】:

        基于常见的 pre-classList javascript 技术:

        public boolean hasClass(WebElement element, String theClass) {
            return (" " + element.getAttribute("class") + " ").contains(" " + theClass + " ");
        }
        

        【讨论】:

          【解决方案5】:

          与上一个类似,但具有 java 8 功能:

          String classes= getDriver().findElement(someSelector).getAttribute("class");
          Optional<String> classFindResult = Arrays.stream(elementClasses.split(" ")).filter(el -> el.equals("myClass")).findFirst();
          if(openClassFindResult.isPresent()){
              return true;
          }
          return false;
          

          【讨论】:

          • classFindResult 应该检查而不是 openClassFindResult,并且使用三元运算符会更优雅一些。无论如何,你已经得到了我的支持。
          • 我认为您可以使用anyMatch() 方法而不是进行过滤然后检查是否存在。 Arrays.stream(elementClasses.split(" ")).anyMatch(css -&gt; css.equals("myClass"));
          【解决方案6】:

          改进@uesports135 答案,“classess”应该是一个字符串数组。

           public boolean hasClass(WebElement element, String htmlClass) {
                  String[] classes = element.getAttribute("class").split("\\s+");
                  if (classes != null) {
                      for (String classAttr: classes) {
                          if (classAttr.equals(htmlClass)) {
                              return true;
                          }
                      }
                  }
                  return false;
              }
          

          【讨论】:

            【解决方案7】:

            对于任何寻找 C# 实现的人:

            public static class WebElementExtensions
            {
                private static Regex _classNameValidatorRegex = new Regex(@"^[a-z][a-z0-9\-_]*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                private static Regex _whiteSpaceRegex = new Regex(@"\s+");
            
                public static bool HasClass(this IWebElement element, params string[] htmlClasses)
                {
                    if (!htmlClasses.Any())
                        throw new ArgumentException("No html classes to match.");
            
                    if (!htmlClasses.All(c => _classNameValidatorRegex.IsMatch(c)))
                        throw new ArgumentException("Invalid CSS class(es) detected.");
            
                    var classAttribute = element.GetAttribute("class");
                    if (string.IsNullOrWhiteSpace(classAttribute))
                        return false;
            
                    var elementClasses = _whiteSpaceRegex.Split(classAttribute.Trim()).ToHashSet();
            
                    return htmlClasses.All(c => elementClasses.Contains(c));
                }
            
                public static bool HasAnyClass(this IWebElement element, params string[] htmlClasses)
                {
                    if (!htmlClasses.Any())
                        throw new ArgumentException("No html classes to match.");
            
                    if (!htmlClasses.All(c => _classNameValidatorRegex.IsMatch(c)))
                        throw new ArgumentException("Invalid CSS class(es) detected.");
            
                    var classAttribute = element.GetAttribute("class");
                    if (string.IsNullOrWhiteSpace(classAttribute))
                        return false;
            
                    var elementClasses = _whiteSpaceRegex.Split(classAttribute.Trim()).ToHashSet();
            
                    return htmlClasses.Any(c => elementClasses.Contains(c));
                }
            }
            

            【讨论】:

              【解决方案8】:

              尝试使用 contains();

              String classes = divPubli.getAttribute("class");
              assertTrue("The element does not contain .maClass class .publi",classes.contains("maClass"));
              

              【讨论】:

              • 这不是一个正确的解决方案——例如当你在寻找'nav'并且你有'nav-item'类时它不会失败。
              猜你喜欢
              • 2013-07-31
              • 2020-02-09
              • 2020-06-18
              • 2014-11-30
              • 2011-06-23
              • 1970-01-01
              • 2012-02-20
              • 1970-01-01
              • 2019-04-30
              相关资源
              最近更新 更多