From 36bdb661ff01e791b4a3b974bc32587e45ee4911 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Wed, 17 Apr 2019 18:04:03 -0700 Subject: [PATCH] Suppress some selenium-webdriver deprecation notices --- lib/capybara/selenium/driver.rb | 46 +++++++++++++++---- .../driver_specializations/chrome_driver.rb | 8 +++- lib/capybara/selenium/logger_suppressor.rb | 29 ++++++++++++ lib/capybara/selenium/nodes/chrome_node.rb | 8 +++- 4 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 lib/capybara/selenium/logger_suppressor.rb diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 91fedbd0..0aaa5da1 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -17,6 +17,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base class << self def load_selenium require 'selenium-webdriver' + require 'capybara/selenium/logger_suppressor' warn "Warning: You're using an unsupported version of selenium-webdriver, please upgrade." if Gem.loaded_specs['selenium-webdriver'].version < Gem::Version.new('3.5.0') rescue LoadError => e raise e unless e.message.match?(/selenium-webdriver/) @@ -124,7 +125,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base navigated = true # Ensure the page is empty and trigger an UnhandledAlertError for any modals that appear during unload wait_for_empty_page(timer) - rescue Selenium::WebDriver::Error::UnhandledAlertError, Selenium::WebDriver::Error::UnexpectedAlertOpenError + rescue *unhandled_alert_errors # This error is thrown if an unhandled alert is on the page # Firefox appears to automatically dismiss this alert, chrome does not # We'll try to accept it @@ -235,19 +236,26 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base end def invalid_element_errors - [ + errors = [ ::Selenium::WebDriver::Error::StaleElementReferenceError, - ::Selenium::WebDriver::Error::UnhandledError, - ::Selenium::WebDriver::Error::ElementNotVisibleError, - ::Selenium::WebDriver::Error::InvalidSelectorError, # Work around a chromedriver go_back/go_forward race condition ::Selenium::WebDriver::Error::ElementNotInteractableError, + ::Selenium::WebDriver::Error::InvalidSelectorError, # Work around chromedriver go_back/go_forward race condition ::Selenium::WebDriver::Error::ElementClickInterceptedError, - ::Selenium::WebDriver::Error::InvalidElementStateError, - ::Selenium::WebDriver::Error::ElementNotSelectableError, - ::Selenium::WebDriver::Error::ElementNotSelectableError, ::Selenium::WebDriver::Error::NoSuchElementError, # IE ::Selenium::WebDriver::Error::InvalidArgumentError # IE ] + + unless selenium_4? + ::Selenium::WebDriver.logger.suppress_deprecations do + errors.concat [ + ::Selenium::WebDriver::Error::UnhandledError, + ::Selenium::WebDriver::Error::ElementNotVisibleError, + ::Selenium::WebDriver::Error::InvalidElementStateError, + ::Selenium::WebDriver::Error::ElementNotSelectableError + ] + end + end + errors end def no_such_window_error @@ -263,12 +271,24 @@ private def clear_browser_state delete_all_cookies clear_storage - rescue Selenium::WebDriver::Error::UnhandledError # rubocop:disable Lint/HandleExceptions + rescue *clear_browser_state_errors # rubocop:disable Lint/HandleExceptions # delete_all_cookies fails when we've previously gone # to about:blank, so we rescue this error and do nothing # instead. end + def clear_browser_state_errors + ::Selenium::WebDriver.logger.suppress_deprecations do + [Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::UnknownError] + end + end + + def unhandled_alert_errors + ::Selenium::WebDriver.logger.suppress_deprecations do + [Selenium::WebDriver::Error::UnhandledAlertError, Selenium::WebDriver::Error::UnexpectedAlertOpenError] + end + end + def delete_all_cookies @browser.manage.delete_all_cookies end @@ -341,11 +361,17 @@ private regexp = text.is_a?(Regexp) ? text : Regexp.escape(text.to_s) alert.text.match?(regexp) ? alert : nil end - rescue Selenium::WebDriver::Error::TimeOutError + rescue *find_modal_errors raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{text}" if text}" end end + def find_modal_errors + ::Selenium::WebDriver.logger.suppress_deprecations do + [Selenium::WebDriver::Error::TimeoutError, Selenium::WebDriver::Error::TimeOutError] + end + end + def silenced_unknown_error_message?(msg) silenced_unknown_error_messages.any? { |regex| msg.match? regex } end diff --git a/lib/capybara/selenium/driver_specializations/chrome_driver.rb b/lib/capybara/selenium/driver_specializations/chrome_driver.rb index 3e518876..4c52667e 100644 --- a/lib/capybara/selenium/driver_specializations/chrome_driver.rb +++ b/lib/capybara/selenium/driver_specializations/chrome_driver.rb @@ -40,11 +40,17 @@ private def delete_all_cookies execute_cdp('Network.clearBrowserCookies') - rescue Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::WebDriverError + rescue *cdp_unsupported_errors # If the CDP clear isn't supported do original limited clear super end + def cdp_unsupported_errors + ::Selenium::WebDriver.logger.suppress_deprecations do + [Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::WebDriverError] + end + end + def execute_cdp(cmd, params = {}) args = { cmd: cmd, params: params } result = bridge.http.call(:post, "session/#{bridge.session_id}/goog/cdp/execute", args) diff --git a/lib/capybara/selenium/logger_suppressor.rb b/lib/capybara/selenium/logger_suppressor.rb new file mode 100644 index 00000000..7f4bf5bd --- /dev/null +++ b/lib/capybara/selenium/logger_suppressor.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Capybara + module Selenium + module DeprecationSuppressor + def deprecate(*) + super unless @suppress_for_capybara + end + + def suppress_deprecations + prev_suppress_for_capybara, @suppress_for_capybara = @suppress_for_capybara, true + yield + ensure + @suppress_for_capybara = prev_suppress_for_capybara + end + end + + module ErrorSuppressor + def for_code(*) + ::Selenium::WebDriver.logger.suppress_deprecations do + super + end + end + end + end +end + +Selenium::WebDriver::Logger.prepend Capybara::Selenium::DeprecationSuppressor +Selenium::WebDriver::Error.singleton_class.prepend Capybara::Selenium::ErrorSuppressor diff --git a/lib/capybara/selenium/nodes/chrome_node.rb b/lib/capybara/selenium/nodes/chrome_node.rb index 32407d3b..60779e05 100644 --- a/lib/capybara/selenium/nodes/chrome_node.rb +++ b/lib/capybara/selenium/nodes/chrome_node.rb @@ -14,7 +14,7 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node def set_file(value) # rubocop:disable Naming/AccessorMethodName super(value) - rescue ::Selenium::WebDriver::Error::ExpectedError => e + rescue *file_errors => e raise ArgumentError, "Selenium < 3.14 with remote Chrome doesn't support multiple file upload" if e.message.match?(/File not found : .+\n.+/m) raise @@ -28,6 +28,12 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node private + def file_errors + ::Selenium::WebDriver.logger.suppress_deprecations do + [::Selenium::WebDriver::Error::ExpectedError] + end + end + def bridge driver.browser.send(:bridge) end