From 2ec2a2f295b4477b0b7c298a7f91f456d11aac8d Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Sat, 10 Oct 2020 15:10:56 -0700 Subject: [PATCH] Detect shadow dom elements when calling `path` --- lib/capybara/selenium/node.rb | 3 +++ lib/capybara/spec/public/test.js | 7 ++++++- lib/capybara/spec/session/node_spec.rb | 11 +++++++++++ lib/capybara/spec/views/with_js.erb | 1 + spec/dsl_spec.rb | 2 +- spec/rack_test_spec.rb | 1 + 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index 8f859971..0b7784c2 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -493,6 +493,9 @@ private var xpath = ''; var pos, tempitem2; + if (el.getRootNode && el.getRootNode() instanceof ShadowRoot) { + return ": Shadow DOM element - no XPath :" + }; while(el !== xml.documentElement) { pos = 0; tempitem2 = el; diff --git a/lib/capybara/spec/public/test.js b/lib/capybara/spec/public/test.js index 2a2406d2..589b073d 100644 --- a/lib/capybara/spec/public/test.js +++ b/lib/capybara/spec/public/test.js @@ -271,5 +271,10 @@ $(function() { }); $('#multiple-file, #hidden_file').change(function(e){ $('body').append($('

File input changed

')); - }) + }); + + var shadow = document.querySelector('#shadow').attachShadow({mode: 'open'}); + var span = document.createElement('span'); + span.textContent = 'The things we do in the shadows'; + shadow.appendChild(span); }); diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb index 4d43bc71..d0fadae4 100644 --- a/lib/capybara/spec/session/node_spec.rb +++ b/lib/capybara/spec/session/node_spec.rb @@ -409,6 +409,17 @@ Capybara::SpecHelper.spec 'node' do element = @session.find(:link, 'Second Link') expect(@session.find(:xpath, element.path)).to eq(element) end + + it 'reports when element in shadow dom', requires: [:shadow_dom] do + @session.visit('/with_js') + shadow = @session.find(:css, '#shadow') + element = @session.evaluate_script(<<~JS, shadow) + (function(root){ + return root.shadowRoot.querySelector('span'); + })(arguments[0]) + JS + expect(element.path).to eq ": Shadow DOM element - no XPath :" + end end describe '#trigger', requires: %i[js trigger] do diff --git a/lib/capybara/spec/views/with_js.erb b/lib/capybara/spec/views/with_js.erb index 6c05df99..ea007f88 100644 --- a/lib/capybara/spec/views/with_js.erb +++ b/lib/capybara/spec/views/with_js.erb @@ -152,6 +152,7 @@

This is an HTML5 draggable element.

+