Merge pull request #2439 from teamcapybara/selenium_4_alpha

Update for selenium 4 latest alpha - Fix issue #2431
This commit is contained in:
Thomas Walpole 2021-01-20 09:20:07 -08:00 committed by GitHub
commit a760f1775e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 48 deletions

View File

@ -59,7 +59,7 @@ matrix:
rvm: 2.7 rvm: 2.7
env: HEADLESS=true env: HEADLESS=true
- gemfile: gemfiles/Gemfile.beta-versions - gemfile: gemfiles/Gemfile.beta-versions
rvm: 2.6 rvm: 3.0
env: CAPYBARA_FF=true env: CAPYBARA_FF=true
addons: addons:
firefox: latest-beta firefox: latest-beta

View File

@ -7,13 +7,14 @@ gem 'pkg-config' # needed by nokogiri
gem 'xpath', github: 'teamcapybara/xpath' gem 'xpath', github: 'teamcapybara/xpath'
gem 'rack', github: 'rack/rack' gem 'rack', github: 'rack/rack'
gem 'sinatra', github: 'sinatra/sinatra', branch: 'master' gem 'sinatra', github: 'sinatra/sinatra', branch: 'master'
gem 'rspec', github: 'rspec/rspec' gem 'rspec', github: 'rspec/rspec', branch: 'main'
gem 'rspec-core', github: 'rspec/rspec-core' gem 'rspec-core', github: 'rspec/rspec-core', branch: 'main'
gem 'rspec-support', github: 'rspec/rspec-support' gem 'rspec-support', github: 'rspec/rspec-support', branch: 'main'
gem 'rspec-mocks', github: 'rspec/rspec-mocks' gem 'rspec-mocks', github: 'rspec/rspec-mocks', branch: 'main'
gem 'rspec-expectations', github: 'rspec/rspec-expectations' gem 'rspec-expectations', github: 'rspec/rspec-expectations', branch: 'main'
gem 'cucumber', github: 'cucumber/cucumber-ruby' gem 'cucumber', github: 'cucumber/cucumber-ruby'
gem 'cucumber-core', github: 'cucumber/cucumber-ruby-core' gem 'cucumber-core', github: 'cucumber/cucumber-ruby-core'
gem 'cucumber-wire', github: 'cucumber/cucumber-ruby-wire' gem 'cucumber-wire', github: 'cucumber/cucumber-ruby-wire'
gem 'puma', github: 'puma/puma' gem 'puma', github: 'puma/puma'
gem 'selenium-webdriver', '>= 4.0.0.alpha7'

View File

@ -9,32 +9,56 @@ Capybara.register_driver :selenium do |app|
end end
Capybara.register_driver :selenium_headless do |app| Capybara.register_driver :selenium_headless do |app|
Capybara::Selenium::Driver.load_selenium version = Capybara::Selenium::Driver.load_selenium
browser_options = ::Selenium::WebDriver::Firefox::Options.new browser_options = ::Selenium::WebDriver::Firefox::Options.new
if browser_options.respond_to?(:headless!) if browser_options.respond_to?(:headless!)
browser_options.headless! browser_options.headless!
else else
browser_options.args << '-headless' browser_options.args << '-headless'
end end
Capybara::Selenium::Driver.new(app, browser: :firefox, options: browser_options)
if version >= Gem::Version.new('4.0.0.alpha6')
Capybara::Selenium::Driver.new(app, browser: :firefox, capabilities: browser_options)
else
Capybara::Selenium::Driver.new(app, browser: :firefox, options: browser_options)
end
end end
Capybara.register_driver :selenium_chrome do |app| Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.load_selenium version = Capybara::Selenium::Driver.load_selenium
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts| browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
opts.args << '--disable-site-isolation-trials' if opts.respond_to?(:add_argument)
opts.add_argument('--disable-site-isolation-trials')
else
opts.args << '--disable-site-isolation-trials'
end
end
if version >= Gem::Version.new('4.0.0.alpha6')
Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: browser_options)
else
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end end
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end end
Capybara.register_driver :selenium_chrome_headless do |app| Capybara.register_driver :selenium_chrome_headless do |app|
Capybara::Selenium::Driver.load_selenium version = Capybara::Selenium::Driver.load_selenium
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts| browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
opts.args << '--headless' if opts.respond_to?(:headless!)
opts.headless!
else
opts.args << '--headless'
end
opts.args << '--disable-gpu' if Gem.win_platform? opts.args << '--disable-gpu' if Gem.win_platform?
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
opts.args << '--disable-site-isolation-trials' opts.args << '--disable-site-isolation-trials'
end end
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
if version >= Gem::Version.new('4.0.0.alpha6')
Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: browser_options)
else
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
end end

