5

I currently have an automation tool built using Python. Currently, the tool serves the custom application my company has built on Salesforce. Salesforce released a Winter 2020 version, and implemented the Shadow DOM and being unable to locate elements through the Shadow DOM with javascript or the normal CSS selectors in Selenium. I cannot use Firefox (ignores the Shadow DOM which is one solution, but not preferred) because the RAM usage over the time of testing increases and maxes out. I would like to stick to google chrome and selenium, but I need to find a way to locate elements through the Shadow DOM.

Does anyone have any experience with this? I know the /deep/ has been deprecated, so any other information would greatly help.

Thanks ahead of time.

EDIT

JQuery locates elements

enter image description here

In normal Google Chrome, I can query for the element just fine.

In the browser for selenium, the element returns null?? This doesn't make sense

EDIT 2

I learned that JQuery is not loaded into the browser, but instead, is an alias for document.queryselector. If that is the case, why is it pulling the element in the shadow dom if it's just an alias and document.querySelector returns null?

Found the article here

1
  • The fix for this is to use Firefox, but Firefox is not as fast as Chrome. Still open to any suggestions! Commented Oct 8, 2019 at 16:51

3 Answers 3

2

When we try to find Shadow DOM elements using selenium locators, it will throw 'NoSuchElementException'. To access these Shadow DOM elements, we need to use JavascriptExecutor executeScript() function. If you look at the DOM structure, every element that has ShadowDOM also has a shadowRoot property which describes the underlying elements.

public WebElement expandRootElement(WebElement element) {
    WebElement ele = (WebElement) ((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", element);
    return ele;
}
...
.
...
WebElement root1 = driver.findElement(By.tagName(<some tag name>));
//Get shadow root element
WebElement shadowRoot1 = expandRootElement(root1);
WebElement actualHeading = root1.findElement(By.cssSelector(<Some Selector>));

See if this worksout for you

1

That is why I shifted to webdriver.io instead of selenium java/.net.There you can chain a selector with a shadowroot selector, preventing to write a javascript for the shadowroot.

//click on salutation via shadow dom

const selecttext = $("[class*=salutation]").shadow$("[class$=select")

selecttext.click()

    SalesforceLogin.pauseLong()
    //select radio button
    const selectradiomr = $('[title$="Mrs."]')
    selectradiomr.click()

//then I select the value with a standard css selector

0

You should be able to use the JavaScript executor to grap the shadowRoot node. From there you can search within.

Read this article: https://medium.com/rate-engineering/a-guide-to-working-with-shadow-dom-using-selenium-b124992559f

The article is in JavaScript, but driver.execute_script should work in python.

1
  • I am aware of this, but the issue is that in Salesforce, the elements that use the shadow dom, the tags are not unique. I need a global search and element locator of particular values. I can query for the items no problem in my regular browser, but in the chrome webdriver, nothing is returned. -currently uploading the pictures to the post to demonstrate- Commented Sep 30, 2019 at 22:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.