Introduction
Modern web applications often use Shadow DOM to keep parts of the webpage separate from the rest of the document. This helps in creating reusable components, but it also makes it difficult for Selenium WebDriver to access elements inside the Shadow DOM. In this blog, we'll explore what Shadow DOM is, why it's used, and how to handle it in Selenium WebDriver.
What is Shadow DOM
The Shadow DOM is a way to create a separate, hidden section of the DOM inside a web page. It's like a mini DOM tree attached to an element, which keeps its structure and styles isolated from the rest of the page. This helps developers build reusable web components without worrying about outside styles or scripts affecting them.
Challenges in Handling Shadow DOM with Selenium WebDriver
Selenium WebDriver typically interacts with the visible DOM. However, elements inside a Shadow DOM are not directly accessible through standard methods like driver.findElement()
. This leads to exceptions like NoSuchElementException
.
Common issues faced:
1. Elements within Shadow DOM are not accessible via regular Selenium locators.
2. Traditional JavaScript executions fail to traverse through the Shadow DOM.
Step 3: Chaining Through Multiple Shadow Roots (Nested Shadow DOMs)Sometimes, Shadow DOM can be nested. In such cases, you need to chain through multiple shadow hosts.
Code Example for Nested Shadow DOMs:
Steps to Handle Shadow DOM in Selenium WebDriver
To interact with elements inside the Shadow DOM, we need to use JavaScript execution.
Step 1. Understand the Structure
Before interacting with elements inside the Shadow DOM, open the browser’s developer tools (F12) or right on the page and inspect the DOM structure. Look for the #Shadow-root tag to find where the Shadow DOM starts and identify the element you need.

Step 2: Using JavaScriptExecutor to Access Shadow DOM
Since Selenium WebDriver doesn't provide direct APIs to handle Shadow DOM, you'll need to use JavaScript execution to interact with elements inside the Shadow DOM.
// Get the shadow host element
WebElement shadowBtnSubmit = driver.findElement(By.cssSelector("Enter Your CSS selector"));
// Use JavaScriptExecutor to access the shadow root
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
WebElement shadowRoot = (WebElement) jsExecutor.executeScript("return arguments[0].shadowRoot", shadowBtnSubmit );
// Now find the element inside the shadow DOM
WebElement elementInsideShadowDOM = shadowRoot.findElement(By.cssSelector("Enter Your CSS selector"));
// Perform action on the element
elementInsideShadowDOM.click();
Step 3: Chaining Through Multiple Shadow Roots (Nested Shadow DOMs)
Sometimes, Shadow DOM can be nested. In such cases, you need to chain through multiple shadow hosts.
Code Example for Nested Shadow DOMs:
// Get the first shadow host
WebElement shadowBtnLogin = driver.findElement(By.cssSelector("Enter Your Css selector"));
// Use JavaScriptExecutor to access the shadow root
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
WebElement shadowRootLgin = (WebElement) jsExecutor.executeScript("return arguments[0].shadowRoot", shadowBtnLogin);
// Get the second shadow host inside the first shadow DOM
WebElement shadowLoginOut = shadowRootLgin.findElement(By.cssSelector("shadow-host2-css-selector"));
WebElement shadowRootLogOut = (WebElement) jsExecutor.executeScript("return arguments[0].shadowRoot", shadowLoginOut);
// Now find the element inside the nested shadow DOM
WebElement nestedElement = shadowRootLogOut.findElement(By.cssSelector("Enter Your Css selector"));
// Perform action on the element
nestedElement.click();
Steps to Use XPath with Shadow-Dom-Selenium
4. Using the Shadow-Dom-Selenium Library
1. Set Up the Project
You need to set up the Selenium WebDriver and include the shadow-dom-selenium library in your project. This library simplifies the process of accessing shadow DOM elements.
Using Maven: If you're using Maven, add the following dependency to your pom.xml
:
<dependency>
<groupId>io.github.sukgu</groupId>
<artifactId>shadow-dom-selenium</artifactId>
<version>0.0.7</version>
</dependency>
2. Set Up ChromeDriver
System.setProperty("webdriver.chrome.driver", "path_to_chromedriver");
WebDriver driver = new ChromeDriver();
3. Initialize the Shadow DOM Helper Library
To interact with shadow DOM elements, you need to instantiate the Shadow
class, which wraps Selenium WebDriver and allows easy interaction with shadow DOM elements.
Shadow shadow = new Shadow(driver);
4. Use findElementByXPath: Use the findElementByXPath method provided by the shadow
object to directly access shadow DOM elements via XPath.
Example Code
//Set Up ChromeDriver
System.setProperty("webdriver.chrome.driver", "path_to_chromedriver");
WebDriver driver = new ChromeDriver();
// Initialize the Shadow object
Shadow shadow = new Shadow(driver);
// Access shadow DOM elements directly using XPath
WebElement shadowElement = shadow.findElementByXPath("//input[@id='inputField']");
Conclusion:
Handling Shadow DOM in Selenium WebDriver requires a different approach than the usual way of interacting with elements. By using JavaScript execution to navigate through the Shadow DOM layers, you can successfully automate scenarios involving web components. This method will allow you to handle modern web applications that use Shadow DOM, ensuring your automation scripts remain effective even as web technologies evolve.
Comments
Post a Comment