Get element text behind shadow DOM element using Playwright

Question:

I am trying to use Playwright to get contents of the open shadow root element which looks like this.

<some-element>
  #shadow-root
  ABC
</some-element>

Here #shadow-root contains text ABC without any additional tags.

I am able to locate some-element but I cannot find a way to get the contents of #shadow-root

Example Python code I am using is below:

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.firefox.launch(args=["--disable-gpu"], headless=False)
    page = browser.new_page()
    page.goto("https://www.sample.com")
    some_element = page.locator('some-element')
    ...
    # ???

Playwright docs state that their selectors can choose elements in shadow DOM, but examples contain only options where shadow-root contains other tags.

How do I get the contents of #shadow-root if it only contains the text, without any tags ?

Asked By: Termos

||

Answers:

I tried with a demo page which have the same behavior than your page has: https://googlechromelabs.github.io/shadow-selection-polyfill/demo.html

enter image description here

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.launch(args=["--disable-gpu"], headless=False)
    page = browser.new_page()
    page.goto("https://googlechromelabs.github.io/shadow-selection-polyfill/demo.html")
    print(page.evaluate("document.querySelector('#host1').shadowRoot.childNodes[0].data"))
Answered By: Jaky Ruby

The locator will help you find an element. But from there, if you don’t have an element to pierce the Shadow DOM, you might need to do that manually.

text = page.locator('some-element').first.evaluate("node => node.shadowRoot.innerHTML")
Answered By: hardkoded