Selenium: Determining the effective background color

Pavel Polívka - Sep 22 '20 - - Dev Community

Recently I did some Selenium test bugfixes (basically trying to solve problems QA engineers were lost at). One of the problems was trying to determine effective background color of a div.

Let’s see this example html

<!DOCTYPE html>
<html lang="en">
<head>
    ...
</head>
<body style="background-color: black;">
    <div id="myDiv" style="color: white;">DEV.TO</div>
</body>
</html>

My goal was to get the background color of #myDiv.

The obvious solution what I tried was getting the css property background color from that element.

WebElement element = driver.findElement(By.cssSelector("#myDiv"));
element.getCssValue("background-color");

This gets me rgba(0, 0, 0, 0) instead of the expected black.

I googled a bit and found an solution that should compute effective property via JavaScript. It looked like this.

WebElement elemement = driver.findElement(By.cssSelector("#myDiv"));
String computedStylePropertyScript = "return window.document.defaultView"
                 + ".getComputedStyle(arguments[0],null).getPropertyValue(arguments[1]);";
((JavascriptExecutor) driver).executeScript(computedStylePropertyScript, elem, "background-color");

Still gets rgba(0, 0, 0, 0).

Why is that?

I googled a lot more and find out that modern browsers treat rgba(0, 0, 0, 0) as transparent color and will mark as effective one.

Not good for me.
So, my solutions need to be to go in, find parent div and check color of that. If it’s still transparent go deeper. To make this not infinite loop let’s end on body tag. If we find no color until that, there is probably no color specified.

My code looks like this.

private String getBGColor(WebElement elementToSearch) {
    WebElement current = elementToSearch;
    while(isTransparent(current.getCssValue("background-color"))) {
        if (current.getTagName().equals("body")) {
            return null;
        }
        // Find Parent
        current = current.findElement(By.xpath("./.."));
    }
    return current.getCssValue("background-color");
}

private boolean isTransparent(String color) {
    String colorMod = color.replaceAll("\\s+","").toLowerCase();
    return Arrays.asList("transparent","","rgba(0,0,0,0)").contains(colorMod);
}

You can call it like this.

WebElement element = driver.findElement(By.cssSelector("#myDiv"));
getBGColor(element);

And it works, it gives you the correct black color.

But. There are always some buts. It’s naïve implementation, if you have absolutely positioned elements (your element is not rendered in the parent div) this will break down.


If this is interesting to you, you can follow me on Twitter.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .