Permalink
Browse files

Raise an error when there are multiple elements found

  • Loading branch information...
jnicklas committed Jan 31, 2012
1 parent 588613a commit cc05b1d63b1201027da7b568a7bd0467df9f7e0a
@@ -24,7 +24,11 @@ module Finders
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
#
def find(*args)
wait_until { first(*args) or raise_find_error(*args) }
wait_until do
results = all(*args)
raise_find_error(*args) unless results.length == 1
results.first
end
end
##
View
@@ -19,9 +19,9 @@ def initialize(*args)
xpath = @selector.call(@locator)
if xpath.respond_to?(:to_xpaths)
@xpaths = xpath.to_xpaths
@xpaths = [xpath.to_xpath(:fuzzy)]
else
@xpaths = [xpath.to_s].flatten
@xpaths = [xpath.to_s]
end
end
@@ -51,15 +51,15 @@
context "with visible filter" do
after { Capybara.ignore_hidden_elements = false }
it "should only find visible nodes" do
@session.all("//a[@title='awesome title']").should have(2).elements
@session.all("//a[@title='awesome title']", :visible => true).should have(1).elements
@session.all(:css, "a.simple").should have(2).elements
@session.all(:css, "a.simple", :visible => true).should have(1).elements
Capybara.ignore_hidden_elements = true
@session.all("//a[@title='awesome title']").should have(1).elements
@session.all(:css, "a.simple").should have(1).elements
end
it "should only find invisible nodes" do
Capybara.ignore_hidden_elements = true
@session.all("//a[@title='awesome title']", :visible => false).should have(2).elements
@session.all(:css, "a.simple", :visible => false).should have(2).elements
end
end
@@ -24,30 +24,30 @@
context "with multipart form" do
it "should set a file path by id" do
@session.attach_file "form_document", @test_file_path
@session.click_button('Upload')
@session.click_button('Upload Single')
@session.body.should include(File.read(@test_file_path))
end
it "should set a file path by label" do
@session.attach_file "Document", @test_file_path
@session.click_button('Upload')
@session.attach_file "Single Document", @test_file_path
@session.click_button('Upload Single')
@session.body.should include(File.read(@test_file_path))
end
it "should not break if no file is submitted" do
@session.click_button('Upload')
@session.click_button('Upload Single')
@session.body.should include('No file uploaded')
end
it "should send content type text/plain when uploading a text file" do
@session.attach_file "Document", @test_file_path
@session.click_button 'Upload'
@session.attach_file "Single Document", @test_file_path
@session.click_button 'Upload Single'
@session.body.should include('text/plain')
end
it "should send content type image/jpeg when uploading an image" do
@session.attach_file "Document", @test_jpg_file_path
@session.click_button 'Upload'
@session.attach_file "Single Document", @test_jpg_file_path
@session.click_button 'Upload Single'
@session.body.should include('image/jpeg')
end
@@ -27,7 +27,7 @@
extract_results(@session)['no_action'].should == 'No Action'
end
end
context "with value given on a submit button" do
context "on a form with HTML5 fields" do
before do
@@ -138,7 +138,7 @@
@session.body.should include('You landed')
end
end
context "with title given on a submit button" do
it "should submit the associated form" do
@session.click_button('What an Awesome Button')
@@ -204,11 +204,6 @@
@session.click_button('Click')
extract_results(@session)['first_name'].should == 'John'
end
it "should prefer exact matches over partial matches" do
@session.click_button('Just an input')
extract_results(@session)['button'].should == 'button_second'
end
end
context "with id given on a button defined by <button> tag" do
@@ -236,11 +231,6 @@
@session.click_button('ck_me')
extract_results(@session)['first_name'].should == 'John'
end
it "should prefer exact matches over partial matches" do
@session.click_button('Just a button')
extract_results(@session)['button'].should == 'Just a button'
end
end
context "with title given on a button defined by <button> tag" do
@@ -268,7 +258,7 @@
@results = extract_results(@session)
@results['no_value'].should_not be_nil
end
it "should not send image buttons that were not clicked" do
@session.click_button('Click me!')
@results = extract_results(@session)
@@ -21,11 +21,6 @@
@session.click_link('abo')
@session.body.should include('Bar')
end
it "should prefer exact matches over partial matches" do
@session.click_link('A link')
@session.body.should include('Bar')
end
end
context "with title given" do
@@ -38,11 +33,6 @@
@session.click_link('some tit')
@session.body.should include('Bar')
end
it "should prefer exact matches over partial matches" do
@session.click_link('a fine link')
@session.body.should include('Bar')
end
end
context "with alternative text given to a contained image" do
@@ -55,11 +45,6 @@
@session.click_link('some imag')
@session.body.should include('Bar')
end
it "should prefer exact matches over partial matches" do
@session.click_link('fine image')
@session.body.should include('Bar')
end
end
context "with a locator that doesn't exist" do
@@ -94,7 +79,7 @@
it "should do nothing on anchor links" do
@session.fill_in("test_field", :with => 'blah')
@session.click_link('Anchor')
@session.click_link('Normal Anchor')
@session.find_field("test_field").value.should == 'blah'
@session.click_link('Blank Anchor')
@session.find_field("test_field").value.should == 'blah'
@@ -17,9 +17,9 @@
end
it "should fill in a text field by label without for" do
@session.fill_in('Street', :with => 'Avenue Q')
@session.fill_in('First Name', :with => 'Harry')
@session.click_button('awesome')
extract_results(@session)['street'].should == 'Avenue Q'
extract_results(@session)['first_name'].should == 'Harry'
end
it "should fill in a url field by label without for" do
@@ -28,12 +28,6 @@
extract_results(@session)['html5_url'].should == 'http://www.avenueq.com'
end
it "should favour exact label matches over partial matches" do
@session.fill_in('Name', :with => 'Harry Jones')
@session.click_button('awesome')
extract_results(@session)['name'].should == 'Harry Jones'
end
it "should fill in a textarea by id" do
@session.fill_in('form_description', :with => 'Texty text')
@session.click_button('awesome')
@@ -93,17 +87,11 @@
@session.click_button('awesome')
extract_results(@session)['password'].should == 'supasikrit'
end
it "should prefer exact matches over partial matches" do
@session.fill_in('Name', :with => 'Ford Prefect')
@session.click_button('awesome')
extract_results(@session)['name'].should == 'Ford Prefect'
end
it "should throw an exception if a hash containing 'with' is not provided" do
lambda{@session.fill_in 'Name', 'ignu'}.should raise_error
end
context "with ignore_hidden_fields" do
before { Capybara.ignore_hidden_elements = true }
after { Capybara.ignore_hidden_elements = false }
@@ -1,5 +1,5 @@
shared_examples_for "find" do
describe '#find' do
describe '#find', :focus => true do
before do
@session.visit('/with_html')
end
@@ -15,7 +15,11 @@
it "should find the first element using the given locator and options" do
@session.find('//a', :text => 'Redirect')[:id].should == 'red'
@session.find(:css, 'a', :text => 'A link')[:title].should == 'twas a fine link'
@session.find(:css, 'a', :text => 'A link came first')[:title].should == 'twas a fine link'
end
it "should raise an error if there are multiple matches" do
expect { @session.find('//a') }.to raise_error(Capybara::ElementNotFound)
end
describe 'the returned node' do
@@ -36,7 +40,7 @@
it "should have a reference to its parent if there is one" do
@node = @session.find(:css, '#first')
@node.parent.should == @node.session.document
@node.find('a').parent.should == @node
@node.find(:css, '#foo').parent.should == @node
end
end
@@ -147,20 +151,20 @@
end.should raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
end
it "should accept an XPath instance and respect the order of paths" do
it "should accept an XPath instance" do
@session.visit('/form')
@xpath = XPath::HTML.fillable_field('Name')
@session.find(@xpath).value.should == 'John Smith'
@xpath = XPath::HTML.fillable_field('First Name')
@session.find(@xpath).value.should == 'John'
end
context "within a scope" do
before do
@session.visit('/with_scope')
end
it "should find the first element using the given locator" do
it "should find the an element using the given locator" do
@session.within(:xpath, "//div[@id='for_bar']") do
@session.find('.//li').text.should =~ /With Simple HTML/
@session.find('.//li[1]').text.should =~ /With Simple HTML/
end
end
end
@@ -15,8 +15,8 @@
it "should accept an XPath instance" do
@session.visit('/form')
@xpath = XPath::HTML.fillable_field('Name')
@session.first(@xpath).value.should == 'John Smith'
@xpath = XPath::HTML.fillable_field('First Name')
@session.first(@xpath).value.should == 'John'
end
context "with css selectors" do
@@ -1,4 +1,4 @@
shared_examples_for "has_css" do
shared_examples_for "has_css" do
describe '#has_css?' do
before do
@session.visit('/with_html')
@@ -30,15 +30,9 @@
end
it "should select an option without giving a select box" do
@session.select("Mr")
@session.select("Swedish")
@session.click_button('awesome')
extract_results(@session)['title'].should == 'Mr'
end
it "should favour exact matches to option labels" do
@session.select("Mr", :from => 'Title')
@session.click_button('awesome')
extract_results(@session)['title'].should == 'Mr'
extract_results(@session)['locale'].should == 'sv'
end
it "should escape quotes" do
@@ -102,15 +96,15 @@
@session.click_button('awesome')
extract_results(@session)['languages'].should include('Ruby', 'Javascript')
end
it "should remain selected if already selected" do
@session.select("Ruby", :from => 'Language')
@session.select("Javascript", :from => 'Language')
@session.select("Ruby", :from => 'Language')
@session.click_button('awesome')
extract_results(@session)['languages'].should include('Ruby', 'Javascript')
end
it "should return value attribute rather than content if present" do
@session.find_field('Underwear').value.should include('thermal')
end
@@ -8,28 +8,28 @@
it "should unselect an option from a select box by id" do
@session.unselect('Commando', :from => 'form_underwear')
@session.click_button('awesome')
extract_results(@session)['underwear'].should include('Briefs', 'Boxer Briefs')
extract_results(@session)['underwear'].should include('Briefs', 'Boxerbriefs')
extract_results(@session)['underwear'].should_not include('Commando')
end
it "should unselect an option without a select box" do
@session.unselect('Commando')
@session.click_button('awesome')
extract_results(@session)['underwear'].should include('Briefs', 'Boxer Briefs')
extract_results(@session)['underwear'].should include('Briefs', 'Boxerbriefs')
extract_results(@session)['underwear'].should_not include('Commando')
end
it "should unselect an option from a select box by label" do
@session.unselect('Commando', :from => 'Underwear')
@session.click_button('awesome')
extract_results(@session)['underwear'].should include('Briefs', 'Boxer Briefs')
extract_results(@session)['underwear'].should include('Briefs', 'Boxerbriefs')
extract_results(@session)['underwear'].should_not include('Commando')
end
it "should favour exact matches to option labels" do
@session.unselect("Briefs", :from => 'Underwear')
@session.click_button('awesome')
extract_results(@session)['underwear'].should include('Commando', 'Boxer Briefs')
extract_results(@session)['underwear'].should include('Commando', 'Boxerbriefs')
extract_results(@session)['underwear'].should_not include('Briefs')
end
Oops, something went wrong.

0 comments on commit cc05b1d

Please sign in to comment.