diff --git a/lib/capybara/node/element.rb b/lib/capybara/node/element.rb index 89d50507..001ef91a 100644 --- a/lib/capybara/node/element.rb +++ b/lib/capybara/node/element.rb @@ -22,11 +22,12 @@ module Capybara # @see Capybara::Node # class Element < Base - def initialize(session, base, query_scope, query) + def initialize(session, base, query_scope, query, &reload_proc) super(session, base) @query_scope = query_scope @query = query @allow_reload = false + @reload_proc = reload_proc @query_idx = nil end @@ -550,7 +551,11 @@ module Capybara return self unless @allow_reload begin - reloaded = @query.resolve_for(query_scope.reload)[@query_idx.to_i] + reloaded = if @reload_proc + @reload_proc.call + else + @query.resolve_for(query_scope.reload)[@query_idx.to_i] + end @base = reloaded.base if reloaded rescue StandardError => e raise e unless catch_error?(e) diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 9e62c7da..ba705761 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -149,11 +149,12 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base end def active_element - build_node(browser.switch_to.active_element) + build_node(native_active_element) end def send_keys(*args) - active_element.native.send_keys(*args) + # Should this call the specialized nodes rather than native??? + native_active_element.send_keys(*args) end def save_screenshot(path, **_options) @@ -333,6 +334,10 @@ private args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg } end + def native_active_element + browser.switch_to.active_element + end + def clear_browser_state delete_all_cookies clear_storage diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index a55e44d9..d4ecab92 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -318,7 +318,9 @@ module Capybara # Not supported by Rack Test # def active_element - driver.active_element + Capybara::Node::Element.new(self, driver.active_element, nil, nil) do + active_element + end.tap(&:allow_reload!) end ## diff --git a/lib/capybara/spec/session/active_element_spec.rb b/lib/capybara/spec/session/active_element_spec.rb index 57502c53..a985c7b2 100644 --- a/lib/capybara/spec/session/active_element_spec.rb +++ b/lib/capybara/spec/session/active_element_spec.rb @@ -5,10 +5,22 @@ Capybara::SpecHelper.spec '#active_element', requires: [:js] do @session.visit('/form') @session.send_keys(:tab) - expect(@session.active_element).to eq(@session.find_by_id('form_title')) + expect(@session.active_element).to match_selector(:css, '#form_title'); @session.send_keys(:tab) - expect(@session.active_element).not_to eq(@session.find_by_id('form_title')) + expect(@session.active_element).not_to match_selector(:css, '#form_title'); + end + + it 'should support reloading' do + @session.visit('/form') + expect(@session.active_element).to match_selector(:css, 'body') + @session.execute_script <<-JS + window.setTimeout(() => { + document.querySelector('#form_title').focus(); + }, 1000) + JS + expect(@session.active_element).to match_selector(:css, 'body', wait: false) + expect(@session.active_element).to match_selector(:css, '#form_title', wait: 2) end end diff --git a/lib/capybara/spec/views/form.erb b/lib/capybara/spec/views/form.erb index 3ba23b6d..5c542b07 100644 --- a/lib/capybara/spec/views/form.erb +++ b/lib/capybara/spec/views/form.erb @@ -1,11 +1,10 @@ -