Skip to content

Commit

Permalink
Fix reloading of elements found via ancestor and sibling
Browse files Browse the repository at this point in the history
  • Loading branch information
twalpole committed Jul 25, 2019
1 parent f1139a5 commit ba12497
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
3 changes: 2 additions & 1 deletion lib/capybara/node/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 5 additions & 9 deletions lib/capybara/queries/ancestor_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 4 additions & 10 deletions lib/capybara/queries/sibling_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
22 changes: 22 additions & 0 deletions lib/capybara/spec/session/node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down

0 comments on commit ba12497

Please sign in to comment.