Merge branch 'master' of git://github.com/jnicklas/capybara

This commit is contained in:
Rob Holland 2009-12-10 15:03:16 +00:00
commit 01d2ca5db2
4 changed files with 145 additions and 45 deletions

View File

@ -208,6 +208,7 @@ The following people have dedicated their time and effort to Capybara:
* Dennis Rogenius
* Rob Holland
* Wincent Colaiuta
* Andrea Fazzi
== License:

View File

@ -49,8 +49,8 @@ module Capybara
SESSION_METHODS = [
:visit, :body, :click_link, :click_button, :drag, :fill_in, :choose, :has_xpath?, :has_css?,
:check, :uncheck, :attach_file, :select, :has_content?, :within, :within_fieldset,
:within_table, :save_and_open_page, :find_field, :find_link, :find_button,
:field_labeled
:within_table, :save_and_open_page, :find, :find_field, :find_link, :find_button,
:field_labeled, :all
]
SESSION_METHODS.each do |method|
class_eval <<-RUBY, __FILE__, __LINE__+1

View File

@ -37,11 +37,15 @@ module Capybara
end
def click_link(locator)
find_link(locator).click
link = find_link(locator)
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
link.click
end
def click_button(locator)
find_button(locator).click
button = find_button(locator)
raise Capybara::ElementNotFound, "no button with value or id or text '#{locator}' found" unless button
button.click
end
def drag(source_locator, target_locator)
@ -53,27 +57,39 @@ module Capybara
end
def fill_in(locator, options={})
find_field(locator, :text_field, :text_area, :password_field).set(options[:with])
field = find_field(locator, :text_field, :text_area, :password_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])
end
def choose(locator)
find_field(locator, :radio).set(true)
field = find_field(locator, :radio)
raise Capybara::ElementNotFound, "cannot choose field, no radio button with id or label '#{locator}' found" unless field
field.set(true)
end
def check(locator)
find_field(locator, :checkbox).set(true)
field = find_field(locator, :checkbox)
raise Capybara::ElementNotFound, "cannot check field, no checkbox with id or label '#{locator}' found" unless field
field.set(true)
end
def uncheck(locator)
find_field(locator, :checkbox).set(false)
field = find_field(locator, :checkbox)
raise Capybara::ElementNotFound, "cannot uncheck field, no checkbox with id or label '#{locator}' found" unless field
field.set(false)
end
def select(value, options={})
find_field(options[:from], :select).select(value)
field = find_field(options[:from], :select)
raise Capybara::ElementNotFound, "cannot select option, no select box with id or label '#{options[:from]}' found" unless field
field.select(value)
end
def attach_file(locator, path)
find_field(locator, :file_field).set(path)
field = find_field(locator, :file_field)
raise Capybara::ElementNotFound, "cannot attach file, no file field with id or label '#{locator}' found" unless field
field.set(path)
end
def body
@ -85,7 +101,7 @@ module Capybara
end
def has_xpath?(path, options={})
results = find(path)
results = all(path)
if options[:text]
results = filter_by_text(results, options[:text])
end
@ -103,7 +119,7 @@ module Capybara
def within(kind, scope=nil)
kind, scope = Capybara.default_selector, kind unless scope
scope = css_to_xpath(scope) if kind == :css
raise Capybara::ElementNotFound, "scope '#{scope}' not found on page" if find(scope).empty?
raise Capybara::ElementNotFound, "scope '#{scope}' not found on page" unless find(scope)
scopes.push(scope)
yield
scopes.pop
@ -126,25 +142,28 @@ module Capybara
Capybara::SaveAndOpenPage.save_and_open_page(body)
end
def all(locator)
locator = current_scope.to_s + locator
driver.find(locator)
end
def find(locator)
all(locator).first
end
def find_field(locator, *kinds)
kinds = FIELDS_PATHS.keys if kinds.empty?
field = find_field_by_id(locator, *kinds) || find_field_by_label(locator, *kinds)
raise Capybara::ElementNotFound, "no field of kind #{kinds.inspect} with id or label '#{locator}' found" unless field
field
find_field_by_id(locator, *kinds) || find_field_by_label(locator, *kinds)
end
alias_method :field_labeled, :find_field
def find_link(locator)
link = find("//a[@id='#{locator}' or contains(.,'#{locator}') or @title='#{locator}']").first
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
link
find("//a[@id='#{locator}' or contains(.,'#{locator}') or @title='#{locator}']")
end
def find_button(locator)
button = find("//input[@type='submit' or @type='image'][@id='#{locator}' or @value='#{locator}']").first \
|| find("//button[@id='#{locator}' or @value='#{locator}' or contains(.,'#{locator}')]").first
raise Capybara::ElementNotFound, "no button with value or id or text '#{locator}' found" unless button
button
button = find("//input[@type='submit' or @type='image'][@id='#{locator}' or @value='#{locator}']")
button || find("//button[@id='#{locator}' or @value='#{locator}' or contains(.,'#{locator}')]")
end
private
@ -174,12 +193,12 @@ module Capybara
def find_field_by_id(locator, *kinds)
field_locator = kinds.map { |kind| FIELDS_PATHS[kind].call(locator) }.join("|")
element = find(field_locator).first
element = find(field_locator)
return element
end
def find_field_by_label(locator, *kinds)
label = find("//label[text()='#{locator}']").first || find("//label[contains(.,'#{locator}')]").first
label = find("//label[text()='#{locator}']") || find("//label[contains(.,'#{locator}')]")
if label
element = find_field_by_id(label[:for], *kinds)
return element if element
@ -187,9 +206,15 @@ module Capybara
return nil
end
def find(locator)
locator = current_scope.to_s + locator
driver.find(locator)
def sanitized_xpath_string(string)
if string.include?("'")
string = string.split("'", -1).map do |substr|
"'#{substr}'"
end.join(%q{,"'",})
"concat(#{string})"
else
"'#{string}'"
end
end
def sanitized_xpath_string(string)

