How to access and interact with Shadow DOM using Watir?

一曲冷凌霜 提交于 2020-12-26 11:08:29

问题


I need to access this page chrome://downloads/ and check that a file has been downloaded but it's Shadow DOM.

I've found this article how to access DOM Elements With Selenium Webdriver. http://jeremysklarsky.github.io/blog/2015/06/13/accessing-shadow-dom-elements-with-selenium-webdriver/

But this is written in JS

driver.executeScript("return $('body /deep/ <#yourSelector>')")

driver.executeScript("return $('body /deep/ ._mm_column')[0].textContent").then(function(title){
  title.should.contain(segmentName);
});

Having changed that to Watir syntax, my code works but doesn't return me the desired results:

    execute_script("return $('<#file-link>')")

    execute_script("return $( '<:contains(test-file.mp3)>')")

I'm just getting nils in the console.

enter image description here

But what I'd like to get is to make sure that the element is present.


回答1:


As mentioned by titusfortner's deleted answer, Selenium Easy had a related article, "Working with Shadow DOM Elements using Webdriver". It turns out that you can get a shadow element via JavaScript and then interact with it's descendants as normal.

However, due to the way Watir is written, I had to monkey-patch Watir::Browser to make it work. I'll see if I can get a more permanent fix, but for now, here's a working example:

require 'watir'

# Monkey-patch due to being unable to check the tag name of the shadow root
class Watir::Browser
  def wrap_element(scope, element)
    Watir.element_class_for(element.tag_name.downcase).new(scope, element: element)
  rescue Selenium::WebDriver::Error::UnknownError # need a better rescue
    Watir::Element.new(scope, element: element)
  end
end

def expand_root_element(element, browser)
    browser.execute_script("return arguments[0].shadowRoot", element)
end

browser = Watir::Browser.new

# Create a download item
browser.goto('https://chromedriver.storage.googleapis.com/2.33/chromedriver_win32.zip')
browser.goto('chrome://downloads')

# Navigate the shadow DOM to the download items
download_manager = browser.element(css: 'downloads-manager')
shadow_download_manager = expand_root_element(download_manager, browser)

download_items = shadow_download_manager.elements(css: '#downloads-list downloads-item')
shadow_download_items = download_items.map { |s| expand_root_element(s, browser) }

# Find a specific download item by file name
expected_file = /chromedriver_win32/
download = shadow_download_items.find { |s| s.span(id: 'name').text_content =~ expected_file }

# Do something with the download - eg wait for the download to complete
download.link(id: 'show').wait_until_present


来源:https://stackoverflow.com/questions/47520550/how-to-access-and-interact-with-shadow-dom-using-watir

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!