How to Find Web Elements in Shadow DOMs using Selenium WebDriver and C#

Alan Canlin
4 min readOct 9, 2018

--

The Problem

The process of finding elements in a web page that does not use Shadow DOM is straightforward enough. Trying to find elements in a web page that does use Shadow DOM is another kettle of fish entirely!

The problem is that the WebDriver libraries do not natively support shadow DOM elements out of the box so if you use the provided function calls to find elements they will fail.

An Example Web Page

A common example web page used to demonstrate shadow DOM usage is the Google Chrome Downloads page:

On this screen there are three shadow roots called “downloads-manager”, “downloads-list” and “downloads-item”. The names come from the tag listed above each shadow-root as outlined in red.

The Solution

Part 1: Use JavaScript

A common solution for working round something that is not supported by WebDriver is to use JavaScript via the WebDriver ExecuteScript function.

At a high level, what we need to do is:

  1. Find the shadow root of an element
  2. Find the element within that shadow root

Let’s tackle the first step. We need to cycle through the shadow root elements to get to the desired level of html source. The best way to do this in code is as follows:

To explain a little:

  • We send in an array of shadow root names
  • We loop thru the array to get to the shadow root we need. To do this we run some Javascript to access the shadowRoot variable of the current element
  • Once we’ve searched thru all the shadow roots provided, we return the element as an IWebElement

Part 2: How do you define the list of selectors to use

The hard part to to all of this is how do we know what selectors to send to FindShadowRootElement()?

The best way to find out what to send is to use Chrome’s Developer Tools and inspect the element. For example, in the above Chrome Downloads page image, if we inspect the node msi file’s ‘X’ icon, you will get:

As we can see, the button with id “remove” is highlighted. The important part is the ribbon list of elements below that. I have expanded out the ribbon to show what I mean:

We are interested in the names that appear before the “#shadow-root” entries, “downloads-manager” and “downloads-item”. In this case the shadow root names are as they appear in the html source, but as I have discovered to my cost, this is not always the case, so it’s good practice to use Chrome’s element ribbon to help.

Part 3: Find and manipulate the element

We can then use our FindShadowRootElement function, passing in our string array of selectors thus:

Now we have access to the shadow root, we can search it for the element we want to use by using whatever strategy we prefer. We can then manipulate the element we have found in the normal way, for example to click the ‘X’ icon:

And Finally…

A great way to use the FindShadowRootElement function is to have it available as if it were part of the WebDriver API by writing an extension method. Further details of how to do this in my story C# WebDriver Extensions

--

--

Alan Canlin

Software Test Engineer specialising in test automation