From 75a309a9ddffabdd4f4d1bb55db827bdac7e7bb6 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Thu, 25 Apr 2019 14:24:17 -0700 Subject: [PATCH] Optimize disabled checking to one call where possible --- .../internet_explorer_driver.rb | 8 ++++++++ lib/capybara/selenium/nodes/chrome_node.rb | 4 ++++ lib/capybara/selenium/nodes/firefox_node.rb | 12 +----------- lib/capybara/selenium/nodes/ie_node.rb | 9 +++++++++ lib/capybara/selenium/nodes/safari_node.rb | 11 +---------- 5 files changed, 23 insertions(+), 21 deletions(-) create mode 100644 lib/capybara/selenium/nodes/ie_node.rb diff --git a/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb b/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb index 808c976b..a1395f1d 100644 --- a/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +++ b/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'capybara/selenium/nodes/ie_node' + module Capybara::Selenium::Driver::InternetExplorerDriver def switch_to_frame(frame) return super unless frame == :parent @@ -10,6 +12,12 @@ module Capybara::Selenium::Driver::InternetExplorerDriver browser.switch_to.default_content handles.tap(&:pop).each { |fh| browser.switch_to.frame(fh) } end + +private + + def build_node(native_node, initial_cache = {}) + ::Capybara::Selenium::IENode.new(self, native_node, initial_cache) + end end module Capybara::Selenium diff --git a/lib/capybara/selenium/nodes/chrome_node.rb b/lib/capybara/selenium/nodes/chrome_node.rb index 09f61094..7051239d 100644 --- a/lib/capybara/selenium/nodes/chrome_node.rb +++ b/lib/capybara/selenium/nodes/chrome_node.rb @@ -35,6 +35,10 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node raise end + def disabled? + driver.evaluate_script("arguments[0].matches(':disabled, select:disabled *')", self) + end + private def file_errors diff --git a/lib/capybara/selenium/nodes/firefox_node.rb b/lib/capybara/selenium/nodes/firefox_node.rb index 5980f4c9..44c823dc 100644 --- a/lib/capybara/selenium/nodes/firefox_node.rb +++ b/lib/capybara/selenium/nodes/firefox_node.rb @@ -18,17 +18,7 @@ class Capybara::Selenium::FirefoxNode < Capybara::Selenium::Node end def disabled? - # Not sure exactly what version of FF fixed the below issue, but it is definitely fixed in 61+ - return super unless browser_version < 61.0 - - return true if super - - # workaround for selenium-webdriver/geckodriver reporting elements as enabled when they are nested in disabling elements - if %w[option optgroup].include? tag_name - find_xpath('parent::*[self::optgroup or self::select]')[0].disabled? - else - !find_xpath(DISABLED_BY_FIELDSET_XPATH).empty? - end + driver.evaluate_script("arguments[0].matches(':disabled, select:disabled *')", self) end def set_file(value) # rubocop:disable Naming/AccessorMethodName diff --git a/lib/capybara/selenium/nodes/ie_node.rb b/lib/capybara/selenium/nodes/ie_node.rb new file mode 100644 index 00000000..999116be --- /dev/null +++ b/lib/capybara/selenium/nodes/ie_node.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'capybara/selenium/extensions/html5_drag' + +class Capybara::Selenium::IENode < Capybara::Selenium::Node + def disabled? + driver.evaluate_script("arguments[0].msMatchesSelector(':disabled, select:disabled *')", self) + end +end diff --git a/lib/capybara/selenium/nodes/safari_node.rb b/lib/capybara/selenium/nodes/safari_node.rb index 700cb0b9..1b316eb1 100644 --- a/lib/capybara/selenium/nodes/safari_node.rb +++ b/lib/capybara/selenium/nodes/safari_node.rb @@ -40,16 +40,7 @@ class Capybara::Selenium::SafariNode < Capybara::Selenium::Node end def disabled? - return true if super - - # workaround for safaridriver reporting elements as enabled when they are nested in disabling elements - if %w[option optgroup].include? tag_name - return true if self[:disabled] == 'true' - - find_xpath('parent::*[self::optgroup or self::select]')[0].disabled? - else - !find_xpath(DISABLED_BY_FIELDSET_XPATH).empty? - end + driver.evaluate_script("arguments[0].matches(':disabled, select:disabled *')", self) end def set_file(value) # rubocop:disable Naming/AccessorMethodName