We are developing a web app using Google Polymer as front end.
We discovered that Capybara could not query element within Shadow DOM.
Is there any technique to solve this?
Please ask questions about usage of Capybara in the mailing list, as requested in the README
I agree with @afterclassroom, I think the specific issue is that Capybara doesn't support "custom elements" (polymer uses it): http://www.html5rocks.com/en/tutorials/webcomponents/customelements/
A work around is to make something like this:
document.querySelector('custom-element').shadowRoot.querySelector('#html-element')
Please look below at the comments of the link:
https://github.com/webdriverio/webdriverio/issues/194
Right now, I am working to develop an approach to overcome this problem, trying to use capybara.
@afterclassroom try using the 'within' method to reference elements within the Shadow DOM. Note that if there are nested Shadow DOMs, you'll need another 'within' function as well.
@qiheme
We would love to apply 'within'.
But as you sketched out, we do have nested Shadow DOMs.
In which case, how could we locate to the proper DOM element, at which, we could use "within"?
Here is an example of how jQuery could locate the needed element at GoogleChrome's console:
document.querySelector('classroom-app').shadowRoot.querySelector('core-animated-pages').querySelector('section.core-selected').querySelector('login-form /deep/ input')
@afterclassroom
Try this:
within('classroom-app') do
within('core-animated-pages') do
within('section.core-selected') do
within('login-form') do
page.find('input')
end
end
end
end
Use 'within' to break through each nested shadow DOM. Since you're using 'deep', I can't really tell if there are any other nested sDOMs in there. Also, since you're not using shadowRoot to get to 'section.core-selected' that particular 'within' might not be needed. I realize that nested loops can cause speed issues when running tests so I would probably put this in a separate rb file in your support folder. Let me know if this works for you.
This issue is old, but since it's the first result when you search for "capybara testing polymer" i want to leave some notes for the next poor soul who is looking for a way to test web-components with capybara.
:js. Duh, I know. But maybe I'm not the only one who makes dumb mistakes.:js specs, you have to decide on a driver. Phantomjs (poltergeist) apparently does not support web-components. I use selenium-webdriver and registered chrome as a browser.selenium-webdriver(gem) requires chromedriver(system binary) to be installed on your machine. You can find it here:chmod +x)rails_helper.rb (if you're using rails)Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.javascript_driver = :chrome
This means your tests won't be headless, but feel free to get this set up and working with headless chrome. If you do, tell me about it :)
Fields and Inputs should be easily reached with:
fill_in "id_of_input_in_component"
click_on "Text of Submit Button in Component"
@maxkerp Assuming you're using current Capybara (2.15.1 as of now) you don't need to register your own driver for this, just specify either
Capybara.javascript_driver = :selenium_chrome
or
Capybara.javascript_driver = :selenium_chrome_headless
@maxkerp what about the primary issue of finding elements within the shadow dom? Your comment doesn't address that at all.
Sorry it took me so long to reply, but I couldn't get to it earlier.
@hraynaud I don't know how I would go about it, I totally forgot about Shadow Dom at the time I commented on this issue.
Most helpful comment
@maxkerp Assuming you're using current Capybara (2.15.1 as of now) you don't need to register your own driver for this, just specify either
or