test_python
test_python

Reputation: 71

How to read text that is under #shadow-root (user-agent)

I am using Selenium (Python) for automating a web page. I am trying to get text from an input field that is under #shadow-root (user-agent). Xpath I used:

driver.find_element_by_xpath("**//*/p-calendar/span/input**").text

is not returning anything. Attached the screenshot of my DOM element. Requirement: To get text from the shadow root : 01:01

#shadow-root (user-agent)

Upvotes: 3

Views: 6905

Answers (3)

KR Akhil
KR Akhil

Reputation: 1017

If your control is inside Shadow-root (user-agent). You can perform enter text, get value and click by using the Parent of Shadow-root (user-agent).

Example: Considering HTML DOM shared in question.

(Selenium/C# code) - same should work for others as well

//You can use any identifier like id, XPath, tagname, etc
Var element = Driver.FindElement(By.Tagname("input"));
//Text will return null, so use below code
var text = element.GetAttribute("value");
or
element.Click();
or
element.Sendkeys("Etered text");

Upvotes: 0

Alvin Ogwu
Alvin Ogwu

Reputation: 23

You can use driver.execute_script to inject JavaScript code that returns the ShadowRoot then use find_element to get the children element of the shadow root you are looking for.

input_shadow = driver.execute_script('''return document.querySelector("$1").shadowRoot''')
div_text = inputShadow.find_element_by_tag_name("div").text

$1 - Your element's identifier or selector.

If you are keen to using xpath to find elements

input_shadow = driver.execute_script('''return $x(\"//*/p-calendar/span/input\")[0]''')
div_text = inputShadow.find_element_by_tag_name("div").text

Upvotes: 1

undetected Selenium
undetected Selenium

Reputation: 193128

As per @hayatoito's (creator of Shadow DOM) comment:

The original motivation of introducing a closed shadow tree is "Never allow an access to a node in a closed shadow tree, via any APIs, from outside", AFAIK. Like that we can not access a node in the internal hidden shadow tree which is used in <video> element, in Blink.

In fact, I designed a closed shadow tree in such a way. If there is a way to access a node in a closed shadow tree, it should be considered as a bug of the spec.

I think it's totally okay to have an API to allow an access in the layer of Chrome apps or extensions. However, for a normal web app, I think the current agreement is "Never allow it".

If we allowed it, that means we do not need a closed shadow tree. Just having an open shadow tree is enough, I think.

Furhter @Supersharp in his comment below his own answer within the discussion How to get element in user-agent shadow root with JavaScript? mentions:

#shadow-root (user-agent) are browser vendors native implementation so they are not documented and will never be accessible. Only open Shadow DOM are, as per the specs


WebDriver perspective

Recently, @AutomatedTester [David Burns, Chief Bacon Officer, Mozilla Corporation] initiated a discussion on WebDriver - Testability of web components

Currently Selenium Team is open for accepting pull requests for the same.


Reference

You can find a couple of relevant detailed discussions in:


Outro

Here you can find a relevant discussion on How to automate shadow DOM elements using selenium?

Upvotes: 6

Related Questions