View File

@ -15,6 +15,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
attr_reader :app, :options attr_reader :app, :options
class << self class << self
attr_reader :selenium_webdriver_version
def load_selenium def load_selenium
require 'selenium-webdriver' require 'selenium-webdriver'
require 'capybara/selenium/logger_suppressor' require 'capybara/selenium/logger_suppressor'
@ -32,15 +34,18 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
# Selenium::WebDriver::VERSION. Ideally we'd # Selenium::WebDriver::VERSION. Ideally we'd
# use the constant in all cases, but earlier versions # use the constant in all cases, but earlier versions
# of `selenium-webdriver` didn't provide the constant. # of `selenium-webdriver` didn't provide the constant.
selenium_webdriver_version = @selenium_webdriver_version =
if Gem.loaded_specs['selenium-webdriver'] if Gem.loaded_specs['selenium-webdriver']
Gem.loaded_specs['selenium-webdriver'].version Gem.loaded_specs['selenium-webdriver'].version
else else
Gem::Version.new(Selenium::WebDriver::VERSION) Gem::Version.new(Selenium::WebDriver::VERSION)
end end
if selenium_webdriver_version < Gem::Version.new('3.5.0')
if @selenium_webdriver_version < Gem::Version.new('3.5.0')
warn "Warning: You're using an unsupported version of selenium-webdriver, please upgrade." warn "Warning: You're using an unsupported version of selenium-webdriver, please upgrade."
end end
@selenium_webdriver_version
rescue LoadError => e rescue LoadError => e
raise e unless e.message.include?('selenium-webdriver') raise e unless e.message.include?('selenium-webdriver')
@ -66,7 +71,15 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
end end
end end
processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) } processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) }
@browser = Selenium::WebDriver.for(options[:browser], **processed_options)
@browser = if options[:browser] == :firefox &&
RUBY_VERSION >= '3.0' &&
Capybara::Selenium::Driver.selenium_webdriver_version <= Gem::Version.new('4.0.0.alpha1')
# selenium-webdriver 3.x doesn't correctly pass options through for Firefox with Ruby 3 so workaround that
Selenium::WebDriver::Firefox::Driver.new(**processed_options)
else
Selenium::WebDriver.for(options[:browser], processed_options)
end
specialize_driver specialize_driver
setup_exit_handler setup_exit_handler

View File

@ -8,7 +8,7 @@ module Capybara
super super
end end
def deprecate(*) def deprecate(*, **, &block)
super unless @suppress_for_capybara super unless @suppress_for_capybara
end end

View File

