mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Refactored automatic reloading
This commit is contained in:
parent
20c9538f5d
commit
a3a75647c0
5 changed files with 59 additions and 49 deletions
|
@ -39,6 +39,21 @@ module Capybara
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def wait_until(seconds=Capybara.default_wait_time)
|
||||||
|
start_time = Time.now
|
||||||
|
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
rescue => e
|
||||||
|
raise e unless wait?
|
||||||
|
raise e unless (driver.respond_to?(:invalid_element_errors) and driver.invalid_element_errors.include?(e.class)) or e.is_a?(Capybara::ElementNotFound)
|
||||||
|
raise e if (Time.now - start_time) >= seconds
|
||||||
|
sleep(0.05)
|
||||||
|
reload if Capybara.automatic_reload
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def wait?
|
def wait?
|
||||||
driver.wait?
|
driver.wait?
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ module Capybara
|
||||||
# @return [Object] The native element from the driver, this allows access to driver specific methods
|
# @return [Object] The native element from the driver, this allows access to driver specific methods
|
||||||
#
|
#
|
||||||
def native
|
def native
|
||||||
carefully { base.native }
|
wait_until { base.native }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -41,7 +41,7 @@ module Capybara
|
||||||
# @return [String] The text of the element
|
# @return [String] The text of the element
|
||||||
#
|
#
|
||||||
def text
|
def text
|
||||||
carefully { base.text }
|
wait_until { base.text }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -54,7 +54,7 @@ module Capybara
|
||||||
# @return [String] The value of the attribute
|
# @return [String] The value of the attribute
|
||||||
#
|
#
|
||||||
def [](attribute)
|
def [](attribute)
|
||||||
carefully { base[attribute] }
|
wait_until { base[attribute] }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -62,7 +62,7 @@ module Capybara
|
||||||
# @return [String] The value of the form element
|
# @return [String] The value of the form element
|
||||||
#
|
#
|
||||||
def value
|
def value
|
||||||
carefully { base.value }
|
wait_until { base.value }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -72,7 +72,7 @@ module Capybara
|
||||||
# @param [String] value The new value
|
# @param [String] value The new value
|
||||||
#
|
#
|
||||||
def set(value)
|
def set(value)
|
||||||
carefully { base.set(value) }
|
wait_until { base.set(value) }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -80,7 +80,7 @@ module Capybara
|
||||||
# Select this node if is an option element inside a select tag
|
# Select this node if is an option element inside a select tag
|
||||||
#
|
#
|
||||||
def select_option
|
def select_option
|
||||||
carefully { base.select_option }
|
wait_until { base.select_option }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -88,7 +88,7 @@ module Capybara
|
||||||
# Unselect this node if is an option element inside a multiple select tag
|
# Unselect this node if is an option element inside a multiple select tag
|
||||||
#
|
#
|
||||||
def unselect_option
|
def unselect_option
|
||||||
carefully { base.unselect_option }
|
wait_until { base.unselect_option }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -96,7 +96,7 @@ module Capybara
|
||||||
# Click the Element
|
# Click the Element
|
||||||
#
|
#
|
||||||
def click
|
def click
|
||||||
carefully { base.click }
|
wait_until { base.click }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -104,7 +104,7 @@ module Capybara
|
||||||
# @return [String] The tag name of the element
|
# @return [String] The tag name of the element
|
||||||
#
|
#
|
||||||
def tag_name
|
def tag_name
|
||||||
carefully { base.tag_name }
|
wait_until { base.tag_name }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -115,7 +115,7 @@ module Capybara
|
||||||
# @return [Boolean] Whether the element is visible
|
# @return [Boolean] Whether the element is visible
|
||||||
#
|
#
|
||||||
def visible?
|
def visible?
|
||||||
carefully { base.visible? }
|
wait_until { base.visible? }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -125,7 +125,7 @@ module Capybara
|
||||||
# @return [Boolean] Whether the element is checked
|
# @return [Boolean] Whether the element is checked
|
||||||
#
|
#
|
||||||
def checked?
|
def checked?
|
||||||
carefully { base.checked? }
|
wait_until { base.checked? }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -135,7 +135,7 @@ module Capybara
|
||||||
# @return [Boolean] Whether the element is selected
|
# @return [Boolean] Whether the element is selected
|
||||||
#
|
#
|
||||||
def selected?
|
def selected?
|
||||||
carefully { base.selected? }
|
wait_until { base.selected? }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -145,7 +145,7 @@ module Capybara
|
||||||
# @return [String] An XPath expression
|
# @return [String] An XPath expression
|
||||||
#
|
#
|
||||||
def path
|
def path
|
||||||
carefully { base.path }
|
wait_until { base.path }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -156,7 +156,7 @@ module Capybara
|
||||||
# @param [String] event The name of the event to trigger
|
# @param [String] event The name of the event to trigger
|
||||||
#
|
#
|
||||||
def trigger(event)
|
def trigger(event)
|
||||||
carefully { base.trigger(event) }
|
wait_until { base.trigger(event) }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -170,19 +170,19 @@ module Capybara
|
||||||
# @param [Capybara::Element] node The element to drag to
|
# @param [Capybara::Element] node The element to drag to
|
||||||
#
|
#
|
||||||
def drag_to(node)
|
def drag_to(node)
|
||||||
carefully { base.drag_to(node.base) }
|
wait_until { base.drag_to(node.base) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def find(*args)
|
def find(*args)
|
||||||
carefully { super }
|
wait_until { super }
|
||||||
end
|
end
|
||||||
|
|
||||||
def first(*args)
|
def first(*args)
|
||||||
carefully { super }
|
wait_until { super }
|
||||||
end
|
end
|
||||||
|
|
||||||
def all(*args)
|
def all(*args)
|
||||||
carefully { super }
|
wait_until { super }
|
||||||
end
|
end
|
||||||
|
|
||||||
def reload
|
def reload
|
||||||
|
@ -196,20 +196,6 @@ module Capybara
|
||||||
rescue NotSupportedByDriverError
|
rescue NotSupportedByDriverError
|
||||||
%(#<Capybara::Element tag="#{tag_name}">)
|
%(#<Capybara::Element tag="#{tag_name}">)
|
||||||
end
|
end
|
||||||
|
|
||||||
def carefully(seconds=Capybara.default_wait_time)
|
|
||||||
start_time = Time.now
|
|
||||||
|
|
||||||
begin
|
|
||||||
yield
|
|
||||||
rescue => e
|
|
||||||
raise e unless driver.respond_to?(:invalid_element_errors) and driver.invalid_element_errors.include?(e.class)
|
|
||||||
raise e if (Time.now - start_time) >= seconds
|
|
||||||
sleep(0.05)
|
|
||||||
reload
|
|
||||||
retry
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,18 +24,7 @@ module Capybara
|
||||||
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
|
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
|
||||||
#
|
#
|
||||||
def find(*args)
|
def find(*args)
|
||||||
begin
|
wait_until { first(*args) or raise_find_error(*args) }
|
||||||
node = wait_conditionally_until { first(*args) }
|
|
||||||
rescue TimeoutError
|
|
||||||
end
|
|
||||||
unless node
|
|
||||||
options = extract_normalized_options(args)
|
|
||||||
normalized = Capybara::Selector.normalize(*args)
|
|
||||||
message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}"
|
|
||||||
message = normalized.failure_message.call(self, normalized) if normalized.failure_message
|
|
||||||
raise Capybara::ElementNotFound, message
|
|
||||||
end
|
|
||||||
return node
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -157,16 +146,20 @@ module Capybara
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def raise_find_error(*args)
|
||||||
|
options = extract_normalized_options(args)
|
||||||
|
normalized = Capybara::Selector.normalize(*args)
|
||||||
|
message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}"
|
||||||
|
message = normalized.failure_message.call(self, normalized) if normalized.failure_message
|
||||||
|
raise Capybara::ElementNotFound, message
|
||||||
|
end
|
||||||
|
|
||||||
def find_in_base(selector, xpath)
|
def find_in_base(selector, xpath)
|
||||||
base.find(xpath).map do |node|
|
base.find(xpath).map do |node|
|
||||||
Capybara::Node::Element.new(session, node, self, selector)
|
Capybara::Node::Element.new(session, node, self, selector)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def wait_conditionally_until
|
|
||||||
if wait? then session.wait_until { yield } else yield end
|
|
||||||
end
|
|
||||||
|
|
||||||
def extract_normalized_options(args)
|
def extract_normalized_options(args)
|
||||||
options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ $(function() {
|
||||||
});
|
});
|
||||||
$('#reload-link').click(function() {
|
$('#reload-link').click(function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$('#reload-me').replaceWith('<div id="reload-me"><em>RELOADED</em></div>');
|
$('#reload-me').replaceWith('<div id="reload-me"><em><a>RELOADED</a></em></div>');
|
||||||
}, 250)
|
}, 250)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,6 +38,14 @@ shared_examples_for "session with javascript support" do
|
||||||
node.reload.text.should == 'RELOADED'
|
node.reload.text.should == 'RELOADED'
|
||||||
node.text.should == 'RELOADED'
|
node.text.should == 'RELOADED'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should not automatically reload" do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
node = @session.find(:css, '#reload-me')
|
||||||
|
@session.click_link('Reload!')
|
||||||
|
sleep(0.3)
|
||||||
|
running { node.text.should == 'RELOADED' }.should raise_error
|
||||||
|
end
|
||||||
after { Capybara.automatic_reload = true }
|
after { Capybara.automatic_reload = true }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -57,6 +65,14 @@ shared_examples_for "session with javascript support" do
|
||||||
sleep(0.3)
|
sleep(0.3)
|
||||||
node.text.should == 'RELOADED'
|
node.text.should == 'RELOADED'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should reload a node automatically when using find" do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
node = @session.find(:css, '#reload-me')
|
||||||
|
@session.click_link('Reload!')
|
||||||
|
sleep(0.3)
|
||||||
|
node.find(:css, 'a').text.should == 'RELOADED'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue