From 1899120224f92e19729286dac07eb195d41b74d8 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 17 Oct 2022 17:33:24 -0700 Subject: [PATCH] Selenium: Raise clear error when trying to get visible text on a shadow root --- lib/capybara/selenium/node.rb | 8 +++++++- lib/capybara/spec/session/node_spec.rb | 14 +++++++++++++- spec/selenium_spec_chrome.rb | 2 ++ spec/selenium_spec_chrome_remote.rb | 2 ++ spec/selenium_spec_edge.rb | 2 ++ spec/selenium_spec_firefox.rb | 2 ++ spec/selenium_spec_firefox_remote.rb | 2 ++ spec/selenium_spec_ie.rb | 2 ++ spec/selenium_spec_safari.rb | 2 ++ 9 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index 3a079cc3..52ceb1bd 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -10,6 +10,8 @@ class Capybara::Selenium::Node < Capybara::Driver::Node include Capybara::Selenium::Scroll def visible_text + raise NotImplementedError, 'Getting visible text is not currently supported directly on shadow roots' if shadow_root? + native.text end @@ -182,7 +184,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node if native.respond_to? :tag_name native.tag_name.downcase else - native.is_a?(::Selenium::WebDriver::ShadowRoot) ? 'ShadowRoot' : 'Unknown' + shadow_root? ? 'ShadowRoot' : 'Unknown' end end @@ -533,6 +535,10 @@ private id || type_or_id end + def shadow_root? + defined?(::Selenium::WebDriver::ShadowRoot) && native.is_a?(::Selenium::WebDriver::ShadowRoot) + end + GET_XPATH_SCRIPT = <<~'JS' (function(el, xml){ var xpath = ''; diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb index 857f2b25..42a99949 100644 --- a/lib/capybara/spec/session/node_spec.rb +++ b/lib/capybara/spec/session/node_spec.rb @@ -1220,13 +1220,25 @@ Capybara::SpecHelper.spec 'node' do expect(descendant).to have_checked_field('shadow_checkbox') end - it 'should produce error messages when failing', :focus_ do + it 'should produce error messages when failing' do @session.visit('/with_shadow') shadow_root = @session.find(:css, '#shadow_host').shadow_root expect do expect(shadow_root).to have_css('#shadow_content', text: 'Not in the document') end.to raise_error(/tag="ShadowRoot"/) end + + it 'should get visible text' do + @session.visit('/with_shadow') + shadow_root = @session.find(:css, '#shadow_host').shadow_root + expect(shadow_root).to have_text('some text scroll.html') + end + + it 'should get all text' do + @session.visit('/with_shadow') + shadow_root = @session.find(:css, '#shadow_host').shadow_root + expect(shadow_root).to have_text(:all, 'some text scroll.html') + end end describe '#reload', requires: [:js] do diff --git a/spec/selenium_spec_chrome.rb b/spec/selenium_spec_chrome.rb index d840e9e5..ed37a3a2 100644 --- a/spec/selenium_spec_chrome.rb +++ b/spec/selenium_spec_chrome.rb @@ -85,6 +85,8 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform? when /Capybara::Session selenium_chrome Capybara::Window#maximize/ pending "Chrome headless doesn't support maximize" if ENV['HEADLESS'] + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_chrome_remote.rb b/spec/selenium_spec_chrome_remote.rb index 7916140d..41e5e027 100644 --- a/spec/selenium_spec_chrome_remote.rb +++ b/spec/selenium_spec_chrome_remote.rb @@ -62,6 +62,8 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded', 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty' pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14) + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_edge.rb b/spec/selenium_spec_edge.rb index 49c307e3..d1bbb97b 100644 --- a/spec/selenium_spec_edge.rb +++ b/spec/selenium_spec_edge.rb @@ -36,6 +36,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_ case example.metadata[:full_description] when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input' pending "EdgeChrome doesn't allow clicking on file inputs" + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_firefox.rb b/spec/selenium_spec_firefox.rb index 1a2ec10d..cdc4b7c3 100644 --- a/spec/selenium_spec_firefox.rb +++ b/spec/selenium_spec_firefox.rb @@ -80,6 +80,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba pending "Firefox doesn't yet have full W3C shadow root support" when 'Capybara::Session selenium #fill_in should handle carriage returns with line feeds in a textarea correctly' pending 'Not sure what firefox is doing here' + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_firefox_remote.rb b/spec/selenium_spec_firefox_remote.rb index dd61c175..dda712ef 100644 --- a/spec/selenium_spec_firefox_remote.rb +++ b/spec/selenium_spec_firefox_remote.rb @@ -65,6 +65,8 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE when /#accept_confirm should work with nested modals$/ # skip because this is timing based and hence flaky when set to pending skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_ie.rb b/spec/selenium_spec_ie.rb index ce906398..d71079be 100644 --- a/spec/selenium_spec_ie.rb +++ b/spec/selenium_spec_ie.rb @@ -108,6 +108,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk skip "IE doesn't support template elements" when /Element#drop/ pending "IE doesn't support DataTransfer constructor" + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end diff --git a/spec/selenium_spec_safari.rb b/spec/selenium_spec_safari.rb index a40808a3..05cfd44f 100644 --- a/spec/selenium_spec_safari.rb +++ b/spec/selenium_spec_safari.rb @@ -88,6 +88,8 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS', 'Capybara::Session selenium node #shadow_root should find nested shadow roots' pending "Safari doesn't yet have W3C shadow root support" + when /Capybara::Session selenium_chrome node #shadow_root should get visible text/ + pending "Selenium doesn't currently support getting visible text for shadow root elements" end end