Understanding Shadow Root Elements in Selenium

What are Shadow Root Elements?

Shadow DOM allows developers to encapsulate their HTML, CSS, and JavaScript, creating reusable web components with isolated DOM trees. Shadow root elements serve as entry points to this encapsulated content.

Types of Shadow Roots: Open, Closed, and Nested

1. Open Shadow Root

Open shadow roots allow access to their internal structure via the `shadowRoot` property.

2. Closed Shadow Root

Closed shadow roots hide their structure from external access, preventing direct manipulation via JavaScript.

3. Nested Shadow Root

Nested shadow roots contain one or more layers of shadow roots, encapsulating their own elements.

Login Module Examples

Open Shadow Root Example

Closed Shadow Root Example

Nested Shadow Root Example

Selenium Scripts for Handling Shadow Roots

1. Open Shadow Root Example


                import org.openqa.selenium.By;
                import org.openqa.selenium.WebDriver;
                import org.openqa.selenium.WebElement;
                import org.openqa.selenium.chrome.ChromeDriver;

                public class OpenShadowRootExample {
                    public static void main(String[] args) {
                        System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
                        WebDriver driver = new ChromeDriver();
                        driver.get("https://shariqsp.com/shadowroot.html");

                        // Access open shadow root
                        WebElement shadowHost = driver.findElement(By.id("openShadowHost"));
                        WebElement shadowRoot = shadowHost.shadowRoot;

                        // Interact with shadow elements
                        WebElement username = shadowRoot.findElement(By.id("openUsername"));
                        WebElement password = shadowRoot.findElement(By.id("openPassword"));
                        WebElement loginButton = shadowRoot.findElement(By.id("openLoginButton"));

                        username.sendKeys("user1");
                        password.sendKeys("password123");
                        loginButton.click();
                    }
                }
            

2. Closed Shadow Root Example

Accessing closed shadow roots directly via Selenium is not possible. Below is the structure.


                import org.openqa.selenium.By;
                import org.openqa.selenium.WebDriver;
                import org.openqa.selenium.WebElement;
                import org.openqa.selenium.chrome.ChromeDriver;
                import org.openqa.selenium.JavascriptExecutor;

                public class ClosedShadowRootExample {
                    public static void main(String[] args) {
                        System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
                        WebDriver driver = new ChromeDriver();
                        driver.get("https://shariqsp.com/shadowroot.html");

                        // Access closed shadow root
                        WebElement shadowHost = driver.findElement(By.id("closedShadowHost"));
                        WebElement shadowRoot = (WebElement) ((JavascriptExecutor) driver)
                                .executeScript("return arguments[0].shadowRoot", shadowHost);

                        // Interact with shadow elements if accessible
                        WebElement username = shadowRoot.findElement(By.cssSelector("input[placeholder='Username (Closed)']"));
                        WebElement password = shadowRoot.findElement(By.cssSelector("input[placeholder='Password (Closed)']"));
                        WebElement loginButton = shadowRoot.findElement(By.xpath("//button[text()='Login']"));

                        username.sendKeys("user1");
                        password.sendKeys("password123");
                        loginButton.click();
                    }
                }
            

3. Nested Shadow Root Example


                import org.openqa.selenium.By;
                import org.openqa.selenium.WebDriver;
                import org.openqa.selenium.WebElement;
                import org.openqa.selenium.chrome.ChromeDriver;
                import org.openqa.selenium.JavascriptExecutor;

                public class NestedShadowRootExample {
                    public static void main(String[] args) {
                        System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
                        WebDriver driver = new ChromeDriver();
                        driver.get("https://shariqsp.com/shadowroot.html");

                        // Access nested shadow root
                        WebElement shadowHost = driver.findElement(By.id("nestedShadowHost"));
                        WebElement firstShadowRoot = (WebElement) ((JavascriptExecutor) driver)
                                .executeScript("return arguments[0].shadowRoot", shadowHost);
                        WebElement secondShadowRoot = (WebElement) ((JavascriptExecutor) driver)
                                .executeScript("return arguments[0].shadowRoot", firstShadowRoot.findElement(By.className("nested-shadow")));

                        // Interact with nested shadow elements
                        WebElement username = secondShadowRoot.findElement(By.id("nestedUsername"));
                        WebElement password = secondShadowRoot.findElement(By.id("nestedPassword"));
                        WebElement loginButton = secondShadowRoot.findElement(By.id("nestedLoginButton"));

                        username.sendKeys("user1");
                        password.sendKeys("password123");
                        loginButton.click();
                    }
                }