@ -19,39 +19,71 @@ browser_options.add_preference('download.default_directory', Capybara.save_path)
browser_options.add_preference(:download, default_directory: Capybara.save_path) browser_options.add_preference(:download, default_directory: Capybara.save_path)
Capybara.register_driver :selenium_chrome do |app| Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options, timeout: 30).tap do |driver| version = Capybara::Selenium::Driver.load_selenium
driver_options = { browser: :chrome, timeout: 30 }.tap do |opts|
if version >= Gem::Version.new('4.0.0.alpha6')
opts[:capabilities] = browser_options
else
opts[:options] = browser_options
end
end
Capybara::Selenium::Driver.new(app, **driver_options).tap do |driver|
# Set download dir for Chrome < 77 # Set download dir for Chrome < 77
driver.browser.download_path = Capybara.save_path driver.browser.download_path = Capybara.save_path
end end
end end
Capybara.register_driver :selenium_chrome_not_clear_storage do |app| Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
chrome_options = { version = Capybara::Selenium::Driver.load_selenium
browser: :chrome, chrome_options = { browser: :chrome, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
options: browser_options if version >= Gem::Version.new('4.0.0.alpha6')
} opts[:capabilities] = browser_options
Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false, clear_session_storage: false)) else
opts[:options] = browser_options
end
end
Capybara::Selenium::Driver.new(app, **chrome_options)
end end
Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app| Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
chrome_options = { version = Capybara::Selenium::Driver.load_selenium
browser: :chrome, chrome_options = { browser: :chrome, clear_session_storage: false }.tap do |opts|
options: browser_options if version >= Gem::Version.new('4.0.0.alpha6')
} opts[:capabilities] = browser_options
Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_session_storage: false)) else
opts[:options] = browser_options
end
end
Capybara::Selenium::Driver.new(app, **chrome_options)
end end
Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app| Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
chrome_options = { version = Capybara::Selenium::Driver.load_selenium
browser: :chrome, chrome_options = { browser: :chrome, clear_local_storage: false }.tap do |opts|
options: browser_options if version >= Gem::Version.new('4.0.0.alpha6')
} opts[:capabilities] = browser_options
Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false)) else
opts[:options] = browser_options
end
end
Capybara::Selenium::Driver.new(app, **chrome_options)
end end
Capybara.register_driver :selenium_driver_subclass_with_chrome do |app| Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
version = Capybara::Selenium::Driver.load_selenium
subclass = Class.new(Capybara::Selenium::Driver) subclass = Class.new(Capybara::Selenium::Driver)
subclass.new(app, browser: :chrome, options: browser_options, timeout: 30) chrome_options = { browser: :chrome, timeout: 30 }.tap do |opts|
if version >= Gem::Version.new('4.0.0.alpha6')
opts[:capabilities] = browser_options
else
opts[:options] = browser_options
end
end
subclass.new(app, **chrome_options)
end end
module TestSessions module TestSessions

View File

@ -14,28 +14,36 @@ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof
profile['browser.download.dir'] = Capybara.save_path profile['browser.download.dir'] = Capybara.save_path
profile['browser.download.folderList'] = 2 profile['browser.download.folderList'] = 2
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv' profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
profile['browser.startup.homepage'] = 'about:blank' # workaround bug in Selenium 4 alpha4-7
end end
Capybara.register_driver :selenium_firefox do |app| Capybara.register_driver :selenium_firefox do |app|
# ::Selenium::WebDriver.logger.level = "debug" # ::Selenium::WebDriver.logger.level = "debug"
Capybara::Selenium::Driver.new( version = Capybara::Selenium::Driver.load_selenium
app, driver_options = { browser: :firefox, timeout: 31 }.tap do |opts|
browser: :firefox, if version >= Gem::Version.new('4.0.0.alpha6')
options: browser_options, opts[:capabilities] = browser_options
timeout: 31 else
opts[:options] = browser_options
end
# Get a trace level log from geckodriver # Get a trace level log from geckodriver
# :driver_opts => { args: ['-vv'] } # :driver_opts => { args: ['-vv'] }
) end
Capybara::Selenium::Driver.new(app, **driver_options)
end end
Capybara.register_driver :selenium_firefox_not_clear_storage do |app| Capybara.register_driver :selenium_firefox_not_clear_storage do |app|
Capybara::Selenium::Driver.new( version = Capybara::Selenium::Driver.load_selenium
app, driver_options = { browser: :firefox, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
browser: :firefox, if version >= Gem::Version.new('4.0.0.alpha6')
clear_local_storage: false, opts[:capabilities] = browser_options
clear_session_storage: false, else
options: browser_options opts[:options] = browser_options
) end
end
Capybara::Selenium::Driver.new(app, **driver_options)
end end
module TestSessions module TestSessions