暗影支持硒

时间:2016-03-21 18:46:58

标签: selenium selenium-chromedriver shadow-dom

我正在研究一个广泛使用阴影dom的自动化项目。所以每次使用execute_script函数访问shadow root

例如。

root = driver.execute_script('return document.querySelector(".flex.vertical.layout").shadowRoot')

然后使用root访问其中的元素。由于我们在很多层面都有影子根源,这让我很烦恼。是否存在比这更好的解决方案来访问阴影根中的元素?

我使用的是Chrome 2.20驱动程序。

5 个答案:

答案 0 :(得分:4)

通过谷歌搜索我发现了另一个解决这个问题的方法 - 使用" / deep / combinator"。

例如,我能够通过

访问所有阴影根元素

driver.find_elements_by_css_selector('主体/深/ .layout.horizo​​ntal.center&#39)

这将可以访问具有复合类名称的元素"布局水平中心"无论它有多少影子根。

但这只适用于Chrome驱动程序,我看到了注释" / deep /"是一种弃用的方法。

答案 1 :(得分:3)

关于Shadow DOM,WebDriver规范仍然是doesn't have anything specific to say

也不是Selenium project pages - 这是可以理解的,因为它们严格遵循规范。然而,存在some low-level code

因此,简短的回答是:不,目前在Selenium的WebDriver API或实施代码中,规范中没有特别的支持。

是的,该功能似乎存在于ChromeDriver 2.14中(作为Chrome的包装)。但是,据我所知,没有Selenium或WebDriver级别的绑定可以让你使用它。

但是有关更多详细信息和可能的解决方法,请参阅:Accessing Shadow DOM tree with Selenium,还有:Accessing elements in the shadow DOM,尤其是:Finding elements in the shadow DOM

答案 2 :(得分:2)

您可以编写扩展方法来操作IWebElement以扩展根目录,如下所示。

        public static class SeleniumExtension
{
    public static IWebElement ExpandRootElement(this IWebElement element, IWebDriver driver)
    {
        return (IWebElement)((IJavaScriptExecutor)driver)
                .ExecuteScript("return arguments[0].shadowRoot", element);
    }
}

您可以使用上面的扩展方法遍历元素层次结构以到达intrest元素。

        By downloads_manager_ShadowDom= By.TagName("downloads-manager");
        By downloadToolBarShadowDom = By.CssSelector("downloads-toolbar");
        By toolBarElement = By.CssSelector("cr-toolbar");

    IWebElement ToolBarElement = driver.FindElement(downloads_manager_ShadowDom).ExpandRootElement(driver)
                          .FindElement(downloadToolBarShadowDom).ExpandRootElement(driver)
                          .FindElement(toolBarElement);

答案 3 :(得分:0)

由于您经常使用可以创建函数,因此上面的内容变为:

plt.tick_params(axis='both', labelsize=20)

在结果元素上你可以放任何方法:

def select_shadow_element_by_css_selector(selector):
  running_script = 'return document.querySelector("%s").shadowRoot' % selector
  element = driver.execute_script(running_script)
  return element

shadow_section = select_shadow_element_by_css_selector(".flex.vertical.layout")
shadow_section.find_element_by_css(".flex")
     

要查找多个元素(这些方法将返回一个列表):

find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector

稍后修改:

有时阴影主机元素会隐藏阴影树,这就是为什么最好的方法是使用selenium选择器来查找阴影主机元素并注入脚本只是为了获取阴影根:

find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector

为了说明这一点,我刚刚在Chrome的下载页面添加了一个可测试的示例,单击搜索按钮需要打开3个嵌套的阴影根元素:

def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

#the above becomes 
shadow_section = expand_shadow_element(find_element_by_tag_name("neon-animatable"))
shadow_section.find_element_by_css(".flex")

答案 4 :(得分:0)

不确定它适用于所有浏览器,但对我来说 ::shadow在chromedriver 2.38中工作正常。例如:

div::shadow div span::shadow a