mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Session#locate - return node identified by locator or raise ElementNotFound(using desc)
- Replaced usage of wait_for with locate. - wait_until back to raising error instead of returning false (This is key) - wait_for_condition removed Capybara::Session with culerity driver#wait_until - should wait for block to return true - should raise Capybara::TimeoutError if block doesn't return true within timeout - should accept custom timeout in seconds - should default to Capybara.default_wait_time before timeout Capybara::Session with culerity driver#locate - should find the first element using the given locator - should raise ElementNotFound with specified fail message if nothing was found - should accept an XPath instance and respect the order of paths Capybara::Session with culerity driver#locate within a scope - should find the first element using the given locator Capybara::Session with culerity driver#locate - should wait for asynchronous load
This commit is contained in:
parent
e41c757394
commit
8a0064cc1b
5 changed files with 89 additions and 87 deletions
|
@ -1,3 +1,5 @@
|
|||
require 'capybara/wait_until'
|
||||
|
||||
module Capybara
|
||||
class Session
|
||||
include Searchable
|
||||
|
@ -38,65 +40,56 @@ module Capybara
|
|||
end
|
||||
|
||||
def click(locator)
|
||||
link = wait_for(XPath.link(locator).button(locator))
|
||||
raise Capybara::ElementNotFound, "no link or button '#{locator}' found" unless link
|
||||
link.click
|
||||
msg = "no link or button '#{locator}' found"
|
||||
locate(XPath.link(locator).button(locator), msg).click
|
||||
end
|
||||
|
||||
def click_link(locator)
|
||||
link = wait_for(XPath.link(locator))
|
||||
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
|
||||
link.click
|
||||
msg = "no link with title, id or text '#{locator}' found"
|
||||
locate(XPath.link(locator), msg).click
|
||||
end
|
||||
|
||||
def click_button(locator)
|
||||
button = wait_for(XPath.button(locator))
|
||||
raise Capybara::ElementNotFound, "no button with value or id or text '#{locator}' found" unless button
|
||||
button.click
|
||||
msg = "no button with value or id or text '#{locator}' found"
|
||||
locate(XPath.button(locator)).click
|
||||
end
|
||||
|
||||
def drag(source_locator, target_locator)
|
||||
source = wait_for(source_locator)
|
||||
raise Capybara::ElementNotFound, "drag source '#{source_locator}' not found on page" unless source
|
||||
target = wait_for(target_locator)
|
||||
raise Capybara::ElementNotFound, "drag target '#{target_locator}' not found on page" unless target
|
||||
source = locate(source_locator, "drag source '#{source_locator}' not found on page")
|
||||
|
||||
target = locate(target_locator, "drag target '#{target_locator}' not found on page")
|
||||
|
||||
source.drag_to(target)
|
||||
end
|
||||
|
||||
def fill_in(locator, options={})
|
||||
field = wait_for(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
|
||||
field.set(options[:with])
|
||||
msg = "cannot fill in, no text field, text area or password field with id or label '#{locator}' found"
|
||||
locate(XPath.fillable_field(locator), msg).set(options[:with])
|
||||
end
|
||||
|
||||
def choose(locator)
|
||||
field = wait_for(XPath.radio_button(locator))
|
||||
raise Capybara::ElementNotFound, "cannot choose field, no radio button with id or label '#{locator}' found" unless field
|
||||
field.set(true)
|
||||
msg = "cannot choose field, no radio button with id or label '#{locator}' found"
|
||||
locate(XPath.radio_button(locator), msg).set(true)
|
||||
end
|
||||
|
||||
def check(locator)
|
||||
field = wait_for(XPath.checkbox(locator))
|
||||
raise Capybara::ElementNotFound, "cannot check field, no checkbox with id or label '#{locator}' found" unless field
|
||||
field.set(true)
|
||||
msg = "cannot check field, no checkbox with id or label '#{locator}' found"
|
||||
locate(XPath.checkbox(locator), msg).set(true)
|
||||
end
|
||||
|
||||
def uncheck(locator)
|
||||
field = wait_for(XPath.checkbox(locator))
|
||||
raise Capybara::ElementNotFound, "cannot uncheck field, no checkbox with id or label '#{locator}' found" unless field
|
||||
field.set(false)
|
||||
msg = "cannot uncheck field, no checkbox with id or label '#{locator}' found"
|
||||
locate(XPath.checkbox(locator), msg).set(false)
|
||||
end
|
||||
|
||||
def select(value, options={})
|
||||
field = wait_for(XPath.select(options[:from]))
|
||||
raise Capybara::ElementNotFound, "cannot select option, no select box with id or label '#{options[:from]}' found" unless field
|
||||
field.select(value)
|
||||
msg = "cannot select option, no select box with id or label '#{options[:from]}' found"
|
||||
locate(XPath.select(options[:from])).select(value)
|
||||
end
|
||||
|
||||
def attach_file(locator, path)
|
||||
field = wait_for(XPath.file_field(locator))
|
||||
raise Capybara::ElementNotFound, "cannot attach file, no file field with id or label '#{locator}' found" unless field
|
||||
field.set(path)
|
||||
msg = "cannot attach file, no file field with id or label '#{locator}' found"
|
||||
locate(XPath.file_field(locator)).set(path)
|
||||
end
|
||||
|
||||
def body
|
||||
|
@ -106,7 +99,7 @@ module Capybara
|
|||
def within(kind, scope=nil)
|
||||
kind, scope = Capybara.default_selector, kind unless scope
|
||||
scope = XPath.from_css(scope) if kind == :css
|
||||
raise Capybara::ElementNotFound, "scope '#{scope}' not found on page" unless wait_for(scope)
|
||||
locate(scope, "scope '#{scope}' not found on page")
|
||||
scopes.push(scope)
|
||||
yield
|
||||
scopes.pop
|
||||
|
@ -129,25 +122,29 @@ module Capybara
|
|||
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
||||
end
|
||||
|
||||
def wait_for(locator)
|
||||
wait_until { find(locator) }
|
||||
#return node identified by locator or raise ElementNotFound(using desc)
|
||||
def locate(locator, fail_msg = nil)
|
||||
|
||||
fail_msg ||= "Unable to locate '#{locator}'"
|
||||
|
||||
node = nil
|
||||
begin
|
||||
if driver.wait?
|
||||
node = wait_until { find(locator) }
|
||||
else
|
||||
node = find(locator)
|
||||
end
|
||||
rescue Capybara::TimeoutError; end
|
||||
|
||||
raise Capybara::ElementNotFound, fail_msg unless node
|
||||
|
||||
node
|
||||
end
|
||||
|
||||
def wait_for_condition(script)
|
||||
wait_until { evaluate_script(script) }
|
||||
def wait_until(timeout = Capybara.default_wait_time)
|
||||
WaitUntil.timeout(timeout) { yield }
|
||||
end
|
||||
|
||||
def wait_until
|
||||
return yield unless driver.wait?
|
||||
10.times do
|
||||
if result = yield
|
||||
return result
|
||||
end
|
||||
sleep(0.1)
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def evaluate_script(script)
|
||||
driver.evaluate_script(script)
|
||||
end
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
module WaitForSpec
|
||||
shared_examples_for "wait_for" do
|
||||
describe '#wait_for' do
|
||||
module LocateSpec
|
||||
shared_examples_for "locate" do
|
||||
describe '#locate' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
end
|
||||
|
||||
it "should find the first element using the given locator" do
|
||||
@session.wait_for('//h1').text.should == 'This is a test'
|
||||
@session.wait_for("//input[@id='test_field']")[:value].should == 'monkey'
|
||||
@session.locate('//h1').text.should == 'This is a test'
|
||||
@session.locate("//input[@id='test_field']")[:value].should == 'monkey'
|
||||
end
|
||||
|
||||
it "should return nil when nothing was found" do
|
||||
@session.wait_for('//div[@id="nosuchthing"]').should be_nil
|
||||
it "should raise ElementNotFound with specified fail message if nothing was found" do
|
||||
running do
|
||||
@session.locate('//div[@id="nosuchthing"]', 'arghh').should be_nil
|
||||
end.should raise_error(Capybara::ElementNotFound, "arghh")
|
||||
end
|
||||
|
||||
it "should accept an XPath instance and respect the order of paths" do
|
||||
@session.visit('/form')
|
||||
@xpath = Capybara::XPath.text_field('Name')
|
||||
@session.wait_for(@xpath).value.should == 'John Smith'
|
||||
@session.locate(@xpath).value.should == 'John Smith'
|
||||
end
|
||||
|
||||
context "within a scope" do
|
||||
|
@ -27,7 +29,7 @@ module WaitForSpec
|
|||
|
||||
it "should find the first element using the given locator" do
|
||||
@session.within(:xpath, "//div[@id='for_bar']") do
|
||||
@session.wait_for('//li').text.should =~ /With Simple HTML/
|
||||
@session.locate('//li').text.should =~ /With Simple HTML/
|
||||
end
|
||||
end
|
||||
end
|
|
@ -39,7 +39,7 @@ shared_examples_for "session" do
|
|||
it_should_behave_like "has_xpath"
|
||||
it_should_behave_like "select"
|
||||
it_should_behave_like "uncheck"
|
||||
it_should_behave_like "wait_for"
|
||||
it_should_behave_like "locate"
|
||||
it_should_behave_like "within"
|
||||
it_should_behave_like "current_url"
|
||||
end
|
||||
|
|
|
@ -10,17 +10,24 @@ shared_examples_for "session with javascript support" do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#wait_for' do
|
||||
describe '#locate' do
|
||||
it "should wait for asynchronous load" do
|
||||
@session.visit('/with_js')
|
||||
@session.click_link('Click me')
|
||||
@session.wait_for("//a[contains(.,'Has been clicked')]")[:href].should == '#'
|
||||
@session.locate("//a[contains(.,'Has been clicked')]")[:href].should == '#'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#wait_until' do
|
||||
before do
|
||||
@default_timeout = Capybara.default_wait_time
|
||||
end
|
||||
|
||||
it "should wait for block to return true" do
|
||||
after do
|
||||
Capybara.default_wait_time = @default_wait_time
|
||||
end
|
||||
|
||||
it "should wait for block to return true" do
|
||||
@session.visit('/with_js')
|
||||
@session.select('My Waiting Option', :from => 'waiter')
|
||||
@session.evaluate_script('activeRequests == 1').should be_true
|
||||
|
@ -30,21 +37,31 @@ shared_examples_for "session with javascript support" do
|
|||
@session.evaluate_script('activeRequests == 0').should be_true
|
||||
end
|
||||
|
||||
it "should return false if block doesn't return true within timeout" do
|
||||
it "should raise Capybara::TimeoutError if block doesn't return true within timeout" do
|
||||
@session.visit('/with_html')
|
||||
|
||||
@session.wait_until { false }.should be_nil
|
||||
Proc.new do
|
||||
@session.wait_until(0.1) do
|
||||
@session.find('//div[@id="nosuchthing"]')
|
||||
end
|
||||
end.should raise_error(::Capybara::TimeoutError)
|
||||
end
|
||||
|
||||
it "should accept custom timeout in seconds" do
|
||||
start = Time.now
|
||||
Capybara.default_wait_time = 5
|
||||
begin
|
||||
@session.wait_until(0.1) { false }
|
||||
rescue Capybara::TimeoutError; end
|
||||
(Time.now - start).should be_close(0.1, 0.1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#wait_for_condition' do
|
||||
it "should wait for condition to be true" do
|
||||
@session.visit('/with_js')
|
||||
@session.select('My Waiting Option', :from => 'waiter')
|
||||
@session.evaluate_script('activeRequests == 1').should be_true
|
||||
@session.wait_for_condition('activeRequests == 0').should be_true
|
||||
@session.evaluate_script('activeRequests == 0').should be_true
|
||||
it "should default to Capybara.default_wait_time before timeout" do
|
||||
start = Time.now
|
||||
Capybara.default_wait_time = 0.2
|
||||
begin
|
||||
@session.wait_until { false }
|
||||
rescue Capybara::TimeoutError; end
|
||||
(Time.now - start).should be_close(0.2, 0.1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,18 +12,4 @@ shared_examples_for "session without javascript support" do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#wait_until' do
|
||||
it "should not wait for asynchronous load" do
|
||||
@session.visit('/with_html')
|
||||
|
||||
before_time = Time.new
|
||||
|
||||
@session.wait_until do
|
||||
@session.find('//div[@id="nosuchthing"]')
|
||||
end.should be_nil
|
||||
|
||||
(Time.now - before_time).should be < 2
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue