How to Get the Style Attribute of an Element

Hi
I want to get the Style property of the highlighted element. But the result returned is null.

This is the result

I tried with javascript also

String js1 = “return document.querySelector(‘TC_06_/div_add_5fae2920d068b224134037e8’).style.background-image”
String top = WebUI.executeJavaScript(js1, null)

There I got the error
Caused by: org.openqa.selenium.InvalidElementStateException: invalid element state: Failed to execute ‘querySelector’ on ‘Document’: ‘TC_06_/div_add_5fae2920d068b224134037e8’ is not a valid selector.

Please help me to resolve this

Are you aware what this symbol means?

It is the name of a “Test Object”, which is an entry in the “Object Repository” folder. You have created it somehow. Are you aware of it?

You can review the definition of that “Test Object” by selecting that entry in Katalon GUI. The definition must have a “locator” defined. The locator would be a CSS Selector expression, or an XPath expression.

Most likely the locator of the Test Object is defined wrongly; it does not point to a HTML element in the target HTML.

You should check if the validity of the locator using Chrome DevTools.

image

You’re trying to subtract the undefined variable image from the style.background property.

Try this:

 ... style.backgroundImage

Hi @Russ_Thomas and @kazurayam
Thanks for the suggestions
I tried the following :

WebUI.verifyElementHasAttribute(findTestObject(‘TC_06_/div_add_5fae2920d068b224134037e8’), ‘style’, 0)
WebElement subimage= driver.findElement(By.xpath("//*[@class = ‘sub-head-image ng-star-inserted’ and @id = ‘5fae2920d068b224134037e8’]"))
String js1 = “return document.querySelector(’#5fae2920d068b224134037e8’).style.backgroundImage;”
String imagestyle = WebUI.executeJavaScript(js1, null)

This gives me the result
Caused by: org.openqa.selenium.InvalidElementStateException: invalid element state: Failed to execute ‘querySelector’ on ‘Document’: ‘#5fae2920d068b224134037e8’ is not a valid selector.

I just tried this too, Instead of element id, I used the classname as #sub-head-image ng-star-inserted

Which gave the result: Caused by: org.openqa.selenium.JavascriptException: javascript error: Cannot read properties of null (reading ‘style’)

Please help me to find out what I am doing wrong.Thanks

I’m surprised by selenium issuing an InvalidElementStateException (heads up, @Brandon_Hein, @kazurayam @ThanhTo) since what is happening is actually caused by a browser failure – specifically, failing to follow the published standard.

Your ID starts with a numeric/digit/number - which is perfectly legal in HTML 5. However, in Chrome and Firefox (at least) IDs with initial numerics are treated as invalid selectors:

#Chrome

#Firefox

https://html.spec.whatwg.org/multipage/dom.html#global-attributes:the-id-attribute-2

What you might need to do from here is to find another way to target that element while avoiding use of the ID (since it starts with a numeric character).

Just as an afterthought, what is the doctype of the HTML document? (It should be the very first “processing instruction” at the top of the document.)

<!DOCTYPE html>

You can also try using xpath, but still providing that ID. I think it will work fine:

//div[@id='5fae2920d068b224134037e8']

Try updating your Test Object with that locator.

As I suspected – an HTML 5 doctype. You should NOT be getting this problem, but selenium is stuck with the browsers’ erroneous handling of that selector.

But do try Brandon’s suggestion - it might sneak past the gatekeeper :wink:

I tried the following:
imagess = WebUI.getAttribute(findTestObject(‘TC_06_/div_add_5fae2920d068b224134037e8’), ‘style’)
System.out.println(imagess)

with the xpath //div[@id=‘5fae2920d068b224134037e8’] in the Locator
But the Result is "Attribute ‘style’ of object ‘Object Repository/TC_06_/div_add_5fae2920d068b224134037e8’ is: ‘’ "

There is no value returned

The style attribute is an OBJECT – a collection of CSS style properties. Printing it, I believe, is not possible.

Use Brandon’s code to access the element, then go back to your original test requirement (Which I assume is not to print the style property).

OK. I will Try That . Thank You

Regarding an ID that starts with a digit, I found an interesting post

Can I have a div with id as number?
Yes, you can.
id values that consist solely of digits are perfectly valid in HTML; anything but a space is okay. And although earlier HTML specs were more restrictive (ref, ref), requiring a small set of chars and starting with a letter, browsers never cared, which is a big part of why the HTML5 specification opens things up.
If you’re going to use those id s with CSS selectors (e.g, style them with CSS, or locate them with querySelector , querySelectorAll , or a library like jQuery that uses CSS selectors), be aware that it can be a pain, because you can’t use an id starting with a digit in a CSS id selector literally ; you have to escape it. (For instance, #12 is an invalid CSS selector; you have to write it #\31\32 .) For that reason, it’s simpler to start it with a letter if you’re going to use it with CSS selectors.

As for HTML5 spec, yes, an ID can start with a digit. However, the CSS Selector specification doesn’t literally accept it.

I (kazurayam) was surprised with this discrepancy in the w3c standard specs! Our pain is due to the CSS spec. Our pain is not due to browsers, nor to Selenium, nor to Katalon Studio.


Here I will show you some experiments that I have done. Please download the following 2 HTML files and open them with Chrome. Please check the console logs in the JavaScript Console.

  1. fixture_easy.html (1.8 KB)

  2. fixture_painful.html (2.0 KB)

The fixture_easy.html has code like this:

<!DOCTYPE html>
<html lang="en">
    ....
    <body>

        <div class='sub-head-image ng-star-inserted' id="fae2920d068b224134037e8" style="background-image: url('https://foo.bar.com/Eggs_Benedict-01-cropped_1610015415453')">ID that starts with a letter is easy.</div>
        ....
        <script>
         window.onload = function() {
             console.log("Hello");
             console.log(document.querySelector("#fae2920d068b224134037e8")
                                     .style.backgroundImage);
         }

Please note the ID is fae2920d068b224134037e8, which does NOT start with a digit.
In the Console, you would see the following output.

Hello
fixture_easy.html:30 url("https://foo.bar.com/Eggs_Benedict-01-cropped_1610015415453")

ID that start with a letter is easy.

On the other hand, “fixture_painful.html” goes like this:

<!DOCTYPE html>
<html lang="en">
    ....
    <body>
        <div class='sub-head-image ng-star-inserted' id="5fae2920d068b224134037e8" style="background-image: url('https://foo.bar.com/Eggs_Benedict-01-cropped_1610015415453')">ID that starts with a digit is a pain.</div>
        ....
        <script>
         window.onload = function() {
             console.log("by getElementById: " +   document.getElementById("5fae2920d068b224134037e8").style.backgroundImage);
             console.log("by querySelector: " + document.querySelector("#\\35fae2920d068b224134037e8").style.backgroundImage);
         }
        </script>
    </body>
</html>

Please note the ID is 5fae2920d068b224134037e8, that starts with a digit 5.

When I loaded this HTML on browser, I saw the following logs in the JavaScript Console.

by getElementById: url("https://foo.bar.com/Eggs_Benedict-01-cropped_1610015415453") fixture_painful.html:30 
Uncaught TypeError: Cannot read properties of null (reading 'style') at window.onload (fixture_painful.html:30)

According to the stackoverflow post, escaping the starting 5 to \\35 should make querySelector() happy. But actually the following code returned null:

document.querySelector("#\\35fae2920d068b224134037e8")

I could not resolve it. Finally I gave up.


My Conclusion:

In the case where ID in a HTML can starts with a digit, we shouldn’t use CSS Selector.

Me too - great detective work Kaz!

:male_detective:

Another point for XPATHERS!!! Sticking it to those filthy CSSers! High five!!! :raised_hand_with_fingers_splayed:

On a serious note, while I’m confident the xpath locator will work fine, I’m less so on getting the style attribute using WebUI keywords. Here’s how you could do it using some Selenium, at least:

WebElement element = WebUiCommonHelper.findWebElement(findTestObject('path/to/object'), 30);
String style = element.getAttribute("style");

This should return the entire style attribute value as a string, none of that Object nonsense…

1 Like

Never let it be said that I never let it be said. :nerd_face:

1 Like