mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Enable rack_test driver to reload nodes if stale
This commit is contained in:
parent
8930306e2f
commit
3d9c6997b0
7 changed files with 71 additions and 10 deletions
|
@ -83,11 +83,18 @@ module Capybara
|
|||
yield
|
||||
rescue StandardError => err
|
||||
session.raise_server_error!
|
||||
raise err unless driver.wait? && catch_error?(err, errors)
|
||||
raise err unless catch_error?(err, errors)
|
||||
|
||||
if driver.wait?
|
||||
raise err if timer.expired?
|
||||
|
||||
sleep(0.01)
|
||||
reload if session_options.automatic_reload
|
||||
else
|
||||
old_base = @base
|
||||
reload if session_options.automatic_reload
|
||||
raise err if old_base == @base
|
||||
end
|
||||
retry
|
||||
ensure
|
||||
session.synchronized = false
|
||||
|
|
|
@ -102,4 +102,8 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
|
|||
def put(*args, &block); browser.put(*args, &block); end
|
||||
def delete(*args, &block); browser.delete(*args, &block); end
|
||||
def header(key, value); browser.header(key, value); end
|
||||
|
||||
def invalid_element_errors
|
||||
[ Capybara::RackTest::Errors::StaleElementReferenceError ]
|
||||
end
|
||||
end
|
||||
|
|
6
lib/capybara/rack_test/errors.rb
Normal file
6
lib/capybara/rack_test/errors.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Capybara::RackTest::Errors
|
||||
class StaleElementReferenceError < StandardError
|
||||
end
|
||||
end
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'capybara/rack_test/errors'
|
||||
|
||||
class Capybara::RackTest::Node < Capybara::Driver::Node
|
||||
BLOCK_ELEMENTS = %w[p h1 h2 h3 h4 h5 h6 ol ul pre address blockquote dl div fieldset form hr noscript table].freeze
|
||||
|
||||
|
@ -106,14 +108,23 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|||
native.path
|
||||
end
|
||||
|
||||
def find_xpath(locator)
|
||||
def find_xpath(locator, **_hints)
|
||||
native.xpath(locator).map { |el| self.class.new(driver, el) }
|
||||
end
|
||||
|
||||
def find_css(locator)
|
||||
def find_css(locator, **_hints)
|
||||
native.css(locator, Capybara::RackTest::CSSHandlers.new).map { |el| self.class.new(driver, el) }
|
||||
end
|
||||
|
||||
self.public_instance_methods(false).each do |meth_name|
|
||||
alias_method "unchecked_#{meth_name}", meth_name
|
||||
private "unchecked_#{meth_name}"
|
||||
define_method meth_name do |*args|
|
||||
stale_check
|
||||
send("unchecked_#{meth_name}", *args)
|
||||
end
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
native == other.native
|
||||
end
|
||||
|
@ -141,6 +152,10 @@ protected
|
|||
|
||||
private
|
||||
|
||||
def stale_check
|
||||
raise Capybara::RackTest::Errors::StaleElementReferenceError unless native.document == driver.dom
|
||||
end
|
||||
|
||||
def deselect_options
|
||||
select_node.find_xpath('.//option[@selected]').each { |node| node.native.remove_attribute('selected') }
|
||||
end
|
||||
|
|
|
@ -79,7 +79,7 @@ module Capybara
|
|||
browser.send(:bridge).send(:read_atom, 'isDisplayed')
|
||||
rescue StandardError
|
||||
# If the atom doesn't exist or other error
|
||||
""
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,6 +26,29 @@ Capybara::SpecHelper.spec '#within' do
|
|||
end
|
||||
expect(@session).to have_content('Bar')
|
||||
end
|
||||
|
||||
it 'should reload the node if the page is changed' do
|
||||
@session.within(:css, '#for_foo') do
|
||||
@session.visit('/with_scope_other')
|
||||
expect(@session).to have_content('Different text')
|
||||
end
|
||||
end
|
||||
|
||||
it 'should reload multiple nodes if the page is changed' do
|
||||
@session.within(:css, '#for_bar') do
|
||||
@session.within(:css, 'form[action="/redirect"]') do
|
||||
@session.refresh
|
||||
expect(@session).to have_content('First Name')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'should error if the page is changed and a matching node no longer exists' do
|
||||
@session.within(:css, '#for_foo') do
|
||||
@session.visit('/')
|
||||
expect { @session.text }.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with XPath selector' do
|
||||
|
|
6
lib/capybara/spec/views/with_scope_other.erb
Normal file
6
lib/capybara/spec/views/with_scope_other.erb
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
<h1>This page is used for testing various scopes</h1>
|
||||
|
||||
<p id="for_foo">
|
||||
Different text same wrapper id
|
||||
</p>
|
Loading…
Reference in a new issue