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
|
@ -1,3 +1,5 @@
|
||||||
|
require 'capybara/wait_until'
|
||||||
|
|
||||||
module Capybara
|
module Capybara
|
||||||
class Session
|
class Session
|
||||||
include Searchable
|
include Searchable
|
||||||
|
@ -38,65 +40,56 @@ module Capybara
|
||||||
end
|
end
|
||||||
|
|
||||||
def click(locator)
|
def click(locator)
|
||||||
link = wait_for(XPath.link(locator).button(locator))
|
msg = "no link or button '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "no link or button '#{locator}' found" unless link
|
locate(XPath.link(locator).button(locator), msg).click
|
||||||
link.click
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_link(locator)
|
def click_link(locator)
|
||||||
link = wait_for(XPath.link(locator))
|
msg = "no link with title, id or text '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
|
locate(XPath.link(locator), msg).click
|
||||||
link.click
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_button(locator)
|
def click_button(locator)
|
||||||
button = wait_for(XPath.button(locator))
|
msg = "no button with value or id or text '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "no button with value or id or text '#{locator}' found" unless button
|
locate(XPath.button(locator)).click
|
||||||
button.click
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def drag(source_locator, target_locator)
|
def drag(source_locator, target_locator)
|
||||||
source = wait_for(source_locator)
|
source = locate(source_locator, "drag source '#{source_locator}' not found on page")
|
||||||
raise Capybara::ElementNotFound, "drag source '#{source_locator}' not found on page" unless source
|
|
||||||
target = wait_for(target_locator)
|
target = locate(target_locator, "drag target '#{target_locator}' not found on page")
|
||||||
raise Capybara::ElementNotFound, "drag target '#{target_locator}' not found on page" unless target
|
|
||||||
source.drag_to(target)
|
source.drag_to(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_in(locator, options={})
|
def fill_in(locator, options={})
|
||||||
field = wait_for(XPath.fillable_field(locator))
|
msg = "cannot fill in, no text field, text area or password field with id or label '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot fill in, no text field, text area or password field with id or label '#{locator}' found" unless field
|
locate(XPath.fillable_field(locator), msg).set(options[:with])
|
||||||
field.set(options[:with])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def choose(locator)
|
def choose(locator)
|
||||||
field = wait_for(XPath.radio_button(locator))
|
msg = "cannot choose field, no radio button with id or label '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot choose field, no radio button with id or label '#{locator}' found" unless field
|
locate(XPath.radio_button(locator), msg).set(true)
|
||||||
field.set(true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check(locator)
|
def check(locator)
|
||||||
field = wait_for(XPath.checkbox(locator))
|
msg = "cannot check field, no checkbox with id or label '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot check field, no checkbox with id or label '#{locator}' found" unless field
|
locate(XPath.checkbox(locator), msg).set(true)
|
||||||
field.set(true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def uncheck(locator)
|
def uncheck(locator)
|
||||||
field = wait_for(XPath.checkbox(locator))
|
msg = "cannot uncheck field, no checkbox with id or label '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot uncheck field, no checkbox with id or label '#{locator}' found" unless field
|
locate(XPath.checkbox(locator), msg).set(false)
|
||||||
field.set(false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def select(value, options={})
|
def select(value, options={})
|
||||||
field = wait_for(XPath.select(options[:from]))
|
msg = "cannot select option, no select box with id or label '#{options[:from]}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot select option, no select box with id or label '#{options[:from]}' found" unless field
|
locate(XPath.select(options[:from])).select(value)
|
||||||
field.select(value)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def attach_file(locator, path)
|
def attach_file(locator, path)
|
||||||
field = wait_for(XPath.file_field(locator))
|
msg = "cannot attach file, no file field with id or label '#{locator}' found"
|
||||||
raise Capybara::ElementNotFound, "cannot attach file, no file field with id or label '#{locator}' found" unless field
|
locate(XPath.file_field(locator)).set(path)
|
||||||
field.set(path)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def body
|
def body
|
||||||
|
@ -106,7 +99,7 @@ module Capybara
|
||||||
def within(kind, scope=nil)
|
def within(kind, scope=nil)
|
||||||
kind, scope = Capybara.default_selector, kind unless scope
|
kind, scope = Capybara.default_selector, kind unless scope
|
||||||
scope = XPath.from_css(scope) if kind == :css
|
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)
|
scopes.push(scope)
|
||||||
yield
|
yield
|
||||||
scopes.pop
|
scopes.pop
|
||||||
|
@ -129,23 +122,27 @@ module Capybara
|
||||||
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
||||||
end
|
end
|
||||||
|
|
||||||
def wait_for(locator)
|
#return node identified by locator or raise ElementNotFound(using desc)
|
||||||
wait_until { find(locator) }
|
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
|
end
|
||||||
|
|
||||||
def wait_for_condition(script)
|
def wait_until(timeout = Capybara.default_wait_time)
|
||||||
wait_until { evaluate_script(script) }
|
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
|
end
|
||||||
|
|
||||||
def evaluate_script(script)
|
def evaluate_script(script)
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
module WaitForSpec
|
module LocateSpec
|
||||||
shared_examples_for "wait_for" do
|
shared_examples_for "locate" do
|
||||||
describe '#wait_for' do
|
describe '#locate' do
|
||||||
before do
|
before do
|
||||||
@session.visit('/with_html')
|
@session.visit('/with_html')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should find the first element using the given locator" do
|
it "should find the first element using the given locator" do
|
||||||
@session.wait_for('//h1').text.should == 'This is a test'
|
@session.locate('//h1').text.should == 'This is a test'
|
||||||
@session.wait_for("//input[@id='test_field']")[:value].should == 'monkey'
|
@session.locate("//input[@id='test_field']")[:value].should == 'monkey'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil when nothing was found" do
|
it "should raise ElementNotFound with specified fail message if nothing was found" do
|
||||||
@session.wait_for('//div[@id="nosuchthing"]').should be_nil
|
running do
|
||||||
|
@session.locate('//div[@id="nosuchthing"]', 'arghh').should be_nil
|
||||||
|
end.should raise_error(Capybara::ElementNotFound, "arghh")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should accept an XPath instance and respect the order of paths" do
|
it "should accept an XPath instance and respect the order of paths" do
|
||||||
@session.visit('/form')
|
@session.visit('/form')
|
||||||
@xpath = Capybara::XPath.text_field('Name')
|
@xpath = Capybara::XPath.text_field('Name')
|
||||||
@session.wait_for(@xpath).value.should == 'John Smith'
|
@session.locate(@xpath).value.should == 'John Smith'
|
||||||
end
|
end
|
||||||
|
|
||||||
context "within a scope" do
|
context "within a scope" do
|
||||||
|
@ -27,7 +29,7 @@ module WaitForSpec
|
||||||
|
|
||||||
it "should find the first element using the given locator" do
|
it "should find the first element using the given locator" do
|
||||||
@session.within(:xpath, "//div[@id='for_bar']") 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
|
end
|
||||||
end
|
end
|
|
@ -39,7 +39,7 @@ shared_examples_for "session" do
|
||||||
it_should_behave_like "has_xpath"
|
it_should_behave_like "has_xpath"
|
||||||
it_should_behave_like "select"
|
it_should_behave_like "select"
|
||||||
it_should_behave_like "uncheck"
|
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 "within"
|
||||||
it_should_behave_like "current_url"
|
it_should_behave_like "current_url"
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,15 +10,22 @@ shared_examples_for "session with javascript support" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#wait_for' do
|
describe '#locate' do
|
||||||
it "should wait for asynchronous load" do
|
it "should wait for asynchronous load" do
|
||||||
@session.visit('/with_js')
|
@session.visit('/with_js')
|
||||||
@session.click_link('Click me')
|
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#wait_until' do
|
describe '#wait_until' do
|
||||||
|
before do
|
||||||
|
@default_timeout = Capybara.default_wait_time
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Capybara.default_wait_time = @default_wait_time
|
||||||
|
end
|
||||||
|
|
||||||
it "should wait for block to return true" do
|
it "should wait for block to return true" do
|
||||||
@session.visit('/with_js')
|
@session.visit('/with_js')
|
||||||
|
@ -30,21 +37,31 @@ shared_examples_for "session with javascript support" do
|
||||||
@session.evaluate_script('activeRequests == 0').should be_true
|
@session.evaluate_script('activeRequests == 0').should be_true
|
||||||
end
|
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.visit('/with_html')
|
||||||
|
Proc.new do
|
||||||
@session.wait_until { false }.should be_nil
|
@session.wait_until(0.1) do
|
||||||
|
@session.find('//div[@id="nosuchthing"]')
|
||||||
|
end
|
||||||
|
end.should raise_error(::Capybara::TimeoutError)
|
||||||
end
|
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 default to Capybara.default_wait_time before timeout" do
|
||||||
it "should wait for condition to be true" do
|
start = Time.now
|
||||||
@session.visit('/with_js')
|
Capybara.default_wait_time = 0.2
|
||||||
@session.select('My Waiting Option', :from => 'waiter')
|
begin
|
||||||
@session.evaluate_script('activeRequests == 1').should be_true
|
@session.wait_until { false }
|
||||||
@session.wait_for_condition('activeRequests == 0').should be_true
|
rescue Capybara::TimeoutError; end
|
||||||
@session.evaluate_script('activeRequests == 0').should be_true
|
(Time.now - start).should be_close(0.2, 0.1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,18 +12,4 @@ shared_examples_for "session without javascript support" do
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
Loading…
Reference in New Issue