And*_*son 9 python selenium selenium-webdriver shadow-dom
我想自动执行文件下载完成检查chromedriver
.
HTML
下载列表中的每个条目看起来像
<a is="action-link" id="file-link" tabindex="0" role="link" href="http://fileSource" class="">DownloadedFile#1</a>
Run Code Online (Sandbox Code Playgroud)
所以我使用以下代码来查找目标元素:
driver.get('chrome://downloads/') # This page should be available for everyone who use Chrome browser
driver.find_elements_by_tag_name('a')
Run Code Online (Sandbox Code Playgroud)
这将返回空列表,同时有3个新下载.
正如我发现的那样,只能#shadow-root (open)
处理标签的父元素.那么如何在这个#shadow-root
元素中找到元素呢?
小智 8
还可以使用pyshadow pip 模块,该模块在我的情况下有效,如下例:
from pyshadow.main import Shadow
from selenium import webdriver
driver = webdriver.Chrome('chromedriver.exe')
shadow = Shadow(driver)
element = shadow.find_element("#Selector_level1")
element1 = shadow.find_element("#Selector_level2")
element2 = shadow.find_element("#Selector_level3")
element3 = shadow.find_element("#Selector_level4")
element4 = shadow.find_element("#Selector_level5")
element5 = shadow.find_element('#control-button') #target selector
element5.click()
Run Code Online (Sandbox Code Playgroud)
有时,阴影根元素是嵌套的,而第二个阴影根在文档根中不可见,但在其父级访问的阴影根中可用。我认为最好使用硒选择器并注入脚本只是为了扎根影子:
def expand_shadow_element(element):
shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
return shadow_root
outer = expand_shadow_element(driver.find_element_by_css_selector("#test_button"))
inner = outer.find_element_by_id("inner_button")
inner.click()
Run Code Online (Sandbox Code Playgroud)
为了说明这一点,我刚刚在Chrome的下载页面上添加了一个可测试的示例,单击“搜索”按钮需要打开3个嵌套的阴影根元素:
import selenium
from selenium import webdriver
driver = webdriver.Chrome()
def expand_shadow_element(element):
shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
return shadow_root
driver.get("chrome://downloads")
root1 = driver.find_element_by_tag_name('downloads-manager')
shadow_root1 = expand_shadow_element(root1)
root2 = shadow_root1.find_element_by_css_selector('downloads-toolbar')
shadow_root2 = expand_shadow_element(root2)
root3 = shadow_root2.find_element_by_css_selector('cr-search-field')
shadow_root3 = expand_shadow_element(root3)
search_button = shadow_root3.find_element_by_css_selector("#search-button")
search_button.click()
Run Code Online (Sandbox Code Playgroud)
采取其他答案中建议的相同方法的缺点是,它对查询进行了硬编码,可读性较低,并且您不能将中间选择用于其他操作:
search_button = driver.execute_script('return document.querySelector("downloads-manager").shadowRoot.querySelector("downloads-toolbar").shadowRoot.querySelector("cr-search-field").shadowRoot.querySelector("#search-button")')
search_button.click()
Run Code Online (Sandbox Code Playgroud)
我最近尝试访问内容设置(请参见下面的代码),它包含多个影象根元素,现在您通常不能同时访问动态内容和三个以上的影象元素,而不能先扩展另一个影象根元素这使得不可能实现自动化。上面的答案曾经使用过一段时间,但是仅需一个元素就可以改变位置,您需要始终与检查元素一起走到树上,看看它是否在影子根中,这是自动化的噩梦。
当您发现此时无法单击按钮时,不仅由于阴影根和动态更改而很难仅找到内容设置。
driver = webdriver.Chrome()
def expand_shadow_element(element):
shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
return shadow_root
driver.get("chrome://settings")
root1 = driver.find_element_by_tag_name('settings-ui')
shadow_root1 = expand_shadow_element(root1)
root2 = shadow_root1.find_element_by_css_selector('[page-name="Settings"]')
shadow_root2 = expand_shadow_element(root2)
root3 = shadow_root2.find_element_by_id('search')
shadow_root3 = expand_shadow_element(root3)
search_button = shadow_root3.find_element_by_id("searchTerm")
search_button.click()
text_area = shadow_root3.find_element_by_id('searchInput')
text_area.send_keys("content settings")
root0 = shadow_root1.find_element_by_id('main')
shadow_root0_s = expand_shadow_element(root0)
root1_p = shadow_root0_s.find_element_by_css_selector('settings-basic-page')
shadow_root1_p = expand_shadow_element(root1_p)
root1_s = shadow_root1_p.find_element_by_css_selector('settings-privacy-page')
shadow_root1_s = expand_shadow_element(root1_s)
content_settings_div = shadow_root1_s.find_element_by_css_selector('#site-settings-subpage-trigger')
content_settings = content_settings_div.find_element_by_css_selector("button")
content_settings.click()
Run Code Online (Sandbox Code Playgroud)
您可以使用该driver.executeScript()
方法访问网页中的 HTML 元素和 JavaScript 对象。
在下面的示例中,executeScript
将返回元素为 的 Shadow 树中存在的所有元素的Promise
节点列表。然后你可以执行你的断言测试:<a>
id
host
it( 'check shadow root content', function ()
{
return driver.executeScript( function ()
{
return host.shadowRoot.querySelectorAll( 'a' ).then( function ( n )
{
return expect( n ).to.have.length( 3 )
}
} )
} )
Run Code Online (Sandbox Code Playgroud)
注意:我不懂 Python,所以我使用了 JavaScript 语法,但它应该以相同的方式工作。
归档时间: |
|
查看次数: |
3813 次 |
最近记录: |