Is it possible to access elements within a Shadow DOM using Selenium/Chrome webdriver?
Using the normal element search methods doesn\'t work, as is to be expected.
I found a much easier way to get the elements from Shadow Dom. I am taking the same example given above, for search icon of Chrome Download Page.
IWebDriver driver;
public IWebElement getUIObject(params By[] shadowRoots)
{
IWebElement currentElement = null;
IWebElement parentElement = null;
int i = 0;
foreach (var item in shadowRoots)
{
if (parentElement == null)
{
currentElement = driver.FindElement(item);
}
else
{
currentElement = parentElement.FindElement(item);
}
if(i !=(shadowRoots.Length-1))
{
parentElement = expandRootElement(currentElement);
}
i++;
}
return currentElement;
}
public IWebElement expandRootElement(IWebElement element)
{
IWebElement rootElement = (IWebElement)((IJavaScriptExecutor)driver)
.ExecuteScript("return arguments[0].shadowRoot", element);
return rootElement;
}
Google Chrome Download Page
Now as shown in image we have to expand three shadow root elements in order to get our search icon. To to click on icon all we need to do is :-
[TestMethod]
public void test()
{
IWebElement searchButton= getUIObject(By.CssSelector("downloads-manager"),By.CssSelector("downloads-toolbar"),By.Id("search-input"),By.Id("search-buton"));
searchButton.Click();
}
So just one line will give you your Web Element, just need to make sure you pass first shadow root element as first argument of the function "getUIObject" second shadow root element as second argument of the function and so on, finally last argument for the function will be the identifier for your actual element (for this case its 'search-button')