I was trying to achieve the same in Chrome (in 2020), spent too much time on this, the final solution was to automate the disabling of Javascript in Chrome settings page.
To do that, i was writing a function to get Shadow DOM elements from Chrome with Javascript by the provided path, until i reached the level where the control i had to click on was located.
This is the function i was using for that (i found the solution here and modified a bit):
public IWebElement GetElementFromShadow(string[] Path)
{
IWebElement root = null;
foreach (string act in Path)
{
if (root == null)
{
root = (IWebElement)((IJavaScriptExecutor)_driver).ExecuteScript("return document.querySelector(arguments[0]).shadowRoot", act);
}
else
{
root = (IWebElement)((IJavaScriptExecutor)_driver).ExecuteScript("return arguments[0].querySelector(arguments[1]).shadowRoot", root, act);
}
}
return root;
}
Then in the test definition, i created an array of strings with the shadow dom path i found in DevTools, used the function above to get the WebElement from inside the nested shadowRoot, so i could click on it with Selenium:
string[] DisableJSShadowRootPath = { "settings-ui", "settings-main", "settings-basic-page", "settings-privacy-page", "category-default-setting", "settings-toggle-button", "cr-toggle" };
IWebElement control = _JSsettings.GetElementFromShadow(DisableJSShadowRootPath);
control.FindElements(By.TagName("span")).Where(e => e.GetAttribute("id") == "knob").First().Click();
The path can be easily found at the bottom ribbon of Chrome DevTools: