require File.expand_path('spec_helper', File.dirname(__FILE__))
require 'nokogiri'
shared_examples_for "session" do
def extract_results(session)
YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text
end
describe '#app' do
it "should remember the application" do
@session.app.should == TestApp
end
end
describe '#visit' do
it "should fetch a response from the driver" do
@session.visit('/')
@session.body.should include('Hello world!')
@session.visit('/foo')
@session.body.should include('Another World')
end
end
describe '#click_link' do
before do
@session.visit('/with_html')
end
context "with id given" do
it "should take user to the linked page" do
@session.click_link('foo')
@session.body.should include('Another World')
end
end
context "with text given" do
it "should take user to the linked page" do
@session.click_link('labore')
@session.body.should include('
Bar
')
end
end
context "with title given" do
it "should take user to the linked page" do
@session.click_link('awesome title')
@session.body.should include('Bar
')
end
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running do
@session.click_link('does not exist')
end.should raise_error(Capybara::ElementNotFound)
end
end
it "should follow redirects" do
@session.click_link('Redirect')
@session.body.should include('You landed')
end
end
describe '#click_button' do
before do
@session.visit('/form')
end
context "with value given on a submit button" do
before do
@session.click_button('awesome')
@results = extract_results(@session)
end
it "should serialize and submit text fields" do
@results['first_name'].should == 'John'
end
it "should serialize and submit password fields" do
@results['password'].should == 'seeekrit'
end
it "should serialize and submit hidden fields" do
@results['token'].should == '12345'
end
it "should not serialize fields from other forms" do
@results['middle_name'].should be_nil
end
it "should submit the button that was clicked, but not other buttons" do
@results['awesome'].should == 'awesome'
@results['crappy'].should be_nil
end
it "should serialize radio buttons" do
@results['gender'].should == 'female'
end
it "should serialize check boxes" do
@results['pets'].should include('dog', 'hamster')
@results['pets'].should_not include('cat')
end
it "should serialize text areas" do
@results['description'].should == 'Descriptive text goes here'
end
it "should serialize select tag with values" do
@results['locale'].should == 'en'
end
it "should serialize select tag without values" do
@results['region'].should == 'Norway'
end
it "should serialize first option for select tag with no selection" do
@results['city'].should == 'London'
end
it "should not serialize a select tag without options" do
@results['tendency'].should be_nil
end
end
context "with id given on a submit button" do
it "should submit the associated form" do
@session.click_button('awe123')
extract_results(@session)['first_name'].should == 'John'
end
end
context "with value given on an image button" do
it "should submit the associated form" do
@session.click_button('okay')
extract_results(@session)['first_name'].should == 'John'
end
end
context "with id given on an image button" do
it "should submit the associated form" do
@session.click_button('okay556')
extract_results(@session)['first_name'].should == 'John'
end
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running do
@session.click_button('does not exist')
end.should raise_error(Capybara::ElementNotFound)
end
end
it "should serialize and send GET forms" do
@session.visit('/form')
@session.click_button('med')
@results = extract_results(@session)
@results['middle_name'].should == 'Darren'
@results['foo'].should be_nil
end
it "should follow redirects" do
@session.click_button('Go FAR')
@session.body.should include('You landed')
end
end
describe "#fill_in" do
before do
@session.visit('/form')
end
it "should fill in a text field by id" do
@session.fill_in('form_first_name', :with => 'Harry')
@session.click_button('awesome')
extract_results(@session)['first_name'].should == 'Harry'
end
it "should fill in a text field by label" do
@session.fill_in('First Name', :with => 'Harry')
@session.click_button('awesome')
extract_results(@session)['first_name'].should == 'Harry'
end
it "should fill in a textarea by id" do
@session.fill_in('form_description', :with => 'Texty text')
@session.click_button('awesome')
extract_results(@session)['description'].should == 'Texty text'
end
it "should fill in a textarea by label" do
@session.fill_in('Description', :with => 'Texty text')
@session.click_button('awesome')
extract_results(@session)['description'].should == 'Texty text'
end
it "should fill in a password field by id" do
@session.fill_in('form_password', :with => 'supasikrit')
@session.click_button('awesome')
extract_results(@session)['password'].should == 'supasikrit'
end
it "should fill in a password field by label" do
@session.fill_in('Password', :with => 'supasikrit')
@session.click_button('awesome')
extract_results(@session)['password'].should == 'supasikrit'
end
context "with a locator that doesn't exist" do
it "should raise an error" do
running do
@session.fill_in('does not exist', :with => 'Blah blah')
end.should raise_error(Capybara::ElementNotFound)
end
end
end
describe "#choose" do
before do
@session.visit('/form')
end
it "should choose a radio button by id" do
@session.choose("gender_male")
@session.click_button('awesome')
extract_results(@session)['gender'].should == 'male'
end
it "should choose a radio button by label" do
@session.choose("Both")
@session.click_button('awesome')
extract_results(@session)['gender'].should == 'both'
end
end
describe "#check" do
before do
@session.visit('/form')
end
it "should check a checkbox by id" do
@session.check("form_pets_cat")
@session.click_button('awesome')
extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
end
it "should check a checkbox by label" do
@session.check("Cat")
@session.click_button('awesome')
extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
end
end
describe "#uncheck" do
before do
@session.visit('/form')
end
it "should uncheck a checkbox by id" do
@session.uncheck("form_pets_hamster")
@session.click_button('awesome')
extract_results(@session)['pets'].should include('dog')
extract_results(@session)['pets'].should_not include('hamster')
end
it "should uncheck a checkbox by label" do
@session.uncheck("Hamster")
@session.click_button('awesome')
extract_results(@session)['pets'].should include('dog')
extract_results(@session)['pets'].should_not include('hamster')
end
end
describe "#select" do
before do
@session.visit('/form')
end
it "should select an option from a select box by id" do
@session.select("Finish", :from => 'form_locale')
@session.click_button('awesome')
extract_results(@session)['locale'].should == 'fi'
end
it "should select an option from a select box by label" do
@session.select("Finish", :from => 'Locale')
@session.click_button('awesome')
extract_results(@session)['locale'].should == 'fi'
end
end
describe '#has_content?' do
it "should be true if the given content is on the page at least once" do
@session.visit('/with_html')
@session.should have_content('est')
@session.should have_content('Lorem')
@session.should have_content('Redirect')
end
it "should be false if the given content is not on the page" do
@session.visit('/with_html')
@session.should_not have_content('xxxxyzzz')
@session.should_not have_content('monkey')
end
end
describe '#has_xpath?' do
before do
@session.visit('/with_html')
end
it "should be true if the given selector is on the page" do
@session.should have_xpath("//p")
@session.should have_xpath("//p//a[@id='foo']")
@session.should have_xpath("//p[contains(.,'est')]")
end
it "should be false if the given selector is not on the page" do
@session.should_not have_xpath("//abbr")
@session.should_not have_xpath("//p//a[@id='doesnotexist']")
@session.should_not have_xpath("//p[contains(.,'thisstringisnotonpage')]")
end
it "should respect scopes" do
@session.within "//p[@id='first']" do
@session.should have_xpath("//a[@id='foo']")
@session.should_not have_xpath("//a[@id='red']")
end
end
context "with count" do
it "should be true if the content is on the page the given number of times" do
@session.should have_xpath("//p", :count => 3)
@session.should have_xpath("//p//a[@id='foo']", :count => 1)
@session.should have_xpath("//p[contains(.,'est')]", :count => 1)
end
it "should be false if the content is on the page the given number of times" do
@session.should_not have_xpath("//p", :count => 6)
@session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
@session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
end
it "should be false if the content isn't on the page at all" do
@session.should_not have_xpath("//abbr", :count => 2)
@session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
end
end
context "with text" do
it "should discard all matches where the given string is not contained" do
@session.should have_xpath("//p//a", :text => "Redirect", :count => 1)
@session.should_not have_xpath("//p", :text => "Doesnotexist")
end
it "should discard all matches where the given regexp is not matched" do
@session.should have_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
@session.should_not have_xpath("//p//a", :text => /Red$/)
end
end
end
describe '#has_css?' do
before do
@session.visit('/with_html')
end
it "should be true if the given selector is on the page" do
@session.should have_css("p")
@session.should have_css("p a#foo")
end
it "should be false if the given selector is not on the page" do
@session.should_not have_css("abbr")
@session.should_not have_css("p a#doesnotexist")
@session.should_not have_css("p.nosuchclass")
end
it "should respect scopes" do
@session.within "//p[@id='first']" do
@session.should have_css("a#foo")
@session.should_not have_css("a#red")
end
end
context "with count" do
it "should be true if the content is on the page the given number of times" do
@session.should have_css("p", :count => 3)
@session.should have_css("p a#foo", :count => 1)
end
it "should be false if the content is on the page the given number of times" do
@session.should_not have_css("p", :count => 6)
@session.should_not have_css("p a#foo", :count => 2)
end
it "should be false if the content isn't on the page at all" do
@session.should_not have_css("abbr", :count => 2)
@session.should_not have_css("p a.doesnotexist", :count => 1)
end
end
context "with text" do
it "should discard all matches where the given string is not contained" do
@session.should have_css("p a", :text => "Redirect", :count => 1)
@session.should_not have_css("p a", :text => "Doesnotexist")
end
it "should discard all matches where the given regexp is not matched" do
@session.should have_css("p a", :text => /re[dab]i/i, :count => 1)
@session.should_not have_css("p a", :text => /Red$/)
end
end
end
describe "#attach_file" do
before do
@session.visit('/form')
end
context "with normal form" do
it "should set a file path by id" do
@session.attach_file "form_image", __FILE__
@session.click_button('awesome')
extract_results(@session)['image'].should == File.basename(__FILE__)
end
it "should set a file path by label" do
@session.attach_file "Image", __FILE__
@session.click_button('awesome')
extract_results(@session)['image'].should == File.basename(__FILE__)
end
end
context "with multipart form" do
before do
@test_file_path = File.expand_path('fixtures/test_file.txt', File.dirname(__FILE__))
end
it "should set a file path by id" do
@session.attach_file "form_document", @test_file_path
@session.click_button('Upload')
@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.body.should include(File.read(@test_file_path))
end
end
end
describe '#find_field' do
before do
@session.visit('/form')
end
it "should find any field" do
@session.find_field('Dog').value.should == 'dog'
@session.find_field('form_description').text.should == 'Descriptive text goes here'
@session.find_field('Region')[:name].should == 'form[region]'
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)
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)
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)
end
end
describe '#find_link' do
before do
@session.visit('/with_html')
end
it "should find any field" do
@session.find_link('foo').text.should == "ullamco"
@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)
end
end
describe '#find_button' do
before do
@session.visit('/form')
end
it "should find any field" do
@session.find_button('med')[:id].should == "mediocre"
@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)
end
end
describe '#within' do
before do
@session.visit('/with_scope')
end
context "with CSS selector" do
it "should click links in the given scope" do
@session.within(:css, "ul li[contains('With Simple HTML')]") do
@session.click_link('Go')
end
@session.body.should include('Bar
')
end
end
context "with XPath selector" do
it "should click links in the given scope" do
@session.within(:xpath, "//li[contains(.,'With Simple HTML')]") do
@session.click_link('Go')
end
@session.body.should include('Bar
')
end
end
context "with click_link" do
it "should click links in the given scope" do
@session.within("//li[contains(.,'With Simple HTML')]") do
@session.click_link('Go')
end
@session.body.should include('Bar
')
end
context "with nested scopes" do
it "should respect the inner scope" do
@session.within("//div[@id='for_bar']") do
@session.within("//li[contains(.,'Bar')]") do
@session.click_link('Go')
end
end
@session.body.should include('Another World')
end
it "should respect the outer scope" do
@session.within("//div[@id='another_foo']") do
@session.within("//li[contains(.,'With Simple HTML')]") do
@session.click_link('Go')
end
end
@session.body.should include('Hello world')
end
end
it "should raise an error if the scope is not found on the page" do
running {
@session.within("//div[@id='doesnotexist']") do
end
}.should raise_error(Capybara::ElementNotFound)
end
end
context "with forms" do
it "should fill in a field and click a button" do
@session.within("//li[contains(.,'Bar')]") do
@session.click_button('Go')
end
extract_results(@session)['first_name'].should == 'Peter'
@session.visit('/with_scope')
@session.within("//li[contains(.,'Bar')]") do
@session.fill_in('First Name', :with => 'Dagobert')
@session.click_button('Go')
end
extract_results(@session)['first_name'].should == 'Dagobert'
end
end
end
describe '#within_fieldset' do
before do
@session.visit('/fieldsets')
end
it "should restrict scope to a fieldset given by id" do
@session.within_fieldset("villain_fieldset") do
@session.fill_in("Name", :with => 'Goldfinger')
@session.click_button("Create")
end
extract_results(@session)['villain_name'].should == 'Goldfinger'
end
it "should restrict scope to a fieldset given by legend" do
@session.within_fieldset("Villain") do
@session.fill_in("Name", :with => 'Goldfinger')
@session.click_button("Create")
end
extract_results(@session)['villain_name'].should == 'Goldfinger'
end
end
describe '#within_table' do
before do
@session.visit('/tables')
end
it "should restrict scope to a fieldset given by id" do
@session.within_table("girl_table") do
@session.fill_in("Name", :with => 'Christmas')
@session.click_button("Create")
end
extract_results(@session)['girl_name'].should == 'Christmas'
end
it "should restrict scope to a fieldset given by legend" do
@session.within_table("Villain") do
@session.fill_in("Name", :with => 'Quantum')
@session.click_button("Create")
end
extract_results(@session)['villain_name'].should == 'Quantum'
end
end
end
describe Capybara::Session do
context 'with non-existant driver' do
it "should raise an error" do
running {
Capybara::Session.new(:quox, TestApp).driver
}.should raise_error(Capybara::DriverNotFoundError)
end
end
end