diff --git a/lib/capybara/node/element.rb b/lib/capybara/node/element.rb index 8bacc1f7b..8754c02b0 100644 --- a/lib/capybara/node/element.rb +++ b/lib/capybara/node/element.rb @@ -514,7 +514,8 @@ def evaluate_async_script(script, *args) def reload if @allow_reload begin - reloaded = query_scope.reload.first(@query.name, @query.locator, @query.options) + reloaded = @query.resolve_for(query_scope.reload)&.first + @base = reloaded.base if reloaded rescue StandardError => e raise e unless catch_error?(e) diff --git a/lib/capybara/queries/ancestor_query.rb b/lib/capybara/queries/ancestor_query.rb index a351f12d3..531bd23f5 100644 --- a/lib/capybara/queries/ancestor_query.rb +++ b/lib/capybara/queries/ancestor_query.rb @@ -3,20 +3,16 @@ module Capybara module Queries class AncestorQuery < Capybara::Queries::SelectorQuery - def initialize(*args) - super - @count_options = {} - COUNT_KEYS.each do |key| - @count_options[key] = @options.delete(key) if @options.key?(key) - end - end - # @api private def resolve_for(node, exact = nil) @child_node = node + node.synchronize do match_results = super(node.session.current_scope, exact) - node.all(:xpath, XPath.ancestor, **@count_options) { |el| match_results.include?(el) } + ancestors = node.find_xpath(XPath.ancestor.to_s) + .map(&method(:to_element)) + .select { |el| match_results.include?(el) } + Capybara::Result.new(ancestors, self) end end diff --git a/lib/capybara/queries/sibling_query.rb b/lib/capybara/queries/sibling_query.rb index c803b9103..c550573d5 100644 --- a/lib/capybara/queries/sibling_query.rb +++ b/lib/capybara/queries/sibling_query.rb @@ -3,21 +3,15 @@ module Capybara module Queries class SiblingQuery < SelectorQuery - def initialize(*args) - super - @count_options = {} - COUNT_KEYS.each do |key| - @count_options[key] = @options.delete(key) if @options.key?(key) - end - end - # @api private def resolve_for(node, exact = nil) @sibling_node = node node.synchronize do match_results = super(node.session.current_scope, exact) - xpath = XPath.preceding_sibling + XPath.following_sibling - node.all(:xpath, xpath, **@count_options) { |el| match_results.include?(el) } + siblings = node.find_xpath((XPath.preceding_sibling + XPath.following_sibling).to_s) + .map(&method(:to_element)) + .select { |el| match_results.include?(el) } + Capybara::Result.new(siblings, self) end end diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb index 3ff160b71..065469846 100644 --- a/lib/capybara/spec/session/node_spec.rb +++ b/lib/capybara/spec/session/node_spec.rb @@ -1002,6 +1002,28 @@ end describe '#reload', requires: [:js] do + it 'should reload elements found via ancestor with CSS' do + @session.visit('/with_js') + node = @session.find(:css, '#reload-me em').ancestor(:css, 'div') + node.reload + expect(node[:id]).to eq 'reload-me' + end + + it 'should reload elements found via ancestor with XPath' do + @session.visit('/with_js') + node = @session.find(:css, '#reload-me em').ancestor(:xpath, './/div') + node.reload + expect(node[:id]).to eq 'reload-me' + end + + it 'should reload elements found via sibling' do + @session.visit('/with_js') + node = @session.find(:css, '#the-list li', text: 'Item 1').sibling(:css, 'li') + expect(node.text).to eq 'Item 2' + node.reload + expect(node.text).to eq 'Item 2' + end + context 'without automatic reload' do before { Capybara.automatic_reload = false }