Handling Shadow DOM in Selenium – Devstringx

Back to Blog
Handling Shadow DOM

Handling Shadow DOM in Selenium – Devstringx

If there is a shadow element in the webpage we cannot interact directly with selenium code, normally if we locate the element by finding the Element method then it will throw NosuchElement Exception in order to overcome this situation please read the below-mentioned context.

How to Identify Shadow DOM Exists?

The shadow DOM can identify by a shadow root XPath that is enclosed somewhere in the middle of the HTML structure.

Section:  #shadow-root (open) is implemented before the start of every Shadow DOM.

In HTML there can be multiple shadow root sections each section’s shadow properties are completely hidden from the actual Main DOM.

So, we cannot access the shadow elements directly from Main DOM

Handling Shadow DOM Elements

There are two ways to handle/locate shadow elements in selenium by

  1. Using JavaScript Executor
  2. Shadow Libraries by Maven dependency

1) Using JavaScript Executor

Using the JavaScript Executor interface we can execute shadow DOM query scripts in our selenium code by the executeScript method.

SYNTAX:

document.querySelector(selector).shadowRoot.querySelector(shadowSelector)

document- an object of Main DOM that provides access to all HTML elements

shadow root -the object of Shadow DOM that provides access only to Shadow elements

selector-represents CSS selector of the main DOM

shadowSelector -represents the CSS selector of the shadow DOM

Selenium Syntax :

JavascriptExecutor js = (JavascriptExecutor) driver;

js.executeScript(queryScript)

Read Also:- Process Java Script Executor in Selenium Test Automation

Here we are downcasting Javascript Executor with driver reference in order to make the executeScript method available to the current driver reference.

Test Scenario: Automate Clear data function in Chrome browser

  1. Open the Chrome browser
  2. Maximize the browser window
  3. Navigate to the chrome settings page
  4. Click on Privacy and security
  5. Click on Clear browsing data
  6. Click on clear data

Create a class with the name HandleShadowDomByJavascript and paste the below code

public class HandleShadowDomByJavascript {

public static void main(String[] args) {

WebDriverManager.chromedriver().setup();

WebDriver driver= new ChromeDriver();

driver.manage().window().maximize();

driver.get("chrome://settings");

JavascriptExecutor js = (JavascriptExecutor) driver;

String clickPrivacySafetySelector="document.querySelector(\"body > settings-ui\").shadowRoot.querySelector(\"#leftMenu\").shadowRoot.querySelector(\"a[href='/privacy']\").click()";

js.executeScript(clickPrivacySafetySelector);

String clickClearDataSelector="document.querySelector(\"body > settings-ui\").shadowRoot.querySelector(\"#main\").shadowRoot.querySelector(\"settings-basic-page\").shadowRoot.querySelector(\"#basicPage > settings-section:nth-child(9) > settings-privacy-page\").shadowRoot.querySelector(\"#clearBrowsingData\").shadowRoot.querySelector(\"#label\").click()";

js.executeScript(clickClearDataSelector);

String clickCancelSelector="document.querySelector(\"body > settings-ui\").shadowRoot.querySelector(\"#main\").shadowRoot.querySelector(\"settings-basic-page\").shadowRoot.querySelector(\"#basicPage > settings-section:nth-child(9) > settings-privacy-page\").shadowRoot.querySelector(\"settings-clear-browsing-data-dialog\").shadowRoot.querySelector(\"#clearBrowsingDataConfirm\").click()";

js.executeScript(clickCancelSelector);




}

Read Also:- Mobile Test Automation Using Appium Python

2) Shadow Libraries by Maven Dependency

We can access shadow libraries by adding the Maven dependency in our pom.xml file

<dependency>

<groupId>io.github.sukgu</groupId>

<artifactId>automation</artifactId>

<version>0.1.3</version>

</dependency> 

Shadow shadow = new Shadow(driver);

shadow.findElement(cssSelector);

shadow.findElementByXPath(xpath);

1.findElement ->in argument pass css selector

2.findElementByXpath -> in argument pass xpath 

public class HandleShadowDomByShadowLib { 

public static void main(String[] args) {

WebDriverManager.chromedriver().setup();

WebDriver driver= new ChromeDriver();

driver.manage().window().maximize();

driver.get(“chrome://settings”);

Shadow shadow = new Shadow(driver);

shadow.findElementByXPath(“//a[contains(text(),’Privacy and security’)]”).click();

shadow.findElementByXPath(“//div[contains(text(),’Clear browsing data’)]”).click();

shadow.findElementByXPath(“//cr-button[contains(text(),’Clear data’)]”).click();

}

From the above code, the chrome browser opens with a maximized window to navigate to the chrome settings page and it performs clear data actions with the help of Javascript Executor/Shadow Libraries in our test automation script.

FAQ’s

1) Why Are Some Elements Not Accessible With Selenium?

There are a few reasons why some elements may not be accessible with Selenium. The first reason is that the element may be located in a shadow DOM. Shadow DOM is a type of document object model where elements render in a separate tree from the main document. This means that they are not visible to Selenium unless you know how to access them. The second reason is that the element may be dynamically generated, which means it is not present in the HTML source code.

2) Are There Any Drawbacks To Using The Shadow DOM?

First, it’s currently only available as an experimental feature in Firefox. That’s why if you plan on writing code to work with any other browsers besides Firefox, then the shadow DOM selenium may not be appropriate for your project.

Second, since it’s still experimental and not yet widely adopted by browser vendors, there are some rendering differences between browsers that could affect your design if you use CSS selectors or JavaScript APIs specific to the shadow DOM.

If you are interested in even more software testing-related articles and information from us here at Devstringx, then we have a lot to choose from.

Share this post

Back to Blog