Fix access to specializations when Selenium::Driver is subclassed
The specializations are stored in a class instance variable. However, they are accessed from the specialize_driver method via `self.class`. Previously if this method was called on an instance of a subclass of Selenium::Driver, then it accessed the class instance variable associated with the subclass (which is nil by default) and not the class instance variable associated with the Selenium::Driver class as intended resulting in an exception like this: NoMethodError: private method `select' called for nil:NilClass ./lib/capybara/selenium/driver.rb:417:in `specialize_driver' ./lib/capybara/selenium/driver.rb:49:in `browser' ./lib/capybara/selenium/driver.rb:66:in `visit' ./lib/capybara/session.rb:277:in `visit' ./spec/selenium_spec_chrome.rb:118:in `block (3 levels) in <top (required)>' This commit adds a spec using a subclass of Selenium::Driver with Chrome to demonstrate the problem and fixes it by changing the specialize_driver method to access the specializations via the explicitly specified class name. An alternative fix would be to use a class variable for specializations and do away with the class attribute reader altogether.
This commit is contained in:
parent
a62c7b32c5
commit
e382792352
|
@ -414,7 +414,7 @@ private
|
||||||
|
|
||||||
def specialize_driver
|
def specialize_driver
|
||||||
browser_type = browser.browser
|
browser_type = browser.browser
|
||||||
self.class.specializations.select { |k, _v| k === browser_type }.each_value do |specialization| # rubocop:disable Style/CaseEquality
|
Capybara::Selenium::Driver.specializations.select { |k, _v| k === browser_type }.each_value do |specialization| # rubocop:disable Style/CaseEquality
|
||||||
extend specialization
|
extend specialization
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,6 +27,11 @@ Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
|
||||||
Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
|
Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
|
||||||
|
subclass = Class.new(Capybara::Selenium::Driver)
|
||||||
|
subclass.new(app, browser: :chrome, options: browser_options, timeout: 30)
|
||||||
|
end
|
||||||
|
|
||||||
module TestSessions
|
module TestSessions
|
||||||
Chrome = Capybara::Session.new(CHROME_DRIVER, TestApp)
|
Chrome = Capybara::Session.new(CHROME_DRIVER, TestApp)
|
||||||
end
|
end
|
||||||
|
@ -106,4 +111,12 @@ RSpec.describe 'Capybara::Session with chrome' do
|
||||||
expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
|
expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'using subclass of selenium driver' do
|
||||||
|
it 'works' do
|
||||||
|
session = Capybara::Session.new(:selenium_driver_subclass_with_chrome, TestApp)
|
||||||
|
session.visit('/form')
|
||||||
|
expect(session).to have_current_path('/form')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue