mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Automatically wait for asynchonous loading
This commit is contained in:
parent
cd2b411ea2
commit
364affa757
10 changed files with 97 additions and 21 deletions
|
@ -21,12 +21,13 @@ module Capybara
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
autoload :Server, 'capybara/server'
|
autoload :Server, 'capybara/server'
|
||||||
autoload :Session, 'capybara/session'
|
autoload :Session, 'capybara/session'
|
||||||
autoload :Node, 'capybara/node'
|
autoload :Node, 'capybara/node'
|
||||||
autoload :XPath, 'capybara/xpath'
|
autoload :XPath, 'capybara/xpath'
|
||||||
|
|
||||||
module Driver
|
module Driver
|
||||||
|
autoload :Base, 'capybara/driver/base'
|
||||||
autoload :RackTest, 'capybara/driver/rack_test_driver'
|
autoload :RackTest, 'capybara/driver/rack_test_driver'
|
||||||
autoload :Culerity, 'capybara/driver/culerity_driver'
|
autoload :Culerity, 'capybara/driver/culerity_driver'
|
||||||
autoload :Selenium, 'capybara/driver/selenium_driver'
|
autoload :Selenium, 'capybara/driver/selenium_driver'
|
||||||
|
|
20
lib/capybara/driver/base.rb
Normal file
20
lib/capybara/driver/base.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class Capybara::Driver::Base
|
||||||
|
def visit(path)
|
||||||
|
raise "Not implemented"
|
||||||
|
end
|
||||||
|
|
||||||
|
def find(query)
|
||||||
|
raise "Not implemented"
|
||||||
|
end
|
||||||
|
|
||||||
|
def body
|
||||||
|
raise "Not implemented"
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch(*paths)
|
||||||
|
paths.find do |path|
|
||||||
|
result = find(path).first
|
||||||
|
return result if result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
require 'culerity'
|
require 'culerity'
|
||||||
|
|
||||||
class Capybara::Driver::Culerity
|
class Capybara::Driver::Culerity < Capybara::Driver::Base
|
||||||
class Node < Capybara::Node
|
class Node < Capybara::Node
|
||||||
def text
|
def text
|
||||||
node.text
|
node.text
|
||||||
|
@ -69,6 +69,15 @@ class Capybara::Driver::Culerity
|
||||||
def find(selector)
|
def find(selector)
|
||||||
browser.elements_by_xpath(selector).map { |node| Node.new(self, node) }
|
browser.elements_by_xpath(selector).map { |node| Node.new(self, node) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch(*paths)
|
||||||
|
8.times do
|
||||||
|
result = super
|
||||||
|
return result if result
|
||||||
|
sleep(0.1)
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ require 'rack/test'
|
||||||
require 'nokogiri'
|
require 'nokogiri'
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
|
||||||
class Capybara::Driver::RackTest
|
class Capybara::Driver::RackTest < Capybara::Driver::Base
|
||||||
class Node < Capybara::Node
|
class Node < Capybara::Node
|
||||||
def text
|
def text
|
||||||
node.text
|
node.text
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'selenium-webdriver'
|
require 'selenium-webdriver'
|
||||||
|
|
||||||
class Capybara::Driver::Selenium
|
class Capybara::Driver::Selenium < Capybara::Driver::Base
|
||||||
class Node < Capybara::Node
|
class Node < Capybara::Node
|
||||||
def text
|
def text
|
||||||
node.text
|
node.text
|
||||||
|
@ -83,6 +83,15 @@ class Capybara::Driver::Selenium
|
||||||
def find(selector)
|
def find(selector)
|
||||||
driver.find_elements(:xpath, selector).map { |node| Node.new(self, node) }
|
driver.find_elements(:xpath, selector).map { |node| Node.new(self, node) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch(*paths)
|
||||||
|
8.times do
|
||||||
|
result = super
|
||||||
|
return result if result
|
||||||
|
sleep(0.1)
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -38,37 +38,37 @@ module Capybara
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_in(locator, options={})
|
def fill_in(locator, options={})
|
||||||
field = get(XPath.fillable_field(locator))
|
field = fetch(XPath.fillable_field(locator))
|
||||||
raise Capybara::ElementNotFound, "cannot fill in, no text field, text area or password field with id or label '#{locator}' found" unless field
|
raise Capybara::ElementNotFound, "cannot fill in, no text field, text area or password field with id or label '#{locator}' found" unless field
|
||||||
field.set(options[:with])
|
field.set(options[:with])
|
||||||
end
|
end
|
||||||
|
|
||||||
def choose(locator)
|
def choose(locator)
|
||||||
field = get(XPath.radio_button(locator))
|
field = fetch(XPath.radio_button(locator))
|
||||||
raise Capybara::ElementNotFound, "cannot choose field, no radio button with id or label '#{locator}' found" unless field
|
raise Capybara::ElementNotFound, "cannot choose field, no radio button with id or label '#{locator}' found" unless field
|
||||||
field.set(true)
|
field.set(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check(locator)
|
def check(locator)
|
||||||
field = get(XPath.checkbox(locator))
|
field = fetch(XPath.checkbox(locator))
|
||||||
raise Capybara::ElementNotFound, "cannot check field, no checkbox with id or label '#{locator}' found" unless field
|
raise Capybara::ElementNotFound, "cannot check field, no checkbox with id or label '#{locator}' found" unless field
|
||||||
field.set(true)
|
field.set(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def uncheck(locator)
|
def uncheck(locator)
|
||||||
field = get(XPath.checkbox(locator))
|
field = fetch(XPath.checkbox(locator))
|
||||||
raise Capybara::ElementNotFound, "cannot uncheck field, no checkbox with id or label '#{locator}' found" unless field
|
raise Capybara::ElementNotFound, "cannot uncheck field, no checkbox with id or label '#{locator}' found" unless field
|
||||||
field.set(false)
|
field.set(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def select(value, options={})
|
def select(value, options={})
|
||||||
field = get(XPath.select(options[:from]))
|
field = fetch(XPath.select(options[:from]))
|
||||||
raise Capybara::ElementNotFound, "cannot select option, no select box with id or label '#{options[:from]}' found" unless field
|
raise Capybara::ElementNotFound, "cannot select option, no select box with id or label '#{options[:from]}' found" unless field
|
||||||
field.select(value)
|
field.select(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
def attach_file(locator, path)
|
def attach_file(locator, path)
|
||||||
field = get(XPath.file_field(locator))
|
field = fetch(XPath.file_field(locator))
|
||||||
raise Capybara::ElementNotFound, "cannot attach file, no file field with id or label '#{locator}' found" unless field
|
raise Capybara::ElementNotFound, "cannot attach file, no file field with id or label '#{locator}' found" unless field
|
||||||
field.set(path)
|
field.set(path)
|
||||||
end
|
end
|
||||||
|
@ -133,25 +133,22 @@ module Capybara
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_field(locator)
|
def find_field(locator)
|
||||||
get(XPath.field(locator))
|
fetch(XPath.field(locator))
|
||||||
end
|
end
|
||||||
alias_method :field_labeled, :find_field
|
alias_method :field_labeled, :find_field
|
||||||
|
|
||||||
def find_link(locator)
|
def find_link(locator)
|
||||||
get(XPath.link(locator))
|
fetch(XPath.link(locator))
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_button(locator)
|
def find_button(locator)
|
||||||
get(XPath.button(locator))
|
fetch(XPath.button(locator))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get(xpath)
|
def fetch(xpath)
|
||||||
xpath.paths.find do |path|
|
driver.fetch(*xpath.paths.map { |path| current_scope.to_s + path })
|
||||||
path = all(path).first
|
|
||||||
return path if path
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def css_to_xpath(css)
|
def css_to_xpath(css)
|
||||||
|
|
|
@ -19,5 +19,6 @@ describe Capybara::Session do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_should_behave_like "session"
|
it_should_behave_like "session"
|
||||||
|
it_should_behave_like "session with javascript support"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,5 +19,6 @@ describe Capybara::Session do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_should_behave_like "session"
|
it_should_behave_like "session"
|
||||||
|
it_should_behave_like "session with javascript support"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -790,6 +790,33 @@ shared_examples_for "session" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples_for "session with javascript support" do
|
||||||
|
describe '#click_link' do
|
||||||
|
it "should wait for asynchronous load" do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
@session.click_link('Click me')
|
||||||
|
@session.click_link('Has been clicked')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#click_button' do
|
||||||
|
it "should wait for asynchronous load" do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
@session.click_link('Click me')
|
||||||
|
@session.click_button('New Here')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#fill_in' do
|
||||||
|
it "should wait for asynchronous load" do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
@session.click_link('Click me')
|
||||||
|
@session.fill_in('new_field', :with => 'Testing...')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
describe Capybara::Session do
|
describe Capybara::Session do
|
||||||
context 'with non-existant driver' do
|
context 'with non-existant driver' do
|
||||||
it "should raise an error" do
|
it "should raise an error" do
|
||||||
|
|
|
@ -11,10 +11,19 @@
|
||||||
$('#drag').draggable();
|
$('#drag').draggable();
|
||||||
$('#drop').droppable({
|
$('#drop').droppable({
|
||||||
drop: function(event, ui) {
|
drop: function(event, ui) {
|
||||||
ui.draggable.remove()
|
ui.draggable.remove();
|
||||||
$(this).html('Dropped!');
|
$(this).html('Dropped!');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$('#clickable').click(function() {
|
||||||
|
var link = $(this);
|
||||||
|
setTimeout(function() {
|
||||||
|
$(link).after('<a href="#">Has been clicked</a>');
|
||||||
|
$(link).after('<input type="submit" value="New Here">');
|
||||||
|
$(link).after('<input type="text" id="new_field">');
|
||||||
|
}, 500);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
|
@ -30,5 +39,7 @@
|
||||||
<div id="drop">
|
<div id="drop">
|
||||||
<p>It should be dropped here.</p>
|
<p>It should be dropped here.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p><a href="#" id="clickable">Click me</a></p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue