Accessing elements inside ShadowDom

Hi, I have a Python code to navigate through the ShadowDom but I don’t know how to code it in Robotframework. I got the first Shadow root element, but facing error in executing Javascript.

Python code :

def expand_shadow_element():
    # return a list of elements
    shadowRoot = driver.find_element(By.CSS_SELECTOR, "camos-html5client")
    shadowRoot = driver.execute_script('return arguments[0].shadowRoot', shadowRoot)
    executableShadow = shadowRoot.find_element(By.CSS_SELECTOR, "div#CHCArena")
    return executableShadow

Robotframework code :

Expand Shadow Element
    ${shadowRoot}=    Get WebElement     css=camos-html5client
    ${shadowRoot}=    Execute Javascript    return arguments[0].shadowRoot    ${shadowRoot}
    ${executableShadow}=    Get WebElement     css=div#CHCArena    ${shadowRoot}
    [Return]    ${executableShadow}

1 Like

One question:
Do you really need to use SeleniumLibrary?

Because Selenium 4 itself is bad with shadowDom and just the basic support for it and SeleniumLibrary has no features to support ShadowDom/WebComponents except of dom selector which is basically js.

Answer for ShadowRoot / ShadowDom / WebComponent automation is the playwright based Browser library.

1 Like

what you can do with the dom selector:

Click Element    dom:document.querySelector("camos-html5client").shadowRoot.querySelector("div#CHCArena")
1 Like

Hi @René, thanks for the code to select the shadow root element. It is working fine.

I want to access further the shadow dom elements using xpath

executableShadow = expand_shadow_element()
page_loaded = WebDriverWait(driver, 120).until(EC.element_to_be_clickable(executableShadow.find_element(By.XPATH, ".//*[@data-ctcwgtname = SelPlatform']/button")))
executableShadow.find_element(By.XPATH, ".//*[@data-ctcwgtname = 'SelPlatform']/button").click()

@René Any help on this?

Hi ramya, I have tried like this:
Use Shadow Path generator chrome extension and get the string value and by using js executor, click on the shadow dom and enter into it. see the reference code below:

JavascriptExecutor Skilljs = (JavascriptExecutor) driver;
String SkillsqueryString = “return document.querySelector(‘records-related-list-lwc-detail-panel-wrapper’).shadowRoot.querySelector(‘records-lwc-detail-panel’).” +
“shadowRoot.querySelector(‘records-base-record-form’).shadowRoot.querySelector(‘div.record-layout-container’)”;
WebElement SkillsshadowElement = (WebElement) ((JavascriptExecutor) driver).executeScript(SkillsqueryString);
SkillsshadowElement.click();

then start locating the element. it will work

Thank you,
Sid

Hi Sid,
I am still not able to click the element, could you please help me out in RobotFramework

Library SeleniumLibrary

Click Element document.querySelector(“#LauncherButton”)

Click Element dom:document.querySelector(“body>unblu-floating-app”).shadowRoot.querySelector(“button[id=‘LauncherButton’]”)

Execute Javascript document.querySelector(“body>unblu-floating-app”).shadowRoot.querySelector(“button[id=‘LauncherButton’]”).click()

:red_exclamation_mark:Important:

  • FlaUILibrary cannot access shadow DOM directly, because it operates at the UI automation level (Windows native UI), not inside the browser’s HTML DOM.
  • Shadow DOM access must be handled via SeleniumLibrary (or Playwright) in Robot Framework, because these libraries can interact with web elements inside shadow DOMs.

this is with Python add it as a wrapper and use it in Robot Framework

tests/
├── shadow_test.robot
├── ShadowKeywords.py

from selenium.webdriver.common.by import By

class ShadowKeywords:
def click_deny_in_shadow(self, driver):
shadow_host = driver.find_element(By.CSS_SELECTOR, “#usercentrics-cmp-ui”)
shadow_root = shadow_host.shadow_root
deny_button = shadow_root.find_element(By.CSS_SELECTOR, “#deny”)
deny_button.click()

the other one handled via SeleniumLibrary.

This is for new browser
*** Test Cases ***
Click Deny Using JavaScript
Open Browser https://example.com Chrome
Execute JavaScript return document.querySelector(‘#usercentrics-cmp-ui’).shadowRoot.querySelector(‘#deny’).click();
Execute JavaScript ${script}

the below is for new Tab in a existing open browser
Open Url In New Tab And Wait
Execute JavaScript window.open(‘${New_Tab URL}’, ‘_blank’) # if new tab not open already this will open a new tab
Sleep 1s
Switch Window title=New_Tab Title name # Find in the Elements on clicking inspect take title tag
Sleep 2s
Execute javascript return document.querySelector(‘"IFrame id or tag that have the shadow Root encloed’).shadowRoot.querySelector('Button ID only CSS Selector id can be used ').click();
Sleep 2s

To Find Shadow DomElements use Only CSS in selector Hub inside Elements section.

Hope this is clear and helpful