How to check if element contains specific class attribute

71,158

Solution 1

Given you already found your element and you want to check for a certain class inside the class-attribute:

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

#EDIT As @aurelius rightly pointed out, there is an even simpler way (that doesn't work very well):

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

This approach looks simpler but has one big caveat:

As pointed out by @JuanMendes you will run into problems if the class-name you're searching for is a substring of other class-names:

for example class="test-a test-b", searching for class.contains("test") will return true but it should be false

#EDIT 2 Try combining the two code snippets:

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

That should fix your caveat.

Solution 2

The answer provided by @drkthng works but you might have a case where the class name is a subset of another class name. For example:

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

If you wanted to find the class "item" then the provided answer would give a false positive. You might want to try something like this:

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

Solution 3

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

Solution 4

Based on a common pre-classList javascript technique:

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

Solution 5

Improving on @uesports135 answer, "classess" should be a String array.

 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;
    }
Share:
71,158
aurelius
Author by

aurelius

Updated on January 23, 2022

Comments

  • aurelius
    aurelius over 2 years

    How can I check if a selenium web element contains a specific css class.

    I have this html li element

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

    As you can see inside class attribute there is an active class.

    My problem is that I have this element and I want to do a check based on if the class attribute has that "active" value among the others, being more elegant solution then using xpath.

    How can I do this?

  • aurelius
    aurelius over 8 years
    classes.contains("active") is enough, thanks for this!
  • Ruan Mendes
    Ruan Mendes over 6 years
    -1 because the edit is not good enough, it will give you false positives if you search for a substring of a class, for example class="test-a test-b", searching for class.contains("test") will return true but it should be false
  • Krystian
    Krystian over 6 years
    This is not a correct solution- for example it will not fail when you are looking for 'nav' and you have 'nav-item' class.
  • aurelius
    aurelius over 6 years
    classFindResult should be checked not openClassFindResult, and would be a bit more elegant to use the ternary operator. Anyways, you already have my upvote.
  • GKalnytskyi
    GKalnytskyi almost 6 years
    I think you can use anyMatch() method instead of doing filtering and then checking if any exists. Arrays.stream(elementClasses.split(" ")).anyMatch(css -> css.equals("myClass"));
  • aurelius
    aurelius over 5 years
    it depends on the case, variations of css class names. If you know the a certain class name will not have these name clashes, it works just fine.
  • PixelMaster
    PixelMaster almost 5 years
    instead of "contains", how about using .getAttribute("class").matches("^classname | classname | classname$")? That should fix the issue of name subsets.
  • PixelMaster
    PixelMaster almost 5 years
    correction: it should of course be .getAttribute("class").matches("^classname .*|.* classname .*|.* classname$|^classname$")
  • John R Perry
    John R Perry over 4 years
    @drkthng the elementHasClass method is suuuuuuper redundant.
  • Christopher Coleman
    Christopher Coleman over 4 years
    Edit 2 does not have valid code. The split method returns a string array which does not have the contains method. In order to perform that you will need to first convert the array to a list.
  • Shai Alon
    Shai Alon almost 4 years
    EDIT 2 should be like: public boolean elementHasClass(WebElement element, String active) { return element.getAttribute("class").contains(active); }