View File

@ -272,6 +272,12 @@ shared_examples_for "session" do
@session.click_button('awesome')
extract_results(@session)['gender'].should == 'both'
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.choose('does not exist') }.should raise_error(Capybara::ElementNotFound)
end
end
end
describe "#check" do
@ -290,6 +296,12 @@ shared_examples_for "session" do
@session.click_button('awesome')
extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.check('does not exist') }.should raise_error(Capybara::ElementNotFound)
end
end
end
describe "#uncheck" do
@ -310,6 +322,12 @@ shared_examples_for "session" do
extract_results(@session)['pets'].should include('dog')
extract_results(@session)['pets'].should_not include('hamster')
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
end
end
end
describe "#select" do
@ -328,6 +346,12 @@ shared_examples_for "session" do
@session.click_button('awesome')
extract_results(@session)['locale'].should == 'fi'
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
end
end
end
describe '#has_content?' do
@ -509,7 +533,12 @@ shared_examples_for "session" do
@session.click_button('Upload')
end
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
end
end
end
describe '#find_field' do
@ -524,23 +553,17 @@ shared_examples_for "session" do
end
it "should raise an error if the field doesn't exist" do
running {
@session.find_field('Does not exist')
}.should raise_error(Capybara::ElementNotFound)
@session.find_field('Does not exist').should be_nil
end
it "should find only given kind of field" do
@session.find_field('form_description', :text_field, :text_area).text.should == 'Descriptive text goes here'
running {
@session.find_field('form_description', :password_field)
}.should raise_error(Capybara::ElementNotFound)
@session.find_field('form_description', :password_field).should be_nil
end
it "should be aliased as 'field_labeled' for webrat compatibility" do
@session.field_labeled('Dog').value.should == 'dog'
running {
@session.field_labeled('Does not exist')
}.should raise_error(Capybara::ElementNotFound)
@session.field_labeled('Does not exist').should be_nil
end
end
@ -554,10 +577,8 @@ shared_examples_for "session" do
@session.find_link('labore')[:href].should == "/with_simple_html"
end
it "should raise an error if the field doesn't exist" do
running {
@session.find_link('Does not exist')
}.should raise_error(Capybara::ElementNotFound)
it "should return nil if the field doesn't exist" do
@session.find_link('Does not exist').should be_nil
end
end
@ -571,10 +592,63 @@ shared_examples_for "session" do
@session.find_button('crap321').value.should == "crappy"
end
it "should raise an error if the field doesn't exist" do
running {
@session.find_button('Does not exist')
}.should raise_error(Capybara::ElementNotFound)
it "should return nil if the field doesn't exist" do
@session.find_button('Does not exist').should be_nil
end
end
describe '#all' do
before do
@session.visit('/with_html')
end
it "should find all elements using the given locator" do
@session.all('//p').should have(3).elements
@session.all('//h1').first.text.should == 'This is a test'
@session.all("//input[@id='test_field']").first[:value].should == 'monkey'
end
it "should return an empty array when nothing was found" do
@session.all('//div').should be_empty
end
context "within a scope" do
before do
@session.visit('/with_scope')
end
it "should find any element using the given locator" do
@session.within(:xpath, "//div[@id='for_bar']") do
@session.all('//li').should have(2).elements
end
end
end
end
describe '#find' do
before do
@session.visit('/with_html')
end
it "should find the first element using the given locator" do
@session.find('//h1').text.should == 'This is a test'
@session.find("//input[@id='test_field']")[:value].should == 'monkey'
end
it "should return nil when nothing was found" do
@session.find('//div').should be_nil
end
context "within a scope" do
before do
@session.visit('/with_scope')
end
it "should find the first element using the given locator" do
@session.within(:xpath, "//div[@id='for_bar']") do
@session.find('//li').text.should =~ /With Simple HTML/
end
end
end
end