4

I have the following typical shadow dom html code:

<input is="text-input" class="input-element style-scope paper-input" 
autocomplete="off" placeholder="" autocapitalize="none" autocorrect="off" 
aria-describedby="" aria-labelledby="paper-input-label-22" id="input-22" 
tabindex="0">
   #shadow-root (user-agent)
   <div id="inner-editor">test</div>
</input>

I am using Selenium to try to get the text inside the of the shadow root, but it always returns null, I know the differences between open vs closed shadow DOM, and the open version of Shadow dom always displays as #shadow-root (open) in my Devtool, so I am wondering how can I tell if this user-agent shadow dom is open or closed?

Edit: I am using JS and my code look like this:

driver.executeScript("return 
    arguments[0].shadowRoot",driver.findElement(webdriver.By.css("#input-
    22"))).then(function(text) { text.getText()});

text come back as null.

Eduard Florinescu
  • 16,747
  • 28
  • 113
  • 179
Harvey Lin
  • 724
  • 11
  • 25
  • Do you have a public example of this that you can link? I'd like to try some things out. – JeffC Jan 25 '18 at 21:29
  • I don't, this is part of a project that I am working on to write tests with. I would access shadow-root that is marked as (open) with no problem, but with the (user-agent) ones they always come back as null, which makes me think they are closed shadow DOMs. – Harvey Lin Jan 25 '18 at 23:06
  • Understood... do you know of any public/example pages that might be formatted like this that we can see? – JeffC Jan 25 '18 at 23:10
  • 1
    Maybe this page is relevant: https://stackoverflow.com/questions/38701803/how-to-get-element-in-shadow-root-with-javascript – Harvey Lin Jan 25 '18 at 23:18
  • Yes it's relevant. User-agent shadow dom are somewhat closed... sorry! – Supersharp Jan 25 '18 at 23:44
  • What language are you using? Java? You haven't posted any code. – JeffC Jan 26 '18 at 00:26
  • What happens if you do something like `driver.findElement(By.id("input-22")).getAttribute("innerHTML")`? Does it dump the shadow-root elements, etc. then? – JeffC Jan 26 '18 at 00:27
  • 1
    I am using JS. When I tried to use that kind of code, it returns null, which is why I was suspecting it is a closed kind of shadow DOM vs open, which I also tested on and it works. So user-agent shadow DOMs are created by the browser itself and can not be accessed at this time. – Harvey Lin Jan 26 '18 at 00:37
  • The DOM within a `#shadow-root (user-agent)` is generated by the browser itself and is not accessible compared to a `#shadow-root ` which is via `shadowRoot`. Note that the text from the `
    ` is accessible via the `value` property from the ``. Thus to get the text: `driver.findElement(By.css("#input-22")).getAttribute("value")`.
    – Florent B. Jan 26 '18 at 03:00
  • @JeffC When I did that it returned null – Harvey Lin Jan 26 '18 at 18:40
  • @FlorentB. it works! Thanks! – Harvey Lin Jan 26 '18 at 18:51

2 Answers2

4

As per @FlorentB. suggests,

driver.findElement(By.css("#input-22")).getAttribute("value"‌​) 

will return the text value of the user agent shadow root.

Harvey Lin
  • 724
  • 11
  • 25
1

You can tell by seeing if the innerHTML of the root element is empty or not, see this example

import selenium
from selenium import webdriver
driver = webdriver.Chrome()
from bs4 import BeautifulSoup


def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

driver.get("chrome://settings")
root1 = driver.find_element_by_tag_name('settings-ui')

html_of_interest=driver.execute_script('return arguments[0].innerHTML',root1)
sel_soup=BeautifulSoup(html_of_interest, 'html.parser')
sel_soup# empty root not expande

shadow_root1 = expand_shadow_element(root1)

html_of_interest=driver.execute_script('return arguments[0].innerHTML',shadow_root1)
sel_soup=BeautifulSoup(html_of_interest, 'html.parser')
sel_soup

enter image description here

Eduard Florinescu
  • 16,747
  • 28
  • 113
  • 179