From 8ad161b0413ffe905b0c1cb99ed6d18d390f09b3 Mon Sep 17 00:00:00 2001 From: jgagner Date: Tue, 12 Jan 2010 11:40:10 -0800 Subject: [PATCH 01/84] #within_frame method --- lib/capybara/driver/base.rb | 4 ++++ lib/capybara/driver/selenium_driver.rb | 7 ++++++- spec/driver/selenium_driver_spec.rb | 2 +- spec/drivers_spec.rb | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 2f94d106..dbdc064e 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -27,6 +27,10 @@ class Capybara::Driver::Base raise NotImplementedError end + def within_frame frame_id + raise Capybara::NotSupportedByDriverError + end + def source raise NotImplementedError end diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 2f1deabb..076fcc15 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -103,7 +103,12 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base def browser self.class.driver end - + def with_frame(frame_id) + old_window = browser.window_handle + browser.switch_to.frame(frame_id) + yield + browser.switch_to.window old_window + end private def url(path) diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index a71047e0..0fdfa652 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -8,5 +8,5 @@ describe Capybara::Driver::Selenium do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" it_should_behave_like "driver without node path support" - + it_should_behave_like "driver with frame support" end diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index 8643b4e6..523be045 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -1,5 +1,8 @@ require File.expand_path('spec_helper', File.dirname(__FILE__)) +shared_examples_for 'driver with frame support' do + it_should_behave_like 'within_frame' +end shared_examples_for 'driver' do describe '#visit' do From 28605a5d9c38481678a8bd8a41d7f9174026dfc9 Mon Sep 17 00:00:00 2001 From: jgagner Date: Tue, 12 Jan 2010 11:56:17 -0800 Subject: [PATCH 02/84] added specs for with_frame --- spec/drivers_spec.rb | 2 +- spec/dsl/with_frame_spec.rb | 32 ++++++++++++++++++++++++++++++++ spec/views/frame_one.erb | 8 ++++++++ spec/views/frame_two.erb | 8 ++++++++ spec/views/with_frames.erb | 10 ++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 spec/dsl/with_frame_spec.rb create mode 100644 spec/views/frame_one.erb create mode 100644 spec/views/frame_two.erb create mode 100644 spec/views/with_frames.erb diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index 523be045..8d833609 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -1,7 +1,7 @@ require File.expand_path('spec_helper', File.dirname(__FILE__)) shared_examples_for 'driver with frame support' do - it_should_behave_like 'within_frame' + it_should_behave_like 'with_frame' end shared_examples_for 'driver' do diff --git a/spec/dsl/with_frame_spec.rb b/spec/dsl/with_frame_spec.rb new file mode 100644 index 00000000..6bf6ae53 --- /dev/null +++ b/spec/dsl/with_frame_spec.rb @@ -0,0 +1,32 @@ +module WithFrameSpec + shared_examples_for "with_frame" do + describe '#with_frame' do + before(:each) do + @driver.visit('/with_frames') + end + + it "should find the div in frameOne" do + @driver.with_frame("frameOne") do + @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' + end + end + it "should find the div in FrameTwo" do + @driver.with_frame("frameTwo") do + @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' + end + end + it "should find the text div in the main window after finding text in frameOne" do + @driver.with_frame("frameOne") do + @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' + end + @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' + end + it "should find the text div in the main window after finding text in frameTwo" do + @driver.with_frame("frameTwo") do + @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' + end + @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' + end + end + end +end \ No newline at end of file diff --git a/spec/views/frame_one.erb b/spec/views/frame_one.erb new file mode 100644 index 00000000..6b8f8a7b --- /dev/null +++ b/spec/views/frame_one.erb @@ -0,0 +1,8 @@ + + + This is the title of frame one + + +
This is the text of divInFrameOne
+ + \ No newline at end of file diff --git a/spec/views/frame_two.erb b/spec/views/frame_two.erb new file mode 100644 index 00000000..b344964d --- /dev/null +++ b/spec/views/frame_two.erb @@ -0,0 +1,8 @@ + + + This is the title of frame two + + +
This is the text of divInFrameTwo
+ + \ No newline at end of file diff --git a/spec/views/with_frames.erb b/spec/views/with_frames.erb new file mode 100644 index 00000000..871e5dc5 --- /dev/null +++ b/spec/views/with_frames.erb @@ -0,0 +1,10 @@ + + + With Frames + + +
This is the text for divInMainWindow
+ + + + \ No newline at end of file From 1e096ddcc02d09351ee61475e40ed6e8f5e4bca5 Mon Sep 17 00:00:00 2001 From: jgagner Date: Tue, 12 Jan 2010 12:27:39 -0800 Subject: [PATCH 03/84] Fixed naming --- lib/capybara/driver/selenium_driver.rb | 2 +- lib/capybara/session.rb | 6 +++++- spec/drivers_spec.rb | 2 +- spec/dsl/{with_frame_spec.rb => within_frame_spec.rb} | 0 spec/views/{with_frames.erb => within_frames.erb} | 0 5 files changed, 7 insertions(+), 3 deletions(-) rename spec/dsl/{with_frame_spec.rb => within_frame_spec.rb} (100%) rename spec/views/{with_frames.erb => within_frames.erb} (100%) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 076fcc15..d450c629 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -103,7 +103,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base def browser self.class.driver end - def with_frame(frame_id) + def within_frame(frame_id) old_window = browser.window_handle browser.switch_to.frame(frame_id) yield diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index a82d4347..ba0e6a67 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -8,7 +8,7 @@ module Capybara :all, :attach_file, :body, :check, :choose, :click, :click_button, :click_link, :current_url, :drag, :evaluate_script, :field_labeled, :fill_in, :find, :find_button, :find_by_id, :find_field, :find_link, :has_content?, :has_css?, :has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck, - :visit, :wait_until, :within, :within_fieldset, :within_table + :visit, :wait_until, :within, :within_fieldset, :within_table,:within_frame ] attr_reader :mode, :app @@ -33,6 +33,10 @@ module Capybara end end + def within_frame frame_id + driver.within_frame frame_id + end + def current_url driver.current_url end diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index 8d833609..523be045 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -1,7 +1,7 @@ require File.expand_path('spec_helper', File.dirname(__FILE__)) shared_examples_for 'driver with frame support' do - it_should_behave_like 'with_frame' + it_should_behave_like 'within_frame' end shared_examples_for 'driver' do diff --git a/spec/dsl/with_frame_spec.rb b/spec/dsl/within_frame_spec.rb similarity index 100% rename from spec/dsl/with_frame_spec.rb rename to spec/dsl/within_frame_spec.rb diff --git a/spec/views/with_frames.erb b/spec/views/within_frames.erb similarity index 100% rename from spec/views/with_frames.erb rename to spec/views/within_frames.erb From 35c70890376e8d8bbb76785c5f7fdc3394ad6e28 Mon Sep 17 00:00:00 2001 From: jgagner Date: Tue, 12 Jan 2010 12:33:06 -0800 Subject: [PATCH 04/84] Fixed bug with within_frame session method and changed naming in spec --- lib/capybara/session.rb | 4 +++- spec/dsl/within_frame_spec.rb | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index ba0e6a67..a66b86f8 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -34,7 +34,9 @@ module Capybara end def within_frame frame_id - driver.within_frame frame_id + driver.within_frame(frame_id) do + yield + end end def current_url diff --git a/spec/dsl/within_frame_spec.rb b/spec/dsl/within_frame_spec.rb index 6bf6ae53..be46f7d5 100644 --- a/spec/dsl/within_frame_spec.rb +++ b/spec/dsl/within_frame_spec.rb @@ -1,28 +1,28 @@ -module WithFrameSpec - shared_examples_for "with_frame" do - describe '#with_frame' do +module WithinFrameSpec + shared_examples_for "within_frame" do + describe '#within_frame' do before(:each) do - @driver.visit('/with_frames') + @driver.visit('/within_frames') end it "should find the div in frameOne" do - @driver.with_frame("frameOne") do + @driver.within_frame("frameOne") do @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' end end it "should find the div in FrameTwo" do - @driver.with_frame("frameTwo") do + @driver.within_frame("frameTwo") do @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' end end it "should find the text div in the main window after finding text in frameOne" do - @driver.with_frame("frameOne") do + @driver.within_frame("frameOne") do @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' end @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' end it "should find the text div in the main window after finding text in frameTwo" do - @driver.with_frame("frameTwo") do + @driver.within_frame("frameTwo") do @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' end @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' From 2b813f09b921e4ec2ec06c9d602f3eb972650361 Mon Sep 17 00:00:00 2001 From: jgagner Date: Thu, 14 Jan 2010 17:37:19 -0800 Subject: [PATCH 05/84] made it so has_xpath?/has_no_xpath? checks to make sure the element is visible by default. Can be overriden with options. --- lib/capybara/session.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index a66b86f8..2a6e5d17 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -134,7 +134,7 @@ module Capybara def has_xpath?(path, options={}) wait_conditionally_until do results = all(path, options) - + options = {:visible => true}.merge options if options[:count] results.size == options[:count] else @@ -147,6 +147,7 @@ module Capybara def has_no_xpath?(path, options={}) wait_conditionally_until do + options = {:visible => true}.merge options results = all(path, options) if options[:count] From b207370441144e76c587517a5f7138e59026f710 Mon Sep 17 00:00:00 2001 From: jgagner Date: Thu, 14 Jan 2010 17:37:48 -0800 Subject: [PATCH 06/84] rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible --- lib/capybara/driver/selenium_driver.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index d450c629..5e0226ed 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -44,7 +44,12 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def visible? - node.displayed? and node.displayed? != "false" + begin + node.displayed? and node.displayed? != "false" + rescue Selenium::WebDriver::Error::WebDriverError + # rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible + return false + end end private From a19c902a65c1389922e73afc3453d1ca4d7c0b6d Mon Sep 17 00:00:00 2001 From: jgagner Date: Thu, 14 Jan 2010 17:37:19 -0800 Subject: [PATCH 07/84] made it so has_xpath?/has_no_xpath? checks to make sure the element is visible by default. Can be overriden with options. rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible --- lib/capybara/driver/selenium_driver.rb | 7 ++++++- lib/capybara/session.rb | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index d450c629..5e0226ed 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -44,7 +44,12 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def visible? - node.displayed? and node.displayed? != "false" + begin + node.displayed? and node.displayed? != "false" + rescue Selenium::WebDriver::Error::WebDriverError + # rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible + return false + end end private diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index a66b86f8..90d11b6e 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -133,8 +133,8 @@ module Capybara def has_xpath?(path, options={}) wait_conditionally_until do + options = {:visible => true}.merge options results = all(path, options) - if options[:count] results.size == options[:count] else @@ -147,6 +147,7 @@ module Capybara def has_no_xpath?(path, options={}) wait_conditionally_until do + options = {:visible => true}.merge options results = all(path, options) if options[:count] From 4b7609ac1522c8e7c1e9462e74fd53f2bcc7460b Mon Sep 17 00:00:00 2001 From: jgagner Date: Fri, 15 Jan 2010 08:15:38 -0800 Subject: [PATCH 08/84] Ignoring .idea directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7f61f0d3..92836684 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea/ .DS_Store pkg *~ From 96314c05c57bee0320d6d19d8d78e0bac13fce6a Mon Sep 17 00:00:00 2001 From: Rob Holland Date: Tue, 23 Feb 2010 17:43:40 +0000 Subject: [PATCH 09/84] Add support for using HTTP verbs directly to the rack driver. --- lib/capybara/driver/base.rb | 16 ++++++++ lib/capybara/driver/rack_test_driver.rb | 29 ++++++++++---- lib/capybara/session.rb | 36 +++++++---------- spec/driver/celerity_driver_spec.rb | 1 + spec/driver/culerity_driver_spec.rb | 3 +- spec/driver/rack_test_driver_spec.rb | 1 + spec/driver/selenium_driver_spec.rb | 1 + spec/drivers_spec.rb | 52 +++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 31 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 6cf8c00f..3be28d4d 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -34,4 +34,20 @@ class Capybara::Driver::Base def cleanup! end + def get(*args) + raise Capybara::NotSupportedByDriverError + end + + def post(*args) + raise Capybara::NotSupportedByDriverError + end + + def delete(*args) + raise Capybara::NotSupportedByDriverError + end + + def put(*args) + raise Capybara::NotSupportedByDriverError + end + end diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 3dc9acc0..008d771b 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -174,7 +174,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end include ::Rack::Test::Methods - attr_reader :app, :html, :body + attr_reader :app alias_method :response, :last_response alias_method :request, :last_request @@ -188,7 +188,6 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base return if path.gsub(/^#{current_path}/, '') =~ /^#/ get(path, attributes, env) follow_redirects! - cache_body end def current_url @@ -203,13 +202,29 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base path = current_path if not path or path.empty? send(method, path, attributes, env) follow_redirects! - cache_body end def find(selector) html.xpath(selector).map { |node| Node.new(self, node) } end - + + ['get', 'post', 'put', 'delete'].each do |method| + class_eval <<-RUBY, __FILE__, __LINE__+1 + def #{method}(*args, &block) + reset_cache + super + end + RUBY + end + + def body + @body ||= response.body + end + + def html + @html ||= Nokogiri::HTML(body) + end + private def current_path @@ -236,9 +251,9 @@ private env end - def cache_body - @body = response.body - @html = Nokogiri::HTML(body) + def reset_cache + @body = nil + @html = nil end end diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index f98afd39..f95f7a34 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -1,10 +1,13 @@ +require 'forwardable' require 'capybara/wait_until' module Capybara class Session + extend Forwardable include Searchable DSL_METHODS = [ + :get, :put, :post, :delete, :all, :attach_file, :body, :check, :choose, :click, :click_button, :click_link, :current_url, :drag, :evaluate_script, :field_labeled, :fill_in, :find, :find_button, :find_by_id, :find_field, :find_link, :has_content?, :has_css?, :has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck, @@ -34,21 +37,16 @@ module Capybara end end - def cleanup! - driver.cleanup! - end - - def current_url - driver.current_url - end - - def response_headers - driver.response_headers - end - - def visit(path) - driver.visit(path) - end + def_delegator :driver, :cleanup! + def_delegator :driver, :current_url + def_delegator :driver, :response_headers + def_delegator :driver, :visit + def_delegator :driver, :body + def_delegator :driver, :source + def_delegator :driver, :get + def_delegator :driver, :post + def_delegator :driver, :put + def_delegator :driver, :delete def click(locator) msg = "no link or button '#{locator}' found" @@ -106,14 +104,6 @@ module Capybara locate(:xpath, XPath.file_field(locator), msg).set(path) end - def body - driver.body - end - - def source - driver.source - end - def within(kind, scope=nil) kind, scope = Capybara.default_selector, kind unless scope scope = XPath.from_css(scope) if kind == :css diff --git a/spec/driver/celerity_driver_spec.rb b/spec/driver/celerity_driver_spec.rb index bd31440a..fa3ebfd3 100644 --- a/spec/driver/celerity_driver_spec.rb +++ b/spec/driver/celerity_driver_spec.rb @@ -10,6 +10,7 @@ if RUBY_PLATFORM =~ /java/ it_should_behave_like "driver with javascript support" it_should_behave_like "driver with header support" it_should_behave_like "driver with node path support" + it_should_behave_like "driver without direct HTTP support" end else diff --git a/spec/driver/culerity_driver_spec.rb b/spec/driver/culerity_driver_spec.rb index ec6a4e3d..4753d48f 100644 --- a/spec/driver/culerity_driver_spec.rb +++ b/spec/driver/culerity_driver_spec.rb @@ -8,6 +8,7 @@ describe Capybara::Driver::Culerity do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" it_should_behave_like "driver with header support" - it_should_behave_like "driver with node path support" + it_should_behave_like "driver with node path support" + it_should_behave_like "driver without direct HTTP support" end diff --git a/spec/driver/rack_test_driver_spec.rb b/spec/driver/rack_test_driver_spec.rb index 7b2c8d67..9ce4b692 100644 --- a/spec/driver/rack_test_driver_spec.rb +++ b/spec/driver/rack_test_driver_spec.rb @@ -8,5 +8,6 @@ describe Capybara::Driver::RackTest do it_should_behave_like "driver" it_should_behave_like "driver with header support" it_should_behave_like "driver with node path support" + it_should_behave_like "driver with direct HTTP support" end diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index a71047e0..5bc8407b 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -8,5 +8,6 @@ describe Capybara::Driver::Selenium do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" it_should_behave_like "driver without node path support" + it_should_behave_like "driver without direct HTTP support" end diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index b5fbb892..ee20a095 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -137,3 +137,55 @@ shared_examples_for "driver without node path support" do end end + +shared_examples_for "driver with direct HTTP support" do + describe "direct HTTP calls" do + it "should create a response for a GET" do + @driver.get('/tables') + @driver.body.should_not be_nil + end + + it "should create a response for a PUT" do + @driver.put('/tables') + @driver.body.should_not be_nil + end + + it "should create a response for a POST" do + @driver.post('/table') + @driver.body.should_not be_nil + end + + it "should create a response for a DELETE" do + @driver.delete('/table') + @driver.body.should_not be_nil + end + end +end + +shared_examples_for "driver without direct HTTP support" do + describe "direct HTTP calls" do + it "should get NotSupportedByDriverError for a GET" do + running do + @driver.get('/tables') + end.should raise_error(Capybara::NotSupportedByDriverError) + end + + it "should get NotSupportedByDriverError for a PUT" do + running do + @driver.put('/tables') + end.should raise_error(Capybara::NotSupportedByDriverError) + end + + it "should get NotSupportedByDriverError for a POST" do + running do + @driver.post('/tables') + end.should raise_error(Capybara::NotSupportedByDriverError) + end + + it "should get NotSupportedByDriverError for a DELETE" do + running do + @driver.delete('/tables') + end.should raise_error(Capybara::NotSupportedByDriverError) + end + end +end From e6ed2cd8b04916ee89e88fef2fdf6502da93ef15 Mon Sep 17 00:00:00 2001 From: Robot Made Date: Sun, 21 Feb 2010 16:59:17 -0800 Subject: [PATCH 10/84] rails3 --- lib/capybara/rails.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/capybara/rails.rb b/lib/capybara/rails.rb index 2911d60d..b6a62ec1 100644 --- a/lib/capybara/rails.rb +++ b/lib/capybara/rails.rb @@ -3,9 +3,10 @@ require 'capybara/dsl' Capybara.app = Rack::Builder.new do map "/" do - use Rails::Rack::Static - run ActionController::Dispatcher.new + ActionDispatch::Static + run Rails.application end end.to_app Capybara.asset_root = Rails.root.join('public') + From dba9a0421c4a7f99d77f9761424d7489fdc799cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aslak=20Helles=C3=B8y?= Date: Wed, 24 Feb 2010 09:25:47 +0100 Subject: [PATCH 11/84] Support both Rails 2 and Rails 3 --- lib/capybara/rails.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/capybara/rails.rb b/lib/capybara/rails.rb index b6a62ec1..13ad0267 100644 --- a/lib/capybara/rails.rb +++ b/lib/capybara/rails.rb @@ -3,8 +3,13 @@ require 'capybara/dsl' Capybara.app = Rack::Builder.new do map "/" do - ActionDispatch::Static - run Rails.application + if Rails.version.to_f >= 3.0 + ActionDispatch::Static + run Rails.application + else # Rails 2 + use Rails::Rack::Static + run ActionController::Dispatcher.new + end end end.to_app From 7ae8f8db5885fb388131b04e318633cfff0dbee3 Mon Sep 17 00:00:00 2001 From: Darrin Holst Date: Wed, 24 Feb 2010 12:37:31 -0600 Subject: [PATCH 12/84] emulate browser behavior in the rack driver by sending the button that was clicked even if it doesn't have a value --- lib/capybara/driver/rack_test_driver.rb | 8 +++---- spec/dsl/click_button_spec.rb | 28 +++++++++++++++---------- spec/views/form.erb | 1 + 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 3dc9acc0..e4c4a7be 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -106,7 +106,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base class Form < Node def params(button) params = {} - + text_fields = %w[text hidden password url color tel email search].map{|f| "@type='#{f}'"}.join(' or ') node.xpath(".//input[#{text_fields}]").map do |input| @@ -141,7 +141,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end end end - merge_param!(params, button[:name], button[:value]) if button[:name] + merge_param!(params, button[:name], button[:value] || "") if button[:name] params end @@ -154,7 +154,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end private - + def method self[:method] =~ /post/i ? :post : :get end @@ -200,7 +200,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end def submit(method, path, attributes) - path = current_path if not path or path.empty? + path = current_path if not path or path.empty? send(method, path, attributes, env) follow_redirects! cache_body diff --git a/spec/dsl/click_button_spec.rb b/spec/dsl/click_button_spec.rb index 7a96b8f2..1a2aad2b 100644 --- a/spec/dsl/click_button_spec.rb +++ b/spec/dsl/click_button_spec.rb @@ -13,33 +13,33 @@ shared_examples_for "click_button" do end context "with value given on a submit button" do - context "on a form with HTML5 fields" do + context "on a form with HTML5 fields" do before do @session.click_button('html5_submit') @results = extract_results(@session) end - + it "should serialise and submit search fields" do @results['html5_search'].should == 'what are you looking for' end - + it "should serialise and submit email fields" do @results['html5_email'].should == 'person@email.com' end - + it "should serialise and submit url fields" do @results['html5_url'].should == 'http://www.example.com' end - + it "should serialise and submit tel fields" do @results['html5_tel'].should == '911' end - + it "should serialise and submit color fields" do @results['html5_color'].should == '#FFF' - end + end end - + context "on an HTML4 form" do before do @session.click_button('awesome') @@ -175,7 +175,7 @@ shared_examples_for "click_button" do @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' @@ -190,6 +190,12 @@ shared_examples_for "click_button" do end end + it "should serialize and send valueless buttons that were clicked" do + @session.click_button('No Value!') + @results = extract_results(@session) + @results['no_value'].should_not be_nil + end + it "should serialize and send GET forms" do @session.visit('/form') @session.click_button('med') @@ -202,13 +208,13 @@ shared_examples_for "click_button" do @session.click_button('Go FAR') @session.body.should include('You landed') end - + it "should post pack to the same URL when no action given" do @session.visit('/postback') @session.click_button('With no action') @session.body.should include('Postback') end - + it "should post pack to the same URL when blank action given" do @session.visit('/postback') @session.click_button('With blank action') diff --git a/spec/views/form.erb b/spec/views/form.erb index b5cc45ab..d38656d5 100644 --- a/spec/views/form.erb +++ b/spec/views/form.erb @@ -153,6 +153,7 @@ +

From 99a3bd8f828502cb59a26a6f0ad32b7fe1c8aa7f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 25 Feb 2010 00:17:49 +0100 Subject: [PATCH 13/84] Added gemspec --- capybara.gemspec | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 capybara.gemspec diff --git a/capybara.gemspec b/capybara.gemspec new file mode 100644 index 00000000..363dfc20 --- /dev/null +++ b/capybara.gemspec @@ -0,0 +1,61 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{capybara} + s.version = "0.3.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Jonas Nicklas"] + s.date = %q{2010-02-25} + s.description = %q{Capybara aims to simplify the process of integration testing Rack applications, +such as Rails, Sinatra or Merb. It is inspired by and aims to replace Webrat as +a DSL for interacting with a webapplication. It is agnostic about the driver +running your tests and currently comes bundled with rack-test, Culerity, +Celerity and Selenium support built in.} + s.email = ["jonas.nicklas@gmail.com"] + s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"] + s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "config.ru", "lib/capybara.rb", "lib/capybara/cucumber.rb", "lib/capybara/driver/base.rb", "lib/capybara/driver/celerity_driver.rb", "lib/capybara/driver/culerity_driver.rb", "lib/capybara/driver/rack_test_driver.rb", "lib/capybara/driver/selenium_driver.rb", "lib/capybara/dsl.rb", "lib/capybara/node.rb", "lib/capybara/rails.rb", "lib/capybara/save_and_open_page.rb", "lib/capybara/searchable.rb", "lib/capybara/server.rb", "lib/capybara/session.rb", "lib/capybara/wait_until.rb", "lib/capybara/xpath.rb", "script/console", "script/destroy", "script/generate", "spec/capybara_spec.rb", "spec/driver/celerity_driver_spec.rb", "spec/driver/culerity_driver_spec.rb", "spec/driver/rack_test_driver_spec.rb", "spec/driver/remote_culerity_driver_spec.rb", "spec/driver/remote_selenium_driver_spec.rb", "spec/driver/selenium_driver_spec.rb", "spec/drivers_spec.rb", "spec/dsl/all_spec.rb", "spec/dsl/attach_file_spec.rb", "spec/dsl/check_spec.rb", "spec/dsl/choose_spec.rb", "spec/dsl/click_button_spec.rb", "spec/dsl/click_link_spec.rb", "spec/dsl/click_spec.rb", "spec/dsl/current_url_spec.rb", "spec/dsl/fill_in_spec.rb", "spec/dsl/find_button_spec.rb", "spec/dsl/find_by_id_spec.rb", "spec/dsl/find_field_spec.rb", "spec/dsl/find_link_spec.rb", "spec/dsl/find_spec.rb", "spec/dsl/has_button_spec.rb", "spec/dsl/has_content_spec.rb", "spec/dsl/has_css_spec.rb", "spec/dsl/has_field_spec.rb", "spec/dsl/has_link_spec.rb", "spec/dsl/has_xpath_spec.rb", "spec/dsl/locate_spec.rb", "spec/dsl/select_spec.rb", "spec/dsl/uncheck_spec.rb", "spec/dsl/within_spec.rb", "spec/dsl_spec.rb", "spec/fixtures/capybara.jpg", "spec/fixtures/test_file.txt", "spec/public/jquery-ui.js", "spec/public/jquery.js", "spec/public/test.js", "spec/save_and_open_page_spec.rb", "spec/searchable_spec.rb", "spec/server_spec.rb", "spec/session/celerity_session_spec.rb", "spec/session/culerity_session_spec.rb", "spec/session/rack_test_session_spec.rb", "spec/session/selenium_session_spec.rb", "spec/session_spec.rb", "spec/session_with_headers_support_spec.rb", "spec/session_with_javascript_support_spec.rb", "spec/session_without_headers_support_spec.rb", "spec/session_without_javascript_support_spec.rb", "spec/spec_helper.rb", "spec/test_app.rb", "spec/views/buttons.erb", "spec/views/fieldsets.erb", "spec/views/form.erb", "spec/views/postback.erb", "spec/views/tables.erb", "spec/views/with_html.erb", "spec/views/with_js.erb", "spec/views/with_scope.erb", "spec/views/with_simple_html.erb", "spec/wait_until_spec.rb", "spec/xpath_spec.rb"] + s.homepage = %q{http://github.com/jnicklas/capybara} + s.rdoc_options = ["--main", "README.rdoc"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{capybara} + s.rubygems_version = %q{1.3.5} + s.summary = %q{Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb} + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 1.3.3"]) + s.add_runtime_dependency(%q, [">= 1.16"]) + s.add_runtime_dependency(%q, [">= 0.2.4"]) + s.add_runtime_dependency(%q, [">= 0.0.3"]) + s.add_runtime_dependency(%q, [">= 1.0.0"]) + s.add_runtime_dependency(%q, [">= 0.5.2"]) + s.add_development_dependency(%q, [">= 0.9.4"]) + s.add_development_dependency(%q, [">= 1.2.9"]) + s.add_development_dependency(%q, [">= 2.5.0"]) + else + s.add_dependency(%q, [">= 1.3.3"]) + s.add_dependency(%q, [">= 1.16"]) + s.add_dependency(%q, [">= 0.2.4"]) + s.add_dependency(%q, [">= 0.0.3"]) + s.add_dependency(%q, [">= 1.0.0"]) + s.add_dependency(%q, [">= 0.5.2"]) + s.add_dependency(%q, [">= 0.9.4"]) + s.add_dependency(%q, [">= 1.2.9"]) + s.add_dependency(%q, [">= 2.5.0"]) + end + else + s.add_dependency(%q, [">= 1.3.3"]) + s.add_dependency(%q, [">= 1.16"]) + s.add_dependency(%q, [">= 0.2.4"]) + s.add_dependency(%q, [">= 0.0.3"]) + s.add_dependency(%q, [">= 1.0.0"]) + s.add_dependency(%q, [">= 0.5.2"]) + s.add_dependency(%q, [">= 0.9.4"]) + s.add_dependency(%q, [">= 1.2.9"]) + s.add_dependency(%q, [">= 2.5.0"]) + end +end From 125478fe2666e81d4c9ba3721dacf231987deb6c Mon Sep 17 00:00:00 2001 From: Bodaniel Jeanes Date: Thu, 25 Feb 2010 15:34:25 +1000 Subject: [PATCH 14/84] Added failing tests for click_button to find and submit image input buttons using the text of the alt attribute --- spec/dsl/click_button_spec.rb | 12 ++++++++++++ spec/views/form.erb | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/dsl/click_button_spec.rb b/spec/dsl/click_button_spec.rb index 7a96b8f2..59efe3c7 100644 --- a/spec/dsl/click_button_spec.rb +++ b/spec/dsl/click_button_spec.rb @@ -113,6 +113,18 @@ shared_examples_for "click_button" do @session.body.should include('You landed') end end + + context "with alt given on an image button" do + it "should submit the associated form" do + @session.click_button('oh hai thar') + extract_results(@session)['first_name'].should == 'John' + end + + it "should work with partial matches" do + @session.click_button('hai') + 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 diff --git a/spec/views/form.erb b/spec/views/form.erb index b5cc45ab..32d926ac 100644 --- a/spec/views/form.erb +++ b/spec/views/form.erb @@ -151,7 +151,7 @@ - +

From ffe2a89d383e358894150c05cf305fbd5cebd5e4 Mon Sep 17 00:00:00 2001 From: Bodaniel Jeanes Date: Thu, 25 Feb 2010 15:36:57 +1000 Subject: [PATCH 15/84] Fixed failing tests so input[@type='button'] can now be found via the value of the 'alt' attribute --- lib/capybara/xpath.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index 398ce2b0..9d3afcbc 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -80,6 +80,7 @@ module Capybara xpath = append("//input[@type='submit' or @type='image' or @type='button'][@id=#{s(locator)} or contains(@value,#{s(locator)})]") xpath = xpath.append("//button[@id=#{s(locator)} or contains(@value,#{s(locator)}) or contains(.,#{s(locator)})]") xpath = xpath.prepend("//input[@type='submit' or @type='image' or @type='button'][@value=#{s(locator)}]") + xpath = xpath.prepend("//input[@type='image'][@alt=#{s(locator)} or contains(@alt,#{s(locator)})]") xpath = xpath.prepend("//button[@value=#{s(locator)} or text()=#{s(locator)}]") end From e123a602c42991b611f4f506acac8e9396b50b93 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 25 Feb 2010 17:52:30 +0100 Subject: [PATCH 16/84] Added missing dsl methods --- lib/capybara/session.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index f98afd39..0bbcf7b1 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -9,7 +9,8 @@ module Capybara :field_labeled, :fill_in, :find, :find_button, :find_by_id, :find_field, :find_link, :has_content?, :has_css?, :has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck, :visit, :wait_until, :within, :within_fieldset, :within_table, :has_link?, :has_no_link?, :has_button?, :has_no_button?, - :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field? + :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field?, :has_no_table?, :has_table?, :unselect, + :has_select?, :has_no_select? ] attr_reader :mode, :app From 1f35a46388c1a7e392485d03edb1013939c5743b Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 25 Feb 2010 18:01:22 +0100 Subject: [PATCH 17/84] No more annoying deprecation warnings --- lib/capybara/driver/celerity_driver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/driver/celerity_driver.rb b/lib/capybara/driver/celerity_driver.rb index e3403675..4108859b 100644 --- a/lib/capybara/driver/celerity_driver.rb +++ b/lib/capybara/driver/celerity_driver.rb @@ -14,7 +14,7 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base end def value - if node.type == 'select-multiple' + if tag_name == "select" and node.multiple? node.selected_options else super From c23202bb3a015a001eca402fd3defae120ead0b0 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 25 Feb 2010 18:01:34 +0100 Subject: [PATCH 18/84] Number of tables has changed --- spec/drivers_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index b5fbb892..7f89d36d 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -115,7 +115,7 @@ shared_examples_for "driver with node path support" do end it "should be able to navigate/search child nodes" do - @node.all('//table').size.should == 3 + @node.all('//table').size.should == 5 @node.find('//form').all('//table').size.should == 1 @node.find('//form').find('//table//caption').text.should == 'Agent' end From eb9f552ca0752667c73cc7dd02ffae92baec6f12 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 25 Feb 2010 19:37:22 +0100 Subject: [PATCH 19/84] Fix multiple select values under selenium --- lib/capybara/driver/selenium_driver.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 2ac6ef47..9f424211 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -16,6 +16,14 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base nil end + def value + if tag_name == "select" and self[:multiple] + node.find_elements(:xpath, ".//option").select { |n| n.selected? }.map { |n| n.text } + else + super + end + end + def set(value) if tag_name == 'textarea' or (tag_name == 'input' and %w(text password hidden file).include?(type)) node.clear From e8846fb48834744eb3bd1410be2f496f4108bcfc Mon Sep 17 00:00:00 2001 From: Steven Parkes Date: Thu, 25 Feb 2010 14:51:51 -0800 Subject: [PATCH 20/84] Support external drivers and a few tweaks to support the envjs driver * Added code to find drivers that are externally loaded * Support wait_until in driver * Optionally make xpath absolute paths absolute * Add predicate to test if drivers shortcircuit waits and tweak spec * Allows file:/// (envjs) urls as well as http://foo urls (rack) * Warm the driver in wait_until tests so the init cost isn't included in the test --- lib/capybara/driver/base.rb | 11 +++++++++++ lib/capybara/session.rb | 17 ++++++----------- lib/capybara/wait_until.rb | 9 ++++++--- spec/drivers_spec.rb | 12 +++++++++--- spec/dsl/current_url_spec.rb | 2 +- spec/session_with_javascript_support_spec.rb | 7 ++++++- 6 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 6cf8c00f..d34d44a5 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -19,6 +19,9 @@ class Capybara::Driver::Base false end + def wait_until *args + end + def response_headers raise Capybara::NotSupportedByDriverError end @@ -34,4 +37,12 @@ class Capybara::Driver::Base def cleanup! end + def obeys_absolute_xpath + false + end + + def has_shortcircuit_timeout + false + end + end diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 0bbcf7b1..a6a9abbb 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -21,16 +21,11 @@ module Capybara end def driver - @driver ||= case mode - when :rack_test - Capybara::Driver::RackTest.new(app) - when :selenium - Capybara::Driver::Selenium.new(app) - when :celerity - Capybara::Driver::Celerity.new(app) - when :culerity - Capybara::Driver::Culerity.new(app) - else + @driver ||= begin + string = mode.to_s + string.gsub!(%r{(^.)|(_.)}) { |m| m[m.length-1,1].upcase } + Capybara::Driver.const_get(string.to_sym).new(app) + rescue NameError raise Capybara::DriverNotFoundError, "no driver called #{mode} was found" end end @@ -245,7 +240,7 @@ module Capybara end def wait_until(timeout = Capybara.default_wait_time) - WaitUntil.timeout(timeout) { yield } + WaitUntil.timeout(timeout,driver) { yield } end def evaluate_script(script) diff --git a/lib/capybara/wait_until.rb b/lib/capybara/wait_until.rb index 88d5a704..7d661979 100644 --- a/lib/capybara/wait_until.rb +++ b/lib/capybara/wait_until.rb @@ -4,7 +4,7 @@ module Capybara class << self - def timeout(seconds = 1, &block) + def timeout(seconds = 1, driver = nil, &block) start_time = Time.now result = nil @@ -12,9 +12,12 @@ module Capybara until result return result if result = yield - if (Time.now - start_time) > seconds - raise TimeoutError + delay = seconds - (Time.now - start_time) + if delay <= 0 + raise TimeoutError end + + driver && driver.wait_until(delay) end end diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index 7f89d36d..5d44ef66 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -115,9 +115,15 @@ shared_examples_for "driver with node path support" do end it "should be able to navigate/search child nodes" do - @node.all('//table').size.should == 5 - @node.find('//form').all('//table').size.should == 1 - @node.find('//form').find('//table//caption').text.should == 'Agent' + if @driver.obeys_absolute_xpath + @node.all('.//table').size.should == 5 + @node.find('.//form').all('.//table').size.should == 1 + @node.find('.//form').find('.//table//caption').text.should == 'Agent' + else + @node.all('//table').size.should == 5 + @node.find('//form').all('//table').size.should == 1 + @node.find('//form').find('//table//caption').text.should == 'Agent' + end end end end diff --git a/spec/dsl/current_url_spec.rb b/spec/dsl/current_url_spec.rb index c514d3ea..27074f08 100644 --- a/spec/dsl/current_url_spec.rb +++ b/spec/dsl/current_url_spec.rb @@ -2,7 +2,7 @@ shared_examples_for "current_url" do describe '#current_url' do it "should return the current url" do @session.visit('/form') - @session.current_url.should =~ %r(http://[^/]+/form) + @session.current_url.should =~ %r((file|http)://[^/]*/form) end end end diff --git a/spec/session_with_javascript_support_spec.rb b/spec/session_with_javascript_support_spec.rb index 4a6dc66c..21a0d8f0 100644 --- a/spec/session_with_javascript_support_spec.rb +++ b/spec/session_with_javascript_support_spec.rb @@ -90,12 +90,17 @@ shared_examples_for "session with javascript support" do end it "should default to Capybara.default_wait_time before timeout" do + @session.driver # init the driver to exclude init timing from test 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) + if @session.driver.has_shortcircuit_timeout + (Time.now - start).should be_close(0, 0.1) + else + (Time.now - start).should be_close(0.2, 0.1) + end end end From 2f3dc8f53405190aec39e060abdd6fac17cfd724 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 01:04:00 +0100 Subject: [PATCH 21/84] Wrap JS specs in describe block so timeout change only affects them This caused some specs to time out and fail --- spec/session_with_javascript_support_spec.rb | 324 ++++++++++--------- 1 file changed, 163 insertions(+), 161 deletions(-) diff --git a/spec/session_with_javascript_support_spec.rb b/spec/session_with_javascript_support_spec.rb index 4a6dc66c..a89696a1 100644 --- a/spec/session_with_javascript_support_spec.rb +++ b/spec/session_with_javascript_support_spec.rb @@ -3,180 +3,182 @@ require File.expand_path('spec_helper', File.dirname(__FILE__)) require 'nokogiri' shared_examples_for "session with javascript support" do - before do - Capybara.default_wait_time = 1 - end - - after do - Capybara.default_wait_time = 0 - end - - describe '#find' do - it "should allow triggering of custom JS events" do - pending "cannot figure out how to do this with selenium" if @session.mode == :selenium - @session.visit('/with_js') - @session.find(:css, '#with_focus_event').trigger(:focus) - @session.should have_css('#focus_event_triggered') - end - end - - describe '#body' do - it "should return the current state of the page" do - @session.visit('/with_js') - @session.body.should include('I changed it') - @session.body.should_not include('This is text') - end - end - - describe '#source' do - it "should return the original, unmodified source of the page" do - pending "cannot figure out how to do this with selenium" if @session.mode == :selenium - @session.visit('/with_js') - @session.source.should include('This is text') - @session.source.should_not include('I changed it') - end - end - - describe "#evaluate_script" do - it "should return the evaluated script" do - @session.visit('/with_js') - @session.evaluate_script("1+3").should == 4 - end - end - - describe '#locate' do - it "should wait for asynchronous load" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.locate("//a[contains(.,'Has been clicked')]")[:href].should == '#' - end - end - - describe '#wait_until' do + describe 'all JS specs' do before do - @default_timeout = Capybara.default_wait_time + Capybara.default_wait_time = 1 end after do - Capybara.default_wait_time = @default_wait_time + Capybara.default_wait_time = 0 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 - @session.wait_until do - @session.evaluate_script('activeRequests == 0') + + describe '#find' do + it "should allow triggering of custom JS events" do + pending "cannot figure out how to do this with selenium" if @session.mode == :selenium + @session.visit('/with_js') + @session.find(:css, '#with_focus_event').trigger(:focus) + @session.should have_css('#focus_event_triggered') end - @session.evaluate_script('activeRequests == 0').should be_true end - it "should raise Capybara::TimeoutError if block doesn't return true within timeout" do - @session.visit('/with_html') - Proc.new do - @session.wait_until(0.1) do - @session.find('//div[@id="nosuchthing"]') + describe '#body' do + it "should return the current state of the page" do + @session.visit('/with_js') + @session.body.should include('I changed it') + @session.body.should_not include('This is text') + end + end + + describe '#source' do + it "should return the original, unmodified source of the page" do + pending "cannot figure out how to do this with selenium" if @session.mode == :selenium + @session.visit('/with_js') + @session.source.should include('This is text') + @session.source.should_not include('I changed it') + end + end + + describe "#evaluate_script" do + it "should return the evaluated script" do + @session.visit('/with_js') + @session.evaluate_script("1+3").should == 4 + end + end + + describe '#locate' do + it "should wait for asynchronous load" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.locate("//a[contains(.,'Has been clicked')]")[:href].should == '#' + end + end + + 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 + @session.visit('/with_js') + @session.select('My Waiting Option', :from => 'waiter') + @session.evaluate_script('activeRequests == 1').should be_true + @session.wait_until do + @session.evaluate_script('activeRequests == 0') end - end.should raise_error(::Capybara::TimeoutError) + @session.evaluate_script('activeRequests == 0').should be_true + end + + it "should raise Capybara::TimeoutError if block doesn't return true within timeout" do + @session.visit('/with_html') + 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 + + 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 - 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) + describe '#click' do + it "should wait for asynchronous load" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.click('Has been clicked') + end end - 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) + describe '#click_link' do + it "should wait for asynchronous load" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.click_link('Has been clicked') + end end + + describe '#click_button' do + it "should wait for asynchronous load" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.click_button('New Here') + end + end + + describe '#fill_in' do + it "should wait for asynchronous load" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.fill_in('new_field', :with => 'Testing...') + end + end + + describe '#has_xpath?' do + it "should wait for content to appear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_xpath("//input[@type='submit' and @value='New Here']") + end + end + + describe '#has_no_xpath?' do + it "should wait for content to disappear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_no_xpath("//p[@id='change']") + end + end + + describe '#has_css?' do + it "should wait for content to appear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_css("input[type='submit'][value='New Here']") + end + end + + describe '#has_no_xpath?' do + it "should wait for content to disappear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_no_css("p#change") + end + end + + describe '#has_content?' do + it "should wait for content to appear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_content("Has been clicked") + end + end + + describe '#has_no_content?' do + it "should wait for content to disappear" do + @session.visit('/with_js') + @session.click_link('Click me') + @session.should have_no_content("I changed it") + end + end + end - - describe '#click' do - it "should wait for asynchronous load" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.click('Has been clicked') - end - end - - describe '#click_link' do - it "should wait for asynchronous load" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.click_link('Has been clicked') - end - end - - describe '#click_button' do - it "should wait for asynchronous load" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.click_button('New Here') - end - end - - describe '#fill_in' do - it "should wait for asynchronous load" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.fill_in('new_field', :with => 'Testing...') - end - end - - describe '#has_xpath?' do - it "should wait for content to appear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_xpath("//input[@type='submit' and @value='New Here']") - end - end - - describe '#has_no_xpath?' do - it "should wait for content to disappear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_no_xpath("//p[@id='change']") - end - end - - describe '#has_css?' do - it "should wait for content to appear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_css("input[type='submit'][value='New Here']") - end - end - - describe '#has_no_xpath?' do - it "should wait for content to disappear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_no_css("p#change") - end - end - - describe '#has_content?' do - it "should wait for content to appear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_content("Has been clicked") - end - end - - describe '#has_no_content?' do - it "should wait for content to disappear" do - @session.visit('/with_js') - @session.click_link('Click me') - @session.should have_no_content("I changed it") - end - end - end From 0ed383238fd440e2e3fedcebca480e04bf68b1c2 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 01:14:58 +0100 Subject: [PATCH 22/84] Init C[ue]lerity driver/session in before(:all) This way we don't create a crap load of instances which leads to out-of-memory exceptions. --- spec/driver/celerity_driver_spec.rb | 4 ++-- spec/driver/culerity_driver_spec.rb | 2 +- spec/driver/remote_culerity_driver_spec.rb | 5 +---- spec/session/celerity_session_spec.rb | 4 ++-- spec/session/culerity_session_spec.rb | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/spec/driver/celerity_driver_spec.rb b/spec/driver/celerity_driver_spec.rb index bd31440a..3ed2e096 100644 --- a/spec/driver/celerity_driver_spec.rb +++ b/spec/driver/celerity_driver_spec.rb @@ -2,7 +2,7 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__)) if RUBY_PLATFORM =~ /java/ describe Capybara::Driver::Celerity do - before do + before(:all) do @driver = Capybara::Driver::Celerity.new(TestApp) end @@ -14,4 +14,4 @@ if RUBY_PLATFORM =~ /java/ end else puts "#{File.basename(__FILE__)} requires JRuby; skipping.." -end \ No newline at end of file +end diff --git a/spec/driver/culerity_driver_spec.rb b/spec/driver/culerity_driver_spec.rb index ec6a4e3d..ee0fac38 100644 --- a/spec/driver/culerity_driver_spec.rb +++ b/spec/driver/culerity_driver_spec.rb @@ -1,7 +1,7 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__)) describe Capybara::Driver::Culerity do - before do + before(:all) do @driver = Capybara::Driver::Culerity.new(TestApp) end diff --git a/spec/driver/remote_culerity_driver_spec.rb b/spec/driver/remote_culerity_driver_spec.rb index e30fc16d..d3a2c5bd 100644 --- a/spec/driver/remote_culerity_driver_spec.rb +++ b/spec/driver/remote_culerity_driver_spec.rb @@ -1,13 +1,10 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__)) describe Capybara::Driver::Culerity do - before do - @driver = Capybara::Driver::Culerity.new(TestApp) - end - before(:all) do Capybara.app_host = "http://capybara-testapp.heroku.com" Capybara.run_server = false + @driver = Capybara::Driver::Culerity.new(TestApp) end after(:all) do diff --git a/spec/session/celerity_session_spec.rb b/spec/session/celerity_session_spec.rb index 83c06c67..d6b8e989 100644 --- a/spec/session/celerity_session_spec.rb +++ b/spec/session/celerity_session_spec.rb @@ -2,7 +2,7 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__)) if RUBY_PLATFORM =~ /java/ describe Capybara::Driver::Celerity do - before do + before(:all) do @session = Capybara::Session.new(:celerity, TestApp) end @@ -24,4 +24,4 @@ if RUBY_PLATFORM =~ /java/ end else puts "#{File.basename(__FILE__)} requires JRuby; skipping.." -end \ No newline at end of file +end diff --git a/spec/session/culerity_session_spec.rb b/spec/session/culerity_session_spec.rb index 958308b9..6bff94fd 100644 --- a/spec/session/culerity_session_spec.rb +++ b/spec/session/culerity_session_spec.rb @@ -2,7 +2,7 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__)) describe Capybara::Session do context 'with culerity driver' do - before do + before(:all) do @session = Capybara::Session.new(:culerity, TestApp) end From 58380cce3d2121fbafd7e21ddd6969a56508a176 Mon Sep 17 00:00:00 2001 From: Steven Parkes Date: Thu, 25 Feb 2010 16:32:24 -0800 Subject: [PATCH 23/84] revert spec chanage; disallow file urls again --- spec/dsl/current_url_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/dsl/current_url_spec.rb b/spec/dsl/current_url_spec.rb index 27074f08..c514d3ea 100644 --- a/spec/dsl/current_url_spec.rb +++ b/spec/dsl/current_url_spec.rb @@ -2,7 +2,7 @@ shared_examples_for "current_url" do describe '#current_url' do it "should return the current url" do @session.visit('/form') - @session.current_url.should =~ %r((file|http)://[^/]*/form) + @session.current_url.should =~ %r(http://[^/]+/form) end end end From 20e32d9d4a7ccea3ca07e5460671b475b4184929 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 09:04:45 +0100 Subject: [PATCH 24/84] Darrin Holst to contributors --- README.rdoc | 1 + lib/capybara/server.rb | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.rdoc b/README.rdoc index ef22bd3d..6042ed3c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -377,6 +377,7 @@ The following people have dedicated their time and effort to Capybara: * Pavel Gabriel * Bodaniel Jeanes * Carl Porth +* Darrin Holst == License: diff --git a/lib/capybara/server.rb b/lib/capybara/server.rb index 3723547b..5d2840a3 100644 --- a/lib/capybara/server.rb +++ b/lib/capybara/server.rb @@ -59,16 +59,18 @@ class Capybara::Server Capybara.log "application has already booted" and return self if responsive? Capybara.log "booting Rack applicartion on port #{port}" - Timeout.timeout(10) do - Thread.new do - handler.run(Identify.new(@app), :Port => port, :AccessLog => []) - end - Capybara.log "checking if application has booted" + Thread.new do + handler.run(Identify.new(@app), :Port => port, :AccessLog => []) + end + Capybara.log "checking if application has booted" - loop do - Capybara.log("application has booted") and break if responsive? - Capybara.log("waiting for application to boot...") + Capybara::WaitUntil.timeout(10) do + if responsive? + Capybara.log("application has booted") + true + else sleep 0.5 + false end end self From 9a19b758cade62a52e0039cffd713a5f98a3b852 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 18:38:22 +0100 Subject: [PATCH 25/84] All drivers now support relative searching There is a bug in Selenium, which causes it to find only descendant nodes, even when asked for a global search. Bug filed here: http://code.google.com/p/selenium/issues/detail?id=403 --- lib/capybara/driver/celerity_driver.rb | 8 ++++ lib/capybara/driver/rack_test_driver.rb | 4 ++ lib/capybara/driver/selenium_driver.rb | 4 ++ spec/driver/culerity_driver_spec.rb | 1 - spec/driver/rack_test_driver_spec.rb | 1 - spec/driver/selenium_driver_spec.rb | 1 - spec/drivers_spec.rb | 52 ++++++++++--------------- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/lib/capybara/driver/celerity_driver.rb b/lib/capybara/driver/celerity_driver.rb index 4108859b..d5c63e8d 100644 --- a/lib/capybara/driver/celerity_driver.rb +++ b/lib/capybara/driver/celerity_driver.rb @@ -77,6 +77,14 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base node.fire_event(event.to_s) end + private + + def all_unfiltered(locator) + noko_node = Nokogiri::HTML(driver.body).xpath(node.xpath).first + all_nodes = noko_node.xpath(locator).map { |n| n.path }.join(' | ') + driver.find(all_nodes) + end + end attr_reader :app, :rack_server diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index e4c4a7be..dc0c2c1a 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -94,6 +94,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base private + def all_unfiltered(locator) + node.xpath(locator).map { |n| self.class.new(driver, n) } + end + def type node[:type] end diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 9f424211..20e08407 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -78,6 +78,10 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base private + def all_unfiltered(locator) + node.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) } + end + def type self[:type] end diff --git a/spec/driver/culerity_driver_spec.rb b/spec/driver/culerity_driver_spec.rb index ee0fac38..c01ab97c 100644 --- a/spec/driver/culerity_driver_spec.rb +++ b/spec/driver/culerity_driver_spec.rb @@ -8,6 +8,5 @@ describe Capybara::Driver::Culerity do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" it_should_behave_like "driver with header support" - it_should_behave_like "driver with node path support" end diff --git a/spec/driver/rack_test_driver_spec.rb b/spec/driver/rack_test_driver_spec.rb index 7b2c8d67..e4b03d5e 100644 --- a/spec/driver/rack_test_driver_spec.rb +++ b/spec/driver/rack_test_driver_spec.rb @@ -7,6 +7,5 @@ describe Capybara::Driver::RackTest do it_should_behave_like "driver" it_should_behave_like "driver with header support" - it_should_behave_like "driver with node path support" end diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index a71047e0..c2b2b4c1 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -7,6 +7,5 @@ describe Capybara::Driver::Selenium do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" - it_should_behave_like "driver without node path support" end diff --git a/spec/drivers_spec.rb b/spec/drivers_spec.rb index 7f89d36d..c1614686 100644 --- a/spec/drivers_spec.rb +++ b/spec/drivers_spec.rb @@ -72,6 +72,26 @@ shared_examples_for 'driver' do end end + describe "node relative searching" do + before do + @driver.visit('/tables') + @node = @driver.find('//body').first + end + + it "should be able to navigate/search child node" do + @node.all('//table').size.should == 5 + @node.find('//form').all('.//table').size.should == 1 + @node.find('//form').find('.//table//caption').text.should == 'Agent' + if @driver.class == Capybara::Driver::Selenium + pending("Selenium gets this wrong, see http://code.google.com/p/selenium/issues/detail?id=403") do + @node.find('//form').all('//table').size.should == 5 + end + else + @node.find('//form').all('//table').size.should == 5 + end + end + end + end shared_examples_for "driver with javascript support" do @@ -97,7 +117,6 @@ shared_examples_for "driver with javascript support" do @driver.evaluate_script('1+1').should == 2 end end - end shared_examples_for "driver with header support" do @@ -106,34 +125,3 @@ shared_examples_for "driver with header support" do @driver.response_headers['Content-Type'].should == 'text/html' end end - -shared_examples_for "driver with node path support" do - describe "node relative searching" do - before do - @driver.visit('/tables') - @node = @driver.find('//body').first - end - - it "should be able to navigate/search child nodes" do - @node.all('//table').size.should == 5 - @node.find('//form').all('//table').size.should == 1 - @node.find('//form').find('//table//caption').text.should == 'Agent' - end - end -end - -shared_examples_for "driver without node path support" do - describe "node relative searching" do - before do - @driver.visit('/tables') - @node = @driver.find('//body').first - end - - it "should get NotSupportedByDriverError" do - running do - @node.all('//form') - end.should raise_error(Capybara::NotSupportedByDriverError) - end - - end -end From a0e9d78d8f41b90ee3eed76e047082ac3ccfd32b Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 18:39:23 +0100 Subject: [PATCH 26/84] Yo dawg, I put a revert in ur revert Readding support for specifying host for mock rack session This reverts commit 62bd215a476d84da5311a32ecb00fee0d9a8c3e7. --- lib/capybara.rb | 2 +- lib/capybara/driver/rack_test_driver.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/capybara.rb b/lib/capybara.rb index 3ca07809..5cddde47 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -15,7 +15,7 @@ module Capybara class InfiniteRedirectError < TimeoutError; end class << self - attr_accessor :debug, :asset_root, :app_host, :run_server + attr_accessor :debug, :asset_root, :app_host, :run_server, :default_host attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements def default_selector diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index dc0c2c1a..f11fe83d 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -216,6 +216,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base private + def build_rack_mock_session # :nodoc: + Rack::MockSession.new(app, Capybara.default_host) + end + def current_path request.path rescue "" end From 3d673af67178f10e0dcc1127870fe362c2c63300 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 18:52:28 +0100 Subject: [PATCH 27/84] added History for Capybara 0.3.5 --- History.txt | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/History.txt b/History.txt index 01496bb3..ceb169d1 100644 --- a/History.txt +++ b/History.txt @@ -1,4 +1,34 @@ -=== 0.0.1 2009-11-04 +# Version 0.3.5 + +Release date: 2010-02-26 + +This is a mostly backwards compatible release, it does break +the API in some minor places, which should hopefully not affect +too many users, please read the release notes carefully! + +### Breaking + +* Relative searching in a node (e.g. find('//p').all('//a')) will now follow XPath standard + this means that if you want to find descendant nodes only, you'll need to prefix a dot! +* `visit` now accepts fully qualified URLs for drivers that support it. +* Capybara will always try to run a rack server, unless you set Capybara.run_sever = false + +### Changed + +* thin is preferred over mongrel and webrick, since it is Ruby 1.9 compatible +* click_button and click will find , clicking them does nothing in RackTest + +### Added + +* Much improved error messages in a multitude of places +* More semantic page querying with has_link?, has_button?, etc... +* Option to ignore hidden elements when querying and interacting with the page +* Support for multiple selects + +### Fixed + +* find_by_id is no longer broken +* clicking links where the image's alt attribute contains the text is now possible +* within_fieldset and within_table work when the default selector is CSS +* boolean attributes work the same across drivers (return true/false) -* 1 major enhancement: - * Initial release From c7a79731e5dba9ff6b37fef475739a64d8a75dba Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 18:56:38 +0100 Subject: [PATCH 28/84] Added default host when not set --- lib/capybara/driver/rack_test_driver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index f11fe83d..89ab5047 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -217,7 +217,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base private def build_rack_mock_session # :nodoc: - Rack::MockSession.new(app, Capybara.default_host) + Rack::MockSession.new(app, Capybara.default_host || "example.org") end def current_path From 322cdf43856a50684709dd9bd5947d0275fe7110 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 26 Feb 2010 18:56:52 +0100 Subject: [PATCH 29/84] Tagged Version 0.3.5 --- lib/capybara.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara.rb b/lib/capybara.rb index 5cddde47..acf3e57e 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -2,7 +2,7 @@ require 'timeout' require 'nokogiri' module Capybara - VERSION = '0.3.0' + VERSION = '0.3.5' class CapybaraError < StandardError; end class DriverNotFoundError < CapybaraError; end From c1eed949b324cc99b02f9ece4ab3ec199f7bcb17 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sat, 27 Feb 2010 02:31:27 +0100 Subject: [PATCH 30/84] Changed fallback host to www.example.com This matches with Cucumber, and should hopefully cause somewhat less lost sessions --- lib/capybara/driver/rack_test_driver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 89ab5047..831f88da 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -217,7 +217,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base private def build_rack_mock_session # :nodoc: - Rack::MockSession.new(app, Capybara.default_host || "example.org") + Rack::MockSession.new(app, Capybara.default_host || "www.example.com") end def current_path From b8154a2f32b3bd2d85e78f830a4d927bff8edbce Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sat, 27 Feb 2010 19:26:38 +0100 Subject: [PATCH 31/84] Removed unused base code for relative finds --- lib/capybara/node.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/capybara/node.rb b/lib/capybara/node.rb index acbc610c..8db3fa1d 100644 --- a/lib/capybara/node.rb +++ b/lib/capybara/node.rb @@ -56,14 +56,5 @@ module Capybara def trigger(event) raise NotSupportedByDriverError end - - private - - def all_unfiltered(locator) - nodes = XPath.wrap(locator).scope(path).paths.map do |path| - driver.find(path) - end.flatten - end - end end From d298f4dc8c5030db1708fa3c10cc45afca2f9b23 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sat, 27 Feb 2010 19:27:06 +0100 Subject: [PATCH 32/84] Use #click instead of #toggle for Selenium, Closes #50 --- lib/capybara/driver/selenium_driver.rb | 2 +- spec/public/test.js | 5 ++++- spec/session_with_javascript_support_spec.rb | 8 ++++++++ spec/views/with_js.erb | 5 +++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 20e08407..8c289f2c 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -31,7 +31,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base elsif tag_name == 'input' and type == 'radio' node.select elsif tag_name == 'input' and type == 'checkbox' - node.toggle + node.click end end diff --git a/spec/public/test.js b/spec/public/test.js index 4eeb9d39..7ec9cd16 100644 --- a/spec/public/test.js +++ b/spec/public/test.js @@ -27,4 +27,7 @@ $(function() { $('#with_focus_event').focus(function() { $('body').append('

Focus Event triggered

') }); -}); \ No newline at end of file + $('#checkbox_with_event').click(function() { + $('body').append('

Checkbox event triggered

') + }); +}); diff --git a/spec/session_with_javascript_support_spec.rb b/spec/session_with_javascript_support_spec.rb index a89696a1..d414c7ba 100644 --- a/spec/session_with_javascript_support_spec.rb +++ b/spec/session_with_javascript_support_spec.rb @@ -132,6 +132,14 @@ shared_examples_for "session with javascript support" do end end + describe '#check' do + it "should trigger associated events" do + @session.visit('/with_js') + @session.check('checkbox_with_event') + @session.should have_css('#checkbox_event_triggered'); + end + end + describe '#has_xpath?' do it "should wait for content to appear" do @session.visit('/with_js') diff --git a/spec/views/with_js.erb b/spec/views/with_js.erb index 39b829c6..1517d67c 100644 --- a/spec/views/with_js.erb +++ b/spec/views/with_js.erb @@ -30,5 +30,10 @@

+ +

+ +

+ From 7635d98530ba257c75348b8976099dc76d81ba7e Mon Sep 17 00:00:00 2001 From: Steven Parkes Date: Tue, 2 Mar 2010 11:56:41 -0800 Subject: [PATCH 33/84] remove predicate; changed in upstream --- lib/capybara/driver/base.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index d34d44a5..effb1bd8 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -37,10 +37,6 @@ class Capybara::Driver::Base def cleanup! end - def obeys_absolute_xpath - false - end - def has_shortcircuit_timeout false end From 599424181c395c40be567d93cc0cdf7634ce6c18 Mon Sep 17 00:00:00 2001 From: Steven Parkes Date: Tue, 2 Mar 2010 14:37:02 -0800 Subject: [PATCH 34/84] better name for predicate --- lib/capybara/driver/base.rb | 2 +- spec/session_with_javascript_support_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index effb1bd8..bf34728b 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -37,7 +37,7 @@ class Capybara::Driver::Base def cleanup! end - def has_shortcircuit_timeout + def has_shortcircuit_timeout? false end diff --git a/spec/session_with_javascript_support_spec.rb b/spec/session_with_javascript_support_spec.rb index 7f3f613f..74b9bd19 100644 --- a/spec/session_with_javascript_support_spec.rb +++ b/spec/session_with_javascript_support_spec.rb @@ -97,7 +97,7 @@ shared_examples_for "session with javascript support" do begin @session.wait_until { false } rescue Capybara::TimeoutError; end - if @session.driver.has_shortcircuit_timeout + if @session.driver.has_shortcircuit_timeout? (Time.now - start).should be_close(0, 0.1) else (Time.now - start).should be_close(0.2, 0.1) From 0e6836f54827d0af638bac88167314cfbbcfe77c Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 12 Mar 2010 19:07:15 +0100 Subject: [PATCH 35/84] App is optional --- lib/capybara/session.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 0bbcf7b1..f14c8135 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -15,7 +15,7 @@ module Capybara attr_reader :mode, :app - def initialize(mode, app) + def initialize(mode, app=nil) @mode = mode @app = app end From 2b6fd77db5473ce74fea5363ce25ff9b488cd0d7 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 12 Mar 2010 19:14:10 +0100 Subject: [PATCH 36/84] Make sure server does nothing when no app given --- lib/capybara/server.rb | 1 + spec/server_spec.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib/capybara/server.rb b/lib/capybara/server.rb index 5d2840a3..c937c8a3 100644 --- a/lib/capybara/server.rb +++ b/lib/capybara/server.rb @@ -55,6 +55,7 @@ class Capybara::Server end def boot + return self unless @app find_available_port Capybara.log "application has already booted" and return self if responsive? Capybara.log "booting Rack applicartion on port #{port}" diff --git a/spec/server_spec.rb b/spec/server_spec.rb index 35a1ad28..2c8ed174 100644 --- a/spec/server_spec.rb +++ b/spec/server_spec.rb @@ -10,6 +10,12 @@ describe Capybara::Server do @res.body.should include('Hello Server') end + + it "should do nothing when no server given" do + running do + @server = Capybara::Server.new(nil).boot + end.should_not raise_error + end it "should find an available port" do @app1 = proc { |env| [200, {}, "Hello Server!"]} From 113823e3b1cbea65d2b91295deab649f7edefe51 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 12 Mar 2010 19:16:09 +0100 Subject: [PATCH 37/84] Make from_css an instance method on XPath --- lib/capybara/xpath.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index 9d3afcbc..2077de3e 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -5,11 +5,6 @@ module Capybara class XPath class << self - def from_css(css) - Nokogiri::CSS.xpath_for(css).first - end - alias_method :for_css, :from_css - def wrap(path) if path.is_a?(self) path @@ -33,6 +28,11 @@ module Capybara @paths = paths end + def from_css(css) + append(Nokogiri::CSS.xpath_for(css).first) + end + alias_method :for_css, :from_css + def field(locator, options={}) if options[:with] fillable_field(locator, options) From eef3a2c6bb43dd4985b1fa16d762f61d6d4fa013 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 12 Mar 2010 20:11:21 +0100 Subject: [PATCH 38/84] Send input with custom types This puts the rack-test driver more inline with how real browsers work by sending all inputs with types it doesn't recognize as though they were type="text". --- lib/capybara/driver/rack_test_driver.rb | 8 ++++---- lib/capybara/xpath.rb | 27 ++++++++++++------------- spec/dsl/fill_in_spec.rb | 12 +++++++++++ spec/views/form.erb | 5 +++++ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 831f88da..14ab0f38 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -28,9 +28,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base def set(value) - if tag_name == 'input' and %w(text password hidden file).include?(type) - node['value'] = value.to_s - elsif tag_name == 'input' and type == 'radio' + if tag_name == 'input' and type == 'radio' driver.html.xpath("//input[@name='#{self[:name]}']").each { |node| node.remove_attribute("checked") } node['checked'] = 'checked' elsif tag_name == 'input' and type == 'checkbox' @@ -39,6 +37,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base else node.remove_attribute('checked') end + elsif tag_name == 'input' + node['value'] = value.to_s elsif tag_name == "textarea" node.content = value.to_s end @@ -113,7 +113,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base text_fields = %w[text hidden password url color tel email search].map{|f| "@type='#{f}'"}.join(' or ') - node.xpath(".//input[#{text_fields}]").map do |input| + node.xpath(".//input[@type!='radio' and @type!='checkbox' and @type!='submit']").map do |input| merge_param!(params, input['name'].to_s, input['value'].to_s) end node.xpath(".//textarea").map do |textarea| diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index 2077de3e..bf23778f 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -46,9 +46,7 @@ module Capybara end def fillable_field(locator, options={}) - [:text, :password, :email, :url, :search, :tel, :color].inject(text_area(locator, options)) do |all, type| - all.input_field(type, locator, options) - end + text_area(locator, options).text_field(locator, options) end def content(locator) @@ -84,6 +82,11 @@ module Capybara xpath = xpath.prepend("//button[@value=#{s(locator)} or text()=#{s(locator)}]") end + def text_field(locator, options={}) + options = options.merge(:value => options[:with]) if options.has_key?(:with) + add_field(locator, "//input[@type!='radio' and @type!='checkbox' and @type!='hidden']", options) + end + def text_area(locator, options={}) options = options.merge(:text => options[:with]) if options.has_key?(:with) add_field(locator, "//textarea", options) @@ -93,11 +96,6 @@ module Capybara add_field(locator, "//select", options) end - def input_field(type, locator, options={}) - options = options.merge(:value => options[:with]) if options.has_key?(:with) - add_field(locator, "//input[@type='#{type}']", options) - end - def scope(scope) XPath.new(*paths.map { |p| scope + p }) end @@ -122,16 +120,17 @@ module Capybara input_field(:radio, locator, options) end - [:text, :password, :email, :url, :search, :tel, :color, :file].each do |type| - class_eval <<-RUBY, __FILE__, __LINE__+1 - def #{type}_field(locator) - input_field(:#{type}, locator) - end - RUBY + def file_field(locator, options={}) + input_field(:file, locator, options) end protected + def input_field(type, locator, options={}) + options = options.merge(:value => options[:with]) if options.has_key?(:with) + add_field(locator, "//input[@type='#{type}']", options) + end + # place this between to nodes to indicate that they should be siblings def sibling '/following-sibling::*[1]/self::' diff --git a/spec/dsl/fill_in_spec.rb b/spec/dsl/fill_in_spec.rb index aaaf8339..3d7ed539 100644 --- a/spec/dsl/fill_in_spec.rb +++ b/spec/dsl/fill_in_spec.rb @@ -52,6 +52,18 @@ shared_examples_for "fill_in" do extract_results(@session)['password'].should == 'supasikrit' end + it "should fill in a field with a custom type" do + @session.fill_in('Schmooo', :with => 'Schmooo is the game') + @session.click_button('awesome') + extract_results(@session)['schmooo'].should == 'Schmooo is the game' + end + + it "should fill in a password field by name" 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') diff --git a/spec/views/form.erb b/spec/views/form.erb index 5c438c5c..4228d95a 100644 --- a/spec/views/form.erb +++ b/spec/views/form.erb @@ -32,6 +32,11 @@

+ +

+ + +

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat Redirect pariatur. Excepteur sint occaecat cupidatat non proident, - sunt in culpa qui officia deserunt mollit anim id est laborum. + sunt in culpa qui officia + text with + whitespace + id est laborum.

From 240748918bf8f1d5cbcfe09b44e1af47b7fb299f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 22 Mar 2010 23:43:55 +0000 Subject: [PATCH 53/84] selenium can't fill in custom fields --- spec/dsl/fill_in_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/dsl/fill_in_spec.rb b/spec/dsl/fill_in_spec.rb index 3d7ed539..ddbe6dd3 100644 --- a/spec/dsl/fill_in_spec.rb +++ b/spec/dsl/fill_in_spec.rb @@ -53,6 +53,7 @@ shared_examples_for "fill_in" do end it "should fill in a field with a custom type" do + pending "selenium doesn't seem to find custom fields" if @session.mode == :selenium @session.fill_in('Schmooo', :with => 'Schmooo is the game') @session.click_button('awesome') extract_results(@session)['schmooo'].should == 'Schmooo is the game' From 1974fdbdc2ee3a9f9f666421b2d90cf5854bd963 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 22 Mar 2010 23:49:14 +0000 Subject: [PATCH 54/84] updated history --- History.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/History.txt b/History.txt index ceb169d1..67bf228e 100644 --- a/History.txt +++ b/History.txt @@ -1,3 +1,21 @@ +# Version 0.3.6 + +Release date: 2010-03-22 + +This is a maintainance release with minor bug fixes, should be +drop in compatible. + +### Added + +* It's now possible to load in external drivers + +### Fixed + +* has_content? ignores whitespace +* Trigger events when choosing radios and checking checkboxes under Selenium +* Make Capybara.app totally optional when running without server +* Changed fallback host so it matches the one set up by Rails' integration tests + # Version 0.3.5 Release date: 2010-02-26 From 1ff9ac2ab76f5e70e2b3d6a058388f2010e8e08f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 22 Mar 2010 23:50:07 +0000 Subject: [PATCH 55/84] tagged 0.3.6 --- lib/capybara.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara.rb b/lib/capybara.rb index acf3e57e..f5a827b9 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -2,7 +2,7 @@ require 'timeout' require 'nokogiri' module Capybara - VERSION = '0.3.5' + VERSION = '0.3.6' class CapybaraError < StandardError; end class DriverNotFoundError < CapybaraError; end From 736e5d4aa3f08fcc63e0f570b095eff89bb77aee Mon Sep 17 00:00:00 2001 From: lucasprim Date: Wed, 24 Mar 2010 14:21:33 -0300 Subject: [PATCH 56/84] MSWin Fix --- lib/capybara/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/server.rb b/lib/capybara/server.rb index c937c8a3..5f145426 100644 --- a/lib/capybara/server.rb +++ b/lib/capybara/server.rb @@ -93,7 +93,7 @@ private if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection) return res.body == @app.object_id.to_s end - rescue Errno::ECONNREFUSED + rescue Errno::ECONNREFUSED, Errno::EBADF return false end From 5661d67ae9458890ac458cb6bbb2ac45513fac2a Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 24 Mar 2010 23:28:16 +0000 Subject: [PATCH 57/84] Lucas Prim added to contributors --- README.rdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rdoc b/README.rdoc index 62334b7a..187ad2b8 100644 --- a/README.rdoc +++ b/README.rdoc @@ -383,6 +383,7 @@ The following people have dedicated their time and effort to Capybara: * Darrin Holst * Steven Parkes * Davide Marquês +* Lucas Prim == License: From 58d4d0caf7d4fad5519033e9bfd0786146750a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 9 Apr 2010 14:01:17 +0200 Subject: [PATCH 58/84] Rack-test should use data-method if available in links. --- lib/capybara/driver/rack_test_driver.rb | 9 +++++++-- spec/session/rack_test_session_spec.rb | 8 ++++++++ spec/test_app.rb | 4 ++++ spec/views/with_html.erb | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 2c44e156..03e48d2b 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -74,7 +74,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base def click if tag_name == 'a' - driver.visit(self[:href].to_s) + method = self["data-method"] || :get + driver.process(method, self[:href].to_s) elsif (tag_name == 'input' or tag_name == 'button') and %w(submit image).include?(type) Form.new(driver, form).submit(self) end @@ -186,8 +187,12 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end def visit(path, attributes = {}) + process(:get, path, attributes) + end + + def process(method, path, attributes = {}) return if path.gsub(/^#{current_path}/, '') =~ /^#/ - get(path, attributes, env) + send(method, path, attributes, env) follow_redirects! end diff --git a/spec/session/rack_test_session_spec.rb b/spec/session/rack_test_session_spec.rb index 43395278..aca5533a 100644 --- a/spec/session/rack_test_session_spec.rb +++ b/spec/session/rack_test_session_spec.rb @@ -18,6 +18,14 @@ describe Capybara::Session do end end + describe '#click_link' do + it "should use data-method if available" do + @session.visit "/with_html" + @session.click_link "A link with data-method" + @session.body.should == 'The requested object was deleted' + end + end + it_should_behave_like "session" it_should_behave_like "session without javascript support" it_should_behave_like "session with headers support" diff --git a/spec/test_app.rb b/spec/test_app.rb index d88ee555..95e44a86 100644 --- a/spec/test_app.rb +++ b/spec/test_app.rb @@ -42,6 +42,10 @@ class TestApp < Sinatra::Base redirect '/redirect_again' end + delete "/delete" do + "The requested object was deleted" + end + get '/redirect_back' do redirect back end diff --git a/spec/views/with_html.erb b/spec/views/with_html.erb index 3ab2dd73..3b9f20da 100644 --- a/spec/views/with_html.erb +++ b/spec/views/with_html.erb @@ -23,6 +23,7 @@ BackToMyself A link came first A link + A link with data-method No Href Blank Href Blank Anchor From 0144e04ae1e9a751b25a41157f39c7987bc2c3c5 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 14:24:51 +0200 Subject: [PATCH 59/84] =?UTF-8?q?added=20Jos=C3=A9=20Valim=20to=20contribu?= =?UTF-8?q?tors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.rdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rdoc b/README.rdoc index 187ad2b8..501edb7e 100644 --- a/README.rdoc +++ b/README.rdoc @@ -384,6 +384,7 @@ The following people have dedicated their time and effort to Capybara: * Steven Parkes * Davide Marquês * Lucas Prim +* José Valim == License: From 360088a3692b73725102ae26dab4cf9852340fa6 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 15:17:47 +0200 Subject: [PATCH 60/84] don't suggest including Capybara in the global object, closes #63 --- README.rdoc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.rdoc b/README.rdoc index 501edb7e..48195ecb 100644 --- a/README.rdoc +++ b/README.rdoc @@ -276,26 +276,27 @@ examples. Just load the DSL and include it anywhere: require 'capybara' require 'capybara/dsl' - include Capybara Capybara.default_driver = :culerity - within("//form[@id='session']") do - fill_in 'Login', :with => 'user@example.com' - fill_in 'Password', :with => 'password' + module MyModule + include Capybara + + def login! + within("//form[@id='session']") do + fill_in 'Login', :with => 'user@example.com' + fill_in 'Password', :with => 'password' + end + click_link 'Sign in' + end end - click_link 'Sign in' == Calling remote servers Normally Capybara expects to be testing an in-process Rack application, but you can also use it to talk to a web server running anywhere on the internets, by setting app_host: - require 'capybara' - require 'capybara/dsl' - - include Capybara Capybara.current_driver = :selenium Capybara.app_host = 'http://www.google.com' - + ... visit('/') Note that rack-test does not support running against a remote server. With drivers that support it, you can also visit any URL directly: From 14e08240ca9f3c6cc79fd0b818e68e4a9144686c Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 15:28:05 +0200 Subject: [PATCH 61/84] changed outdated API in README, closes #62 --- README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index 48195ecb..307e51ca 100644 --- a/README.rdoc +++ b/README.rdoc @@ -217,7 +217,7 @@ You can also find specific elements, in order to manipulate them: find_button('Send').click find('//table/tr').click - wait_for("//*[@id='overlay'").find("//h1").click + locate("//*[@id='overlay'").find("//h1").click all('a').each { |a| a[:href] } === Scripting From c2c8d68f58d7cdd12a0717e970b9e88aaf7b3f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 9 Apr 2010 15:48:10 +0200 Subject: [PATCH 62/84] Add information about changing Selenium browser to chrome or ie. --- README.rdoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rdoc b/README.rdoc index 187ad2b8..0a9cd5cd 100644 --- a/README.rdoc +++ b/README.rdoc @@ -101,6 +101,11 @@ At the moment, Capybara supports Webdriver, also called Selenium 2.0, *not* Selenium RC. Provided Firefox is installed, everything is set up for you, and you should be able to start using Selenium right away. +If desired, you can change Selenium browser to :chrome or :ie: + + require "selenium-webdriver" + Selenium::WebDriver.for :chrome + == Celerity Celerity only runs on JRuby, so you'll need to install the celerity gem under From cf1aa4d0739cd9e0b5f0a982bf40e26e46d1bb10 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 16:41:35 +0200 Subject: [PATCH 63/84] Moved shared specs into lib directory This way, implementations of other drivers can use the specs to verify that they are working correctly. --- .../capybara/spec/driver.rb | 6 +++++- .../capybara/spec}/fixtures/capybara.jpg | Bin .../capybara/spec}/fixtures/test_file.txt | 0 .../capybara/spec}/public/jquery-ui.js | 0 {spec => lib/capybara/spec}/public/jquery.js | 0 {spec => lib/capybara/spec}/public/test.js | 0 .../capybara/spec/session.rb | 6 +++++- .../capybara/spec/session}/all_spec.rb | 0 .../spec/session}/attach_file_spec.rb | 0 .../capybara/spec/session}/check_spec.rb | 0 .../capybara/spec/session}/choose_spec.rb | 0 .../spec/session}/click_button_spec.rb | 0 .../capybara/spec/session}/click_link_spec.rb | 0 .../capybara/spec/session}/click_spec.rb | 0 .../spec/session}/current_url_spec.rb | 0 .../capybara/spec/session}/fill_in_spec.rb | 0 .../spec/session}/find_button_spec.rb | 0 .../capybara/spec/session}/find_by_id_spec.rb | 0 .../capybara/spec/session}/find_field_spec.rb | 0 .../capybara/spec/session}/find_link_spec.rb | 0 .../capybara/spec/session}/find_spec.rb | 0 .../capybara/spec/session}/has_button_spec.rb | 0 .../spec/session}/has_content_spec.rb | 0 .../capybara/spec/session}/has_css_spec.rb | 0 .../capybara/spec/session}/has_field_spec.rb | 0 .../capybara/spec/session}/has_link_spec.rb | 0 .../capybara/spec/session}/has_select_spec.rb | 0 .../capybara/spec/session}/has_table_spec.rb | 0 .../capybara/spec/session}/has_xpath_spec.rb | 0 lib/capybara/spec/session/headers.rb | 19 ++++++++++++++++++ .../capybara/spec/session/javascript.rb | 15 ++++++++++---- .../capybara/spec/session}/locate_spec.rb | 0 .../capybara/spec/session}/select_spec.rb | 0 .../capybara/spec/session}/uncheck_spec.rb | 0 .../capybara/spec/session}/unselect_spec.rb | 0 .../capybara/spec/session}/within_spec.rb | 0 {spec => lib/capybara/spec}/test_app.rb | 0 {spec => lib/capybara/spec}/views/buttons.erb | 0 .../capybara/spec}/views/fieldsets.erb | 0 {spec => lib/capybara/spec}/views/form.erb | 0 .../capybara/spec}/views/postback.erb | 0 {spec => lib/capybara/spec}/views/tables.erb | 0 .../capybara/spec}/views/with_html.erb | 0 {spec => lib/capybara/spec}/views/with_js.erb | 0 .../capybara/spec}/views/with_scope.erb | 0 .../capybara/spec}/views/with_simple_html.erb | 0 spec/session_with_headers_support_spec.rb | 13 ------------ spec/session_without_headers_support_spec.rb | 15 -------------- ...session_without_javascript_support_spec.rb | 15 -------------- spec/spec_helper.rb | 12 ++--------- 50 files changed, 42 insertions(+), 59 deletions(-) rename spec/drivers_spec.rb => lib/capybara/spec/driver.rb (97%) rename {spec => lib/capybara/spec}/fixtures/capybara.jpg (100%) rename {spec => lib/capybara/spec}/fixtures/test_file.txt (100%) rename {spec => lib/capybara/spec}/public/jquery-ui.js (100%) rename {spec => lib/capybara/spec}/public/jquery.js (100%) rename {spec => lib/capybara/spec}/public/test.js (100%) rename spec/session_spec.rb => lib/capybara/spec/session.rb (95%) rename {spec/dsl => lib/capybara/spec/session}/all_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/attach_file_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/check_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/choose_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/click_button_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/click_link_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/click_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/current_url_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/fill_in_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/find_button_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/find_by_id_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/find_field_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/find_link_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/find_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_button_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_content_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_css_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_field_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_link_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_select_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_table_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/has_xpath_spec.rb (100%) create mode 100644 lib/capybara/spec/session/headers.rb rename spec/session_with_javascript_support_spec.rb => lib/capybara/spec/session/javascript.rb (94%) rename {spec/dsl => lib/capybara/spec/session}/locate_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/select_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/uncheck_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/unselect_spec.rb (100%) rename {spec/dsl => lib/capybara/spec/session}/within_spec.rb (100%) rename {spec => lib/capybara/spec}/test_app.rb (100%) rename {spec => lib/capybara/spec}/views/buttons.erb (100%) rename {spec => lib/capybara/spec}/views/fieldsets.erb (100%) rename {spec => lib/capybara/spec}/views/form.erb (100%) rename {spec => lib/capybara/spec}/views/postback.erb (100%) rename {spec => lib/capybara/spec}/views/tables.erb (100%) rename {spec => lib/capybara/spec}/views/with_html.erb (100%) rename {spec => lib/capybara/spec}/views/with_js.erb (100%) rename {spec => lib/capybara/spec}/views/with_scope.erb (100%) rename {spec => lib/capybara/spec}/views/with_simple_html.erb (100%) delete mode 100644 spec/session_with_headers_support_spec.rb delete mode 100644 spec/session_without_headers_support_spec.rb delete mode 100644 spec/session_without_javascript_support_spec.rb diff --git a/spec/drivers_spec.rb b/lib/capybara/spec/driver.rb similarity index 97% rename from spec/drivers_spec.rb rename to lib/capybara/spec/driver.rb index c1614686..4769e7bc 100644 --- a/spec/drivers_spec.rb +++ b/lib/capybara/spec/driver.rb @@ -1,4 +1,8 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) +require 'capybara/spec/test_app' + +Dir[File.dirname(__FILE__)+'/driver/*'].each { |group| + require group +} shared_examples_for 'driver' do diff --git a/spec/fixtures/capybara.jpg b/lib/capybara/spec/fixtures/capybara.jpg similarity index 100% rename from spec/fixtures/capybara.jpg rename to lib/capybara/spec/fixtures/capybara.jpg diff --git a/spec/fixtures/test_file.txt b/lib/capybara/spec/fixtures/test_file.txt similarity index 100% rename from spec/fixtures/test_file.txt rename to lib/capybara/spec/fixtures/test_file.txt diff --git a/spec/public/jquery-ui.js b/lib/capybara/spec/public/jquery-ui.js similarity index 100% rename from spec/public/jquery-ui.js rename to lib/capybara/spec/public/jquery-ui.js diff --git a/spec/public/jquery.js b/lib/capybara/spec/public/jquery.js similarity index 100% rename from spec/public/jquery.js rename to lib/capybara/spec/public/jquery.js diff --git a/spec/public/test.js b/lib/capybara/spec/public/test.js similarity index 100% rename from spec/public/test.js rename to lib/capybara/spec/public/test.js diff --git a/spec/session_spec.rb b/lib/capybara/spec/session.rb similarity index 95% rename from spec/session_spec.rb rename to lib/capybara/spec/session.rb index ad2426af..f03c1d80 100644 --- a/spec/session_spec.rb +++ b/lib/capybara/spec/session.rb @@ -1,6 +1,10 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) +require 'capybara/spec/test_app' require 'nokogiri' +Dir[File.dirname(__FILE__)+'/session/*'].each { |group| + require group +} + shared_examples_for "session" do def extract_results(session) YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text diff --git a/spec/dsl/all_spec.rb b/lib/capybara/spec/session/all_spec.rb similarity index 100% rename from spec/dsl/all_spec.rb rename to lib/capybara/spec/session/all_spec.rb diff --git a/spec/dsl/attach_file_spec.rb b/lib/capybara/spec/session/attach_file_spec.rb similarity index 100% rename from spec/dsl/attach_file_spec.rb rename to lib/capybara/spec/session/attach_file_spec.rb diff --git a/spec/dsl/check_spec.rb b/lib/capybara/spec/session/check_spec.rb similarity index 100% rename from spec/dsl/check_spec.rb rename to lib/capybara/spec/session/check_spec.rb diff --git a/spec/dsl/choose_spec.rb b/lib/capybara/spec/session/choose_spec.rb similarity index 100% rename from spec/dsl/choose_spec.rb rename to lib/capybara/spec/session/choose_spec.rb diff --git a/spec/dsl/click_button_spec.rb b/lib/capybara/spec/session/click_button_spec.rb similarity index 100% rename from spec/dsl/click_button_spec.rb rename to lib/capybara/spec/session/click_button_spec.rb diff --git a/spec/dsl/click_link_spec.rb b/lib/capybara/spec/session/click_link_spec.rb similarity index 100% rename from spec/dsl/click_link_spec.rb rename to lib/capybara/spec/session/click_link_spec.rb diff --git a/spec/dsl/click_spec.rb b/lib/capybara/spec/session/click_spec.rb similarity index 100% rename from spec/dsl/click_spec.rb rename to lib/capybara/spec/session/click_spec.rb diff --git a/spec/dsl/current_url_spec.rb b/lib/capybara/spec/session/current_url_spec.rb similarity index 100% rename from spec/dsl/current_url_spec.rb rename to lib/capybara/spec/session/current_url_spec.rb diff --git a/spec/dsl/fill_in_spec.rb b/lib/capybara/spec/session/fill_in_spec.rb similarity index 100% rename from spec/dsl/fill_in_spec.rb rename to lib/capybara/spec/session/fill_in_spec.rb diff --git a/spec/dsl/find_button_spec.rb b/lib/capybara/spec/session/find_button_spec.rb similarity index 100% rename from spec/dsl/find_button_spec.rb rename to lib/capybara/spec/session/find_button_spec.rb diff --git a/spec/dsl/find_by_id_spec.rb b/lib/capybara/spec/session/find_by_id_spec.rb similarity index 100% rename from spec/dsl/find_by_id_spec.rb rename to lib/capybara/spec/session/find_by_id_spec.rb diff --git a/spec/dsl/find_field_spec.rb b/lib/capybara/spec/session/find_field_spec.rb similarity index 100% rename from spec/dsl/find_field_spec.rb rename to lib/capybara/spec/session/find_field_spec.rb diff --git a/spec/dsl/find_link_spec.rb b/lib/capybara/spec/session/find_link_spec.rb similarity index 100% rename from spec/dsl/find_link_spec.rb rename to lib/capybara/spec/session/find_link_spec.rb diff --git a/spec/dsl/find_spec.rb b/lib/capybara/spec/session/find_spec.rb similarity index 100% rename from spec/dsl/find_spec.rb rename to lib/capybara/spec/session/find_spec.rb diff --git a/spec/dsl/has_button_spec.rb b/lib/capybara/spec/session/has_button_spec.rb similarity index 100% rename from spec/dsl/has_button_spec.rb rename to lib/capybara/spec/session/has_button_spec.rb diff --git a/spec/dsl/has_content_spec.rb b/lib/capybara/spec/session/has_content_spec.rb similarity index 100% rename from spec/dsl/has_content_spec.rb rename to lib/capybara/spec/session/has_content_spec.rb diff --git a/spec/dsl/has_css_spec.rb b/lib/capybara/spec/session/has_css_spec.rb similarity index 100% rename from spec/dsl/has_css_spec.rb rename to lib/capybara/spec/session/has_css_spec.rb diff --git a/spec/dsl/has_field_spec.rb b/lib/capybara/spec/session/has_field_spec.rb similarity index 100% rename from spec/dsl/has_field_spec.rb rename to lib/capybara/spec/session/has_field_spec.rb diff --git a/spec/dsl/has_link_spec.rb b/lib/capybara/spec/session/has_link_spec.rb similarity index 100% rename from spec/dsl/has_link_spec.rb rename to lib/capybara/spec/session/has_link_spec.rb diff --git a/spec/dsl/has_select_spec.rb b/lib/capybara/spec/session/has_select_spec.rb similarity index 100% rename from spec/dsl/has_select_spec.rb rename to lib/capybara/spec/session/has_select_spec.rb diff --git a/spec/dsl/has_table_spec.rb b/lib/capybara/spec/session/has_table_spec.rb similarity index 100% rename from spec/dsl/has_table_spec.rb rename to lib/capybara/spec/session/has_table_spec.rb diff --git a/spec/dsl/has_xpath_spec.rb b/lib/capybara/spec/session/has_xpath_spec.rb similarity index 100% rename from spec/dsl/has_xpath_spec.rb rename to lib/capybara/spec/session/has_xpath_spec.rb diff --git a/lib/capybara/spec/session/headers.rb b/lib/capybara/spec/session/headers.rb new file mode 100644 index 00000000..434a09cb --- /dev/null +++ b/lib/capybara/spec/session/headers.rb @@ -0,0 +1,19 @@ +shared_examples_for "session with headers support" do + describe '#response_headers' do + it "should return response headers" do + @session.visit('/with_simple_html') + @session.response_headers['Content-Type'].should == 'text/html' + end + end +end + +shared_examples_for "session without headers support" do + describe "#response_headers" do + before{ @session.visit('/with_simple_html') } + it "should raise an error" do + running { + @session.response_headers + }.should raise_error(Capybara::NotSupportedByDriverError) + end + end +end diff --git a/spec/session_with_javascript_support_spec.rb b/lib/capybara/spec/session/javascript.rb similarity index 94% rename from spec/session_with_javascript_support_spec.rb rename to lib/capybara/spec/session/javascript.rb index 74b9bd19..5d629ebf 100644 --- a/spec/session_with_javascript_support_spec.rb +++ b/lib/capybara/spec/session/javascript.rb @@ -1,7 +1,3 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) - -require 'nokogiri' - shared_examples_for "session with javascript support" do describe 'all JS specs' do before do @@ -195,3 +191,14 @@ shared_examples_for "session with javascript support" do end end + +shared_examples_for "session without javascript support" do + describe "#evaluate_script" do + before{ @session.visit('/with_simple_html') } + it "should raise an error" do + running { + @session.evaluate_script('3 + 3') + }.should raise_error(Capybara::NotSupportedByDriverError) + end + end +end diff --git a/spec/dsl/locate_spec.rb b/lib/capybara/spec/session/locate_spec.rb similarity index 100% rename from spec/dsl/locate_spec.rb rename to lib/capybara/spec/session/locate_spec.rb diff --git a/spec/dsl/select_spec.rb b/lib/capybara/spec/session/select_spec.rb similarity index 100% rename from spec/dsl/select_spec.rb rename to lib/capybara/spec/session/select_spec.rb diff --git a/spec/dsl/uncheck_spec.rb b/lib/capybara/spec/session/uncheck_spec.rb similarity index 100% rename from spec/dsl/uncheck_spec.rb rename to lib/capybara/spec/session/uncheck_spec.rb diff --git a/spec/dsl/unselect_spec.rb b/lib/capybara/spec/session/unselect_spec.rb similarity index 100% rename from spec/dsl/unselect_spec.rb rename to lib/capybara/spec/session/unselect_spec.rb diff --git a/spec/dsl/within_spec.rb b/lib/capybara/spec/session/within_spec.rb similarity index 100% rename from spec/dsl/within_spec.rb rename to lib/capybara/spec/session/within_spec.rb diff --git a/spec/test_app.rb b/lib/capybara/spec/test_app.rb similarity index 100% rename from spec/test_app.rb rename to lib/capybara/spec/test_app.rb diff --git a/spec/views/buttons.erb b/lib/capybara/spec/views/buttons.erb similarity index 100% rename from spec/views/buttons.erb rename to lib/capybara/spec/views/buttons.erb diff --git a/spec/views/fieldsets.erb b/lib/capybara/spec/views/fieldsets.erb similarity index 100% rename from spec/views/fieldsets.erb rename to lib/capybara/spec/views/fieldsets.erb diff --git a/spec/views/form.erb b/lib/capybara/spec/views/form.erb similarity index 100% rename from spec/views/form.erb rename to lib/capybara/spec/views/form.erb diff --git a/spec/views/postback.erb b/lib/capybara/spec/views/postback.erb similarity index 100% rename from spec/views/postback.erb rename to lib/capybara/spec/views/postback.erb diff --git a/spec/views/tables.erb b/lib/capybara/spec/views/tables.erb similarity index 100% rename from spec/views/tables.erb rename to lib/capybara/spec/views/tables.erb diff --git a/spec/views/with_html.erb b/lib/capybara/spec/views/with_html.erb similarity index 100% rename from spec/views/with_html.erb rename to lib/capybara/spec/views/with_html.erb diff --git a/spec/views/with_js.erb b/lib/capybara/spec/views/with_js.erb similarity index 100% rename from spec/views/with_js.erb rename to lib/capybara/spec/views/with_js.erb diff --git a/spec/views/with_scope.erb b/lib/capybara/spec/views/with_scope.erb similarity index 100% rename from spec/views/with_scope.erb rename to lib/capybara/spec/views/with_scope.erb diff --git a/spec/views/with_simple_html.erb b/lib/capybara/spec/views/with_simple_html.erb similarity index 100% rename from spec/views/with_simple_html.erb rename to lib/capybara/spec/views/with_simple_html.erb diff --git a/spec/session_with_headers_support_spec.rb b/spec/session_with_headers_support_spec.rb deleted file mode 100644 index aae40b4c..00000000 --- a/spec/session_with_headers_support_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) - - -shared_examples_for "session with headers support" do - - describe '#response_headers' do - it "should return response headers" do - @session.visit('/with_simple_html') - @session.response_headers['Content-Type'].should == 'text/html' - end - end - -end diff --git a/spec/session_without_headers_support_spec.rb b/spec/session_without_headers_support_spec.rb deleted file mode 100644 index 13ea6bdc..00000000 --- a/spec/session_without_headers_support_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) - -require 'nokogiri' - -shared_examples_for "session without headers support" do - describe "#evaluate_script" do - before{ @session.visit('/with_simple_html') } - it "should raise an error" do - running { - @session.response_headers - }.should raise_error(Capybara::NotSupportedByDriverError) - end - end -end - \ No newline at end of file diff --git a/spec/session_without_javascript_support_spec.rb b/spec/session_without_javascript_support_spec.rb deleted file mode 100644 index af54d775..00000000 --- a/spec/session_without_javascript_support_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.expand_path('spec_helper', File.dirname(__FILE__)) - -require 'nokogiri' - -shared_examples_for "session without javascript support" do - describe "#evaluate_script" do - before{ @session.visit('/with_js') } - it "should raise an error" do - running { - @session.evaluate_script("1+5") - }.should raise_error(Capybara::NotSupportedByDriverError) - end - end - -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0f1ff250..d7745dd4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -5,16 +5,8 @@ require 'rubygems' require 'spec' require 'spec/autorun' require 'capybara' -require 'test_app' -require 'drivers_spec' -require 'session_spec' -Dir[File.dirname(__FILE__)+'/dsl/*'].each { |group| - require group -} -require 'session_with_javascript_support_spec' -require 'session_without_javascript_support_spec' -require 'session_with_headers_support_spec' -require 'session_without_headers_support_spec' +require 'capybara/spec/driver' +require 'capybara/spec/session' alias :running :lambda From 975b18c14099277477b1851f2280e432be8062ae Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 17:08:06 +0200 Subject: [PATCH 64/84] No more Hoe! Gemspec managed by hand from now on! --- Manifest.txt | 87 ----------------------------------------- Rakefile | 30 ++------------ capybara.gemspec | 73 +++++++++++----------------------- lib/capybara.rb | 3 +- lib/capybara/version.rb | 3 ++ script/console | 10 ----- script/destroy | 14 ------- script/generate | 14 ------- 8 files changed, 31 insertions(+), 203 deletions(-) delete mode 100644 Manifest.txt create mode 100644 lib/capybara/version.rb delete mode 100755 script/console delete mode 100755 script/destroy delete mode 100755 script/generate diff --git a/Manifest.txt b/Manifest.txt deleted file mode 100644 index 2afc4f98..00000000 --- a/Manifest.txt +++ /dev/null @@ -1,87 +0,0 @@ -History.txt -Manifest.txt -README.rdoc -Rakefile -config.ru -lib/capybara.rb -lib/capybara/cucumber.rb -lib/capybara/driver/base.rb -lib/capybara/driver/celerity_driver.rb -lib/capybara/driver/culerity_driver.rb -lib/capybara/driver/rack_test_driver.rb -lib/capybara/driver/selenium_driver.rb -lib/capybara/dsl.rb -lib/capybara/node.rb -lib/capybara/rails.rb -lib/capybara/save_and_open_page.rb -lib/capybara/searchable.rb -lib/capybara/server.rb -lib/capybara/session.rb -lib/capybara/wait_until.rb -lib/capybara/xpath.rb -script/console -script/destroy -script/generate -spec/capybara_spec.rb -spec/driver/celerity_driver_spec.rb -spec/driver/culerity_driver_spec.rb -spec/driver/rack_test_driver_spec.rb -spec/driver/remote_culerity_driver_spec.rb -spec/driver/remote_selenium_driver_spec.rb -spec/driver/selenium_driver_spec.rb -spec/drivers_spec.rb -spec/dsl/all_spec.rb -spec/dsl/attach_file_spec.rb -spec/dsl/check_spec.rb -spec/dsl/choose_spec.rb -spec/dsl/click_button_spec.rb -spec/dsl/click_link_spec.rb -spec/dsl/click_spec.rb -spec/dsl/current_url_spec.rb -spec/dsl/fill_in_spec.rb -spec/dsl/find_button_spec.rb -spec/dsl/find_by_id_spec.rb -spec/dsl/find_field_spec.rb -spec/dsl/find_link_spec.rb -spec/dsl/find_spec.rb -spec/dsl/has_button_spec.rb -spec/dsl/has_content_spec.rb -spec/dsl/has_css_spec.rb -spec/dsl/has_field_spec.rb -spec/dsl/has_link_spec.rb -spec/dsl/has_xpath_spec.rb -spec/dsl/locate_spec.rb -spec/dsl/select_spec.rb -spec/dsl/uncheck_spec.rb -spec/dsl/within_spec.rb -spec/dsl_spec.rb -spec/fixtures/capybara.jpg -spec/fixtures/test_file.txt -spec/public/jquery-ui.js -spec/public/jquery.js -spec/public/test.js -spec/save_and_open_page_spec.rb -spec/searchable_spec.rb -spec/server_spec.rb -spec/session/celerity_session_spec.rb -spec/session/culerity_session_spec.rb -spec/session/rack_test_session_spec.rb -spec/session/selenium_session_spec.rb -spec/session_spec.rb -spec/session_with_headers_support_spec.rb -spec/session_with_javascript_support_spec.rb -spec/session_without_headers_support_spec.rb -spec/session_without_javascript_support_spec.rb -spec/spec_helper.rb -spec/test_app.rb -spec/views/buttons.erb -spec/views/fieldsets.erb -spec/views/form.erb -spec/views/postback.erb -spec/views/tables.erb -spec/views/with_html.erb -spec/views/with_js.erb -spec/views/with_scope.erb -spec/views/with_simple_html.erb -spec/wait_until_spec.rb -spec/xpath_spec.rb diff --git a/Rakefile b/Rakefile index 8635c618..6a82ddd4 100644 --- a/Rakefile +++ b/Rakefile @@ -1,29 +1,7 @@ require 'rubygems' +require 'spec/rake/spectask' -gem 'hoe', '>= 2.1.0' -require 'hoe' - -Hoe.plugin :newgem - -# Generate all the Rake tasks -# Run 'rake -T' to see list of generated tasks (from gem root directory) -Hoe.spec 'capybara' do - developer 'Jonas Nicklas', 'jonas.nicklas@gmail.com' - - self.readme_file = 'README.rdoc' - self.extra_rdoc_files = Dir['*.rdoc'] - - self.extra_deps = [ - ['nokogiri', '>= 1.3.3'], - ['mime-types', '>= 1.16'], - ['culerity', '>= 0.2.4'], - ['selenium-webdriver', '>= 0.0.3'], - ['rack', '>= 1.0.0'], - ['rack-test', '>= 0.5.2'], - ] - - self.extra_dev_deps = [ - ['sinatra', '>= 0.9.4'], - ['rspec', '>= 1.2.9'] - ] +desc "Run all examples" +Spec::Rake::SpecTask.new('spec') do |t| + t.spec_files = FileList['spec/**/*.rb'] end diff --git a/capybara.gemspec b/capybara.gemspec index 68c764b2..280b6c7e 100644 --- a/capybara.gemspec +++ b/capybara.gemspec @@ -1,61 +1,34 @@ # -*- encoding: utf-8 -*- +lib = File.expand_path('../lib/', __FILE__) +$:.unshift lib unless $:.include?(lib) + +require 'capybara/version' Gem::Specification.new do |s| - s.name = %q{capybara} - s.version = "0.3.5" + s.name = "capybara" + s.rubyforge_project = "capybara" + s.version = Capybara::VERSION - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Jonas Nicklas"] - s.date = %q{2010-03-18} - s.description = %q{Capybara aims to simplify the process of integration testing Rack applications, -such as Rails, Sinatra or Merb. It is inspired by and aims to replace Webrat as -a DSL for interacting with a webapplication. It is agnostic about the driver -running your tests and currently comes bundled with rack-test, Culerity, -Celerity and Selenium support built in.} s.email = ["jonas.nicklas@gmail.com"] - s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"] - s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "config.ru", "lib/capybara.rb", "lib/capybara/cucumber.rb", "lib/capybara/driver/base.rb", "lib/capybara/driver/celerity_driver.rb", "lib/capybara/driver/culerity_driver.rb", "lib/capybara/driver/rack_test_driver.rb", "lib/capybara/driver/selenium_driver.rb", "lib/capybara/dsl.rb", "lib/capybara/node.rb", "lib/capybara/rails.rb", "lib/capybara/save_and_open_page.rb", "lib/capybara/searchable.rb", "lib/capybara/server.rb", "lib/capybara/session.rb", "lib/capybara/wait_until.rb", "lib/capybara/xpath.rb", "script/console", "script/destroy", "script/generate", "spec/capybara_spec.rb", "spec/driver/celerity_driver_spec.rb", "spec/driver/culerity_driver_spec.rb", "spec/driver/rack_test_driver_spec.rb", "spec/driver/remote_culerity_driver_spec.rb", "spec/driver/remote_selenium_driver_spec.rb", "spec/driver/selenium_driver_spec.rb", "spec/drivers_spec.rb", "spec/dsl/all_spec.rb", "spec/dsl/attach_file_spec.rb", "spec/dsl/check_spec.rb", "spec/dsl/choose_spec.rb", "spec/dsl/click_button_spec.rb", "spec/dsl/click_link_spec.rb", "spec/dsl/click_spec.rb", "spec/dsl/current_url_spec.rb", "spec/dsl/fill_in_spec.rb", "spec/dsl/find_button_spec.rb", "spec/dsl/find_by_id_spec.rb", "spec/dsl/find_field_spec.rb", "spec/dsl/find_link_spec.rb", "spec/dsl/find_spec.rb", "spec/dsl/has_button_spec.rb", "spec/dsl/has_content_spec.rb", "spec/dsl/has_css_spec.rb", "spec/dsl/has_field_spec.rb", "spec/dsl/has_link_spec.rb", "spec/dsl/has_xpath_spec.rb", "spec/dsl/locate_spec.rb", "spec/dsl/select_spec.rb", "spec/dsl/uncheck_spec.rb", "spec/dsl/within_spec.rb", "spec/dsl_spec.rb", "spec/fixtures/capybara.jpg", "spec/fixtures/test_file.txt", "spec/public/jquery-ui.js", "spec/public/jquery.js", "spec/public/test.js", "spec/save_and_open_page_spec.rb", "spec/searchable_spec.rb", "spec/server_spec.rb", "spec/session/celerity_session_spec.rb", "spec/session/culerity_session_spec.rb", "spec/session/rack_test_session_spec.rb", "spec/session/selenium_session_spec.rb", "spec/session_spec.rb", "spec/session_with_headers_support_spec.rb", "spec/session_with_javascript_support_spec.rb", "spec/session_without_headers_support_spec.rb", "spec/session_without_javascript_support_spec.rb", "spec/spec_helper.rb", "spec/test_app.rb", "spec/views/buttons.erb", "spec/views/fieldsets.erb", "spec/views/form.erb", "spec/views/postback.erb", "spec/views/tables.erb", "spec/views/with_html.erb", "spec/views/with_js.erb", "spec/views/with_scope.erb", "spec/views/with_simple_html.erb", "spec/wait_until_spec.rb", "spec/xpath_spec.rb"] - s.homepage = %q{http://github.com/jnicklas/capybara} + s.description = "Capybara is an integration testing tool for rack based web applications. It simulates how a user would interact with a website" + + s.files = Dir.glob("{lib,spec}/**/*") + %w(README.rdoc History.txt) + s.extra_rdoc_files = ["README.rdoc"] + + s.homepage = "http://github.com/jnicklas/capybara" s.rdoc_options = ["--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubyforge_project = %q{capybara} - s.rubygems_version = %q{1.3.6} - s.summary = %q{Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb} + s.rubygems_version = "1.3.6" + s.summary = "Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb" - if s.respond_to? :specification_version then - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION - s.specification_version = 3 + s.add_runtime_dependency("nokogiri", [">= 1.3.3"]) + s.add_runtime_dependency("mime-types", [">= 1.16"]) + s.add_runtime_dependency("culerity", [">= 0.2.4"]) + s.add_runtime_dependency("selenium-webdriver", [">= 0.0.3"]) + s.add_runtime_dependency("rack", [">= 1.0.0"]) + s.add_runtime_dependency("rack-test", [">= 0.5.2"]) - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 1.3.3"]) - s.add_runtime_dependency(%q, [">= 1.16"]) - s.add_runtime_dependency(%q, [">= 0.2.4"]) - s.add_runtime_dependency(%q, [">= 0.0.3"]) - s.add_runtime_dependency(%q, [">= 1.0.0"]) - s.add_runtime_dependency(%q, [">= 0.5.2"]) - s.add_development_dependency(%q, [">= 0.9.4"]) - s.add_development_dependency(%q, [">= 1.2.9"]) - s.add_development_dependency(%q, [">= 2.5.0"]) - else - s.add_dependency(%q, [">= 1.3.3"]) - s.add_dependency(%q, [">= 1.16"]) - s.add_dependency(%q, [">= 0.2.4"]) - s.add_dependency(%q, [">= 0.0.3"]) - s.add_dependency(%q, [">= 1.0.0"]) - s.add_dependency(%q, [">= 0.5.2"]) - s.add_dependency(%q, [">= 0.9.4"]) - s.add_dependency(%q, [">= 1.2.9"]) - s.add_dependency(%q, [">= 2.5.0"]) - end - else - s.add_dependency(%q, [">= 1.3.3"]) - s.add_dependency(%q, [">= 1.16"]) - s.add_dependency(%q, [">= 0.2.4"]) - s.add_dependency(%q, [">= 0.0.3"]) - s.add_dependency(%q, [">= 1.0.0"]) - s.add_dependency(%q, [">= 0.5.2"]) - s.add_dependency(%q, [">= 0.9.4"]) - s.add_dependency(%q, [">= 1.2.9"]) - s.add_dependency(%q, [">= 2.5.0"]) - end + s.add_development_dependency("sinatra", [">= 0.9.4"]) + s.add_development_dependency("rspec", [">= 1.2.9"]) end diff --git a/lib/capybara.rb b/lib/capybara.rb index f5a827b9..7de48fa9 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -2,8 +2,6 @@ require 'timeout' require 'nokogiri' module Capybara - VERSION = '0.3.6' - class CapybaraError < StandardError; end class DriverNotFoundError < CapybaraError; end class ElementNotFound < CapybaraError; end @@ -37,6 +35,7 @@ module Capybara autoload :Node, 'capybara/node' autoload :XPath, 'capybara/xpath' autoload :Searchable, 'capybara/searchable' + autoload :VERSION, 'capybara/version' module Driver autoload :Base, 'capybara/driver/base' diff --git a/lib/capybara/version.rb b/lib/capybara/version.rb new file mode 100644 index 00000000..c9c93504 --- /dev/null +++ b/lib/capybara/version.rb @@ -0,0 +1,3 @@ +module Capybara + VERSION = '0.3.6' +end diff --git a/script/console b/script/console deleted file mode 100755 index 2cc3bef5..00000000 --- a/script/console +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env ruby -# File: script/console -irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' - -libs = " -r irb/completion" -# Perhaps use a console_lib to store any extra methods I may want available in the cosole -# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}" -libs << " -r #{File.dirname(__FILE__) + '/../lib/capybara.rb'}" -puts "Loading capybara gem" -exec "#{irb} #{libs} --simple-prompt" \ No newline at end of file diff --git a/script/destroy b/script/destroy deleted file mode 100755 index e48464df..00000000 --- a/script/destroy +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) - -begin - require 'rubigen' -rescue LoadError - require 'rubygems' - require 'rubigen' -end -require 'rubigen/scripts/destroy' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] -RubiGen::Scripts::Destroy.new.run(ARGV) diff --git a/script/generate b/script/generate deleted file mode 100755 index c27f6559..00000000 --- a/script/generate +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) - -begin - require 'rubigen' -rescue LoadError - require 'rubygems' - require 'rubigen' -end -require 'rubigen/scripts/generate' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] -RubiGen::Scripts::Generate.new.run(ARGV) From 04f87b26723ca9b8424fb35f8e55f832510f8821 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 17:09:42 +0200 Subject: [PATCH 65/84] changed config.ru to point to new testapp location --- config.ru | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.ru b/config.ru index f76190e8..68ab7480 100644 --- a/config.ru +++ b/config.ru @@ -1,6 +1,6 @@ ## This is not needed for Thin > 1.0.0 ENV['RACK_ENV'] = "production" -require File.expand_path('spec/test_app', File.dirname(__FILE__)) +require File.expand_path('lib/capybara/spec/test_app', File.dirname(__FILE__)) -run TestApp \ No newline at end of file +run TestApp From 092c2a3288244239271bb2759b5dde24c05e9350 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 17:14:56 +0200 Subject: [PATCH 66/84] updated history --- History.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/History.txt b/History.txt index 67bf228e..f132e2ff 100644 --- a/History.txt +++ b/History.txt @@ -1,3 +1,22 @@ +# Versiob 0.3.7 + +Release date: 2010-04-09 + +This is a drop in compatible maintainance release. It's mostly +important for driver authors. + +### Added + +* RackTest scans for data-method which rails3 uses to change the request method + +### Fixed + +* Don't hang when starting server on Windoze + +### Changed + +* The driver and session specs are now located inside lib! Driver authors can simply require them. + # Version 0.3.6 Release date: 2010-03-22 From dbbb44a166b25ba7023801b525573cd4bf61066a Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 17:17:10 +0200 Subject: [PATCH 67/84] tagged 0.3.7 --- lib/capybara/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/version.rb b/lib/capybara/version.rb index c9c93504..09dcf777 100644 --- a/lib/capybara/version.rb +++ b/lib/capybara/version.rb @@ -1,3 +1,3 @@ module Capybara - VERSION = '0.3.6' + VERSION = '0.3.7' end From 32b3b6a796435815eb39e4c26bad0916752bf142 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Fri, 9 Apr 2010 17:24:14 +0200 Subject: [PATCH 68/84] added default task --- Rakefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Rakefile b/Rakefile index 6a82ddd4..89ba3f3b 100644 --- a/Rakefile +++ b/Rakefile @@ -5,3 +5,5 @@ desc "Run all examples" Spec::Rake::SpecTask.new('spec') do |t| t.spec_files = FileList['spec/**/*.rb'] end + +task :default => :spec From a550cc458a12080d054e22dd3f0b44d06a68935d Mon Sep 17 00:00:00 2001 From: Len Smith Date: Wed, 21 Apr 2010 17:55:33 -0400 Subject: [PATCH 69/84] raising an error if someone forgets to provide a hash to fill_in --- lib/capybara/session.rb | 1 + lib/capybara/spec/session/fill_in_spec.rb | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index eeacc069..77d47f7b 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -62,6 +62,7 @@ module Capybara def fill_in(locator, options={}) msg = "cannot fill in, no text field, text area or password field with id, name, or label '#{locator}' found" + raise "Must pass a hash containing 'with'" unless options.kind_of? Hash && !options.index(:with).nil? locate(:xpath, XPath.fillable_field(locator), msg).set(options[:with]) end diff --git a/lib/capybara/spec/session/fill_in_spec.rb b/lib/capybara/spec/session/fill_in_spec.rb index ddbe6dd3..b1974646 100644 --- a/lib/capybara/spec/session/fill_in_spec.rb +++ b/lib/capybara/spec/session/fill_in_spec.rb @@ -82,7 +82,11 @@ shared_examples_for "fill_in" do @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 } From 73800eb04ce83b762adb749ea0ae3f43b64a05fe Mon Sep 17 00:00:00 2001 From: Craig R Webster Date: Thu, 22 Apr 2010 15:17:31 +0100 Subject: [PATCH 70/84] Only uncheck or check a checkbox if it is not already in that state. Note that I can't test Culerity just now. --- lib/capybara/driver/rack_test_driver.rb | 4 ++-- lib/capybara/driver/selenium_driver.rb | 2 +- lib/capybara/spec/session/check_spec.rb | 28 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 03e48d2b..e72d5ce6 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -32,9 +32,9 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base driver.html.xpath("//input[@name='#{self[:name]}']").each { |node| node.remove_attribute("checked") } node['checked'] = 'checked' elsif tag_name == 'input' and type == 'checkbox' - if value + if value && !node['checked'] node['checked'] = 'checked' - else + elsif !value && node['checked'] node.remove_attribute('checked') end elsif tag_name == 'input' diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 5ce88ae3..b7eb7658 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -31,7 +31,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base elsif tag_name == 'input' and type == 'radio' node.click elsif tag_name == 'input' and type == 'checkbox' - node.click + node.click if node.attribute('checked') != value end end diff --git a/lib/capybara/spec/session/check_spec.rb b/lib/capybara/spec/session/check_spec.rb index bd182d5c..088f31be 100644 --- a/lib/capybara/spec/session/check_spec.rb +++ b/lib/capybara/spec/session/check_spec.rb @@ -17,6 +17,34 @@ module CheckSpec end end + describe "checking" do + it "should not change an already checked checkbox" do + @session.find(:xpath, "//input[@id='form_pets_dog']")['checked'].should be_true + @session.check('form_pets_dog') + @session.find(:xpath, "//input[@id='form_pets_dog']")['checked'].should be_true + end + + it "should check an unchecked checkbox" do + @session.find(:xpath, "//input[@id='form_pets_cat']")['checked'].should be_false + @session.check('form_pets_cat') + @session.find(:xpath, "//input[@id='form_pets_cat']")['checked'].should be_true + end + end + + describe "unchecking" do + it "should not change an already unchecked checkbox" do + @session.find(:xpath, "//input[@id='form_pets_cat']")['checked'].should be_false + @session.uncheck('form_pets_cat') + @session.find(:xpath, "//input[@id='form_pets_cat']")['checked'].should be_false + end + + it "should uncheck a checked checkbox" do + @session.find(:xpath, "//input[@id='form_pets_dog']")['checked'].should be_true + @session.uncheck('form_pets_dog') + @session.find(:xpath, "//input[@id='form_pets_dog']")['checked'].should be_false + end + end + it "should check a checkbox by id" do @session.check("form_pets_cat") @session.click_button('awesome') From cbb42a1da781ba057b01cdd6d9e2a4d1a7834cbf Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 26 Apr 2010 17:23:34 +0200 Subject: [PATCH 71/84] XPath escape value in select/unselect under rack-test --- lib/capybara/driver/rack_test_driver.rb | 10 +++++----- lib/capybara/spec/session/select_spec.rb | 6 ++++++ lib/capybara/spec/session/unselect_spec.rb | 6 ++++++ lib/capybara/spec/views/form.erb | 2 ++ lib/capybara/xpath.rb | 21 ++++++++++++--------- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 03e48d2b..1ca84f30 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -29,7 +29,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base def set(value) if tag_name == 'input' and type == 'radio' - driver.html.xpath("//input[@name='#{self[:name]}']").each { |node| node.remove_attribute("checked") } + driver.html.xpath("//input[@name=#{Capybara::XPath.escape(self[:name])}]").each { |node| node.remove_attribute("checked") } node['checked'] = 'checked' elsif tag_name == 'input' and type == 'checkbox' if value @@ -49,8 +49,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base node.xpath(".//option[@selected]").each { |node| node.remove_attribute("selected") } end - if option_node = node.xpath(".//option[text()='#{option}']").first || - node.xpath(".//option[contains(.,'#{option}')]").first + if option_node = node.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first || + node.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first option_node["selected"] = 'selected' else options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ') @@ -63,8 +63,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box." end - if option_node = node.xpath(".//option[text()='#{option}']").first || - node.xpath(".//option[contains(.,'#{option}')]").first + if option_node = node.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first || + node.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first option_node.remove_attribute('selected') else options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ') diff --git a/lib/capybara/spec/session/select_spec.rb b/lib/capybara/spec/session/select_spec.rb index dbebae5d..c17395be 100644 --- a/lib/capybara/spec/session/select_spec.rb +++ b/lib/capybara/spec/session/select_spec.rb @@ -31,6 +31,12 @@ shared_examples_for "select" do extract_results(@session)['title'].should == 'Mr' end + it "should escape quotes" do + @session.select("John's made-up language", :from => 'Locale') + @session.click_button('awesome') + extract_results(@session)['locale'].should == 'jo' + 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) diff --git a/lib/capybara/spec/session/unselect_spec.rb b/lib/capybara/spec/session/unselect_spec.rb index ad1246a4..4a53f275 100644 --- a/lib/capybara/spec/session/unselect_spec.rb +++ b/lib/capybara/spec/session/unselect_spec.rb @@ -25,6 +25,12 @@ shared_examples_for "unselect" do extract_results(@session)['underwear'].should include('Commando', 'Boxer Briefs') extract_results(@session)['underwear'].should_not include('Briefs') end + + it "should escape quotes" do + @session.unselect("Frenchman's Pantalons", :from => 'Underwear') + @session.click_button('awesome') + extract_results(@session)['underwear'].should_not include("Frenchman's Pantalons") + end end context "with single select" do diff --git a/lib/capybara/spec/views/form.erb b/lib/capybara/spec/views/form.erb index 4228d95a..06cf50d5 100644 --- a/lib/capybara/spec/views/form.erb +++ b/lib/capybara/spec/views/form.erb @@ -76,6 +76,7 @@ +

@@ -142,6 +143,7 @@ +

diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index aaf0a088..87e914f2 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -5,6 +5,17 @@ module Capybara class XPath class << self + def escape(string) + if string.include?("'") + string = string.split("'", -1).map do |substr| + "'#{substr}'" + end.join(%q{,"'",}) + "concat(#{string})" + else + "'#{string}'" + end + end + def wrap(path) if path.is_a?(self) path @@ -161,15 +172,7 @@ module Capybara # Sanitize a String for putting it into an xpath query def s(string) - if string.include?("'") - string = string.split("'", -1).map do |substr| - "'#{substr}'" - end.join(%q{,"'",}) - "concat(#{string})" - else - "'#{string}'" - end - + XPath.escape(string) end end From 8a7ecba3aa1d96cbb16b0440eb2adb2d5416b03f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 26 Apr 2010 23:43:18 +0200 Subject: [PATCH 72/84] Fix options with quotes under selenium --- lib/capybara/driver/selenium_driver.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 5ce88ae3..226a003e 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -36,7 +36,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def select(option) - option_node = node.find_element(:xpath, ".//option[text()='#{option}']") || node.find_element(:xpath, ".//option[contains(.,'#{option}')]") + option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") option_node.select rescue options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ') @@ -49,7 +49,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end begin - option_node = node.find_element(:xpath, ".//option[text()='#{option}']") || node.find_element(:xpath, ".//option[contains(.,'#{option}')]") + option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") option_node.clear rescue options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ') From 9401ecb264ce1e3b09e3f2e2ece1d2408dc3776a Mon Sep 17 00:00:00 2001 From: Jonathan Tron Date: Thu, 6 May 2010 18:22:48 +0200 Subject: [PATCH 73/84] :text option in Capybara::Searchable#all should be escaped if String --- lib/capybara/searchable.rb | 1 + spec/searchable_spec.rb | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/capybara/searchable.rb b/lib/capybara/searchable.rb index 02ca8157..23753766 100644 --- a/lib/capybara/searchable.rb +++ b/lib/capybara/searchable.rb @@ -33,6 +33,7 @@ module Capybara results = all_unfiltered(locator) if options[:text] + options[:text] = Regexp.escape(options[:text]) unless options[:text].kind_of?(Regexp) results = results.select { |n| n.text.match(options[:text]) } end diff --git a/spec/searchable_spec.rb b/spec/searchable_spec.rb index c9bce3de..2d437d71 100644 --- a/spec/searchable_spec.rb +++ b/spec/searchable_spec.rb @@ -26,8 +26,8 @@ module Capybara context "with :text filter" do before do - @node1 = stub(Node, :text => 'node one text') - @node2 = stub(Node, :text => 'node two text') + @node1 = stub(Node, :text => 'node one text (with parens)') + @node2 = stub(Node, :text => 'node two text [-]') @searchable.stub(:all_unfiltered).and_return([@node1, @node2]) end @@ -40,6 +40,11 @@ module Capybara @searchable.all('//x', :text => "node one").should == [@node1] @searchable.all('//x', :text => "node two").should == [@node2] end + + it "should allow Regexp reserved words in text" do + @searchable.all('//x', :text => "node one text (with parens)").should == [@node1] + @searchable.all('//x', :text => "node two text [-]").should == [@node2] + end end context "with :visible filter" do From 32c0c88e6edf3d1a91107934c60cbeeed1d86bf5 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sun, 9 May 2010 16:17:52 +0200 Subject: [PATCH 74/84] Removing the contributors list Maintaining it is getting to be a pain in the ass and impeding progress on the project. I still value everyone's contributions very highly. Sorry. --- README.rdoc | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/README.rdoc b/README.rdoc index 9d4e272c..a70291eb 100644 --- a/README.rdoc +++ b/README.rdoc @@ -362,36 +362,6 @@ moving from Webrat and used CSS a lot, or simply generally prefer CSS: instead. You can achieve this in Rails with link_to('foo', :anchor => '') -== Contributors: - -The following people have dedicated their time and effort to Capybara: - -* Jonas Nicklas -* Dennis Rogenius -* Rob Holland -* Wincent Colaiuta -* Andrea Fazzi -* Aslak Hellesøy -* Andrew Brown -* Lenny Marks -* Aaron Patterson -* Dan Dofter -* Thorbjørn Hermansen -* Louis T. -* Stephan Hagemann -* Graham Ashton -* Joseph Wilk -* Matt Wynne -* Piotr Sarnacki -* Pavel Gabriel -* Bodaniel Jeanes -* Carl Porth -* Darrin Holst -* Steven Parkes -* Davide Marquês -* Lucas Prim -* José Valim - == License: (The MIT License) From 5fd3744d9d0735540cb395edfc4ae7d09e32fb27 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sun, 9 May 2010 16:51:11 +0200 Subject: [PATCH 75/84] parens around method args, plz --- lib/capybara/session.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 3f5dceb6..58004e58 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -119,7 +119,7 @@ module Capybara end end - def within_frame frame_id + def within_frame(frame_id) driver.within_frame(frame_id) do yield end From b74d6cf8293bee287f16ff9b859d383bd54bd8fb Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sun, 9 May 2010 17:00:33 +0200 Subject: [PATCH 76/84] Sleep a little while, closes #44 --- lib/capybara/wait_until.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/capybara/wait_until.rb b/lib/capybara/wait_until.rb index 7d661979..6c0ba678 100644 --- a/lib/capybara/wait_until.rb +++ b/lib/capybara/wait_until.rb @@ -18,6 +18,8 @@ module Capybara end driver && driver.wait_until(delay) + + sleep(0.05) end end From 66249c7bab3b2a08f93a28d5977af59de0193cb4 Mon Sep 17 00:00:00 2001 From: Jon Swope Date: Thu, 22 Apr 2010 16:41:25 -0400 Subject: [PATCH 77/84] [Jon Swope/Zack Adams] Selenium requires a string not a symbol for attribute resolution --- lib/capybara/driver/selenium_driver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index fb4c52f0..646ad48a 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -10,7 +10,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base if name == :value node.value else - node.attribute(name) + node.attribute(name.to_s) end rescue Selenium::WebDriver::Error::WebDriverError nil From 90bda23d800c72ee9d262c2430f9c731f967863a Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sun, 9 May 2010 17:39:01 +0200 Subject: [PATCH 78/84] unless is never a good idea --- lib/capybara/session.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 78329633..dfbc8e52 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -62,7 +62,7 @@ module Capybara def fill_in(locator, options={}) msg = "cannot fill in, no text field, text area or password field with id, name, or label '#{locator}' found" - raise "Must pass a hash containing 'with'" unless options.kind_of? Hash && !options.index(:with).nil? + raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with) locate(:xpath, XPath.fillable_field(locator), msg).set(options[:with]) end From 686e9d7a915ef182bd7c48f68657597131e35dfa Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 12 May 2010 16:40:59 +0200 Subject: [PATCH 79/84] Reverting a19c902a65c1389922e73afc3453d1ca4d7c0b6d I have not seen any discussion around this change nor does it have a test case. It seems reasonable but not uncontroversial. --- lib/capybara/driver/selenium_driver.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 646ad48a..cc30dd6f 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -70,12 +70,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def visible? - begin - node.displayed? and node.displayed? != "false" - rescue Selenium::WebDriver::Error::WebDriverError - # rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible - return false - end + node.displayed? and node.displayed? != "false" end def trigger(event) From 58f8826ac38dd8bb581642fff9a23e07ffb8773e Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 12 May 2010 16:45:11 +0200 Subject: [PATCH 80/84] Added a bit of history --- History.txt | 18 +++++++++++++++++- README.rdoc | 3 ++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/History.txt b/History.txt index f132e2ff..562b77bc 100644 --- a/History.txt +++ b/History.txt @@ -1,4 +1,20 @@ -# Versiob 0.3.7 +# Version 0.3.8 + +Release date: 2010-05-12 + +### Added + +* Within_frame method to execute a block of code within a particular iframe (Selenium only!) + +### Fixed + +* Single quotes are properly escaped with `select` under rack-test and Selenium. +* The :text option for searches now escapes regexp special characters when a string is given. +* Selenium now correctly checks already checked checkboxes (same with uncheck) +* Timing issue which caused Selenium to hang under certain circumstances. +* Selenium now resolves attributes even if they are given as a Symbol + +# Version 0.3.7 Release date: 2010-04-09 diff --git a/README.rdoc b/README.rdoc index a70291eb..def2c16b 100644 --- a/README.rdoc +++ b/README.rdoc @@ -27,7 +27,8 @@ On OSX you may have to install libffi, you can install it via MacPorts with: * Report issues on {GitHub Issues}[http://github.com/jnicklas/capybara/issues] Pull requests are very welcome! Make sure your patches are well tested, Capybara is -a testing tool after all. +a testing tool after all. Please create a topic branch for every separate change +you make, I will not pull anything from your master branch. == Using Capybara with Cucumber From c2e25f96546938396adcf70b4637d6f77233f725 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 12 May 2010 16:45:39 +0200 Subject: [PATCH 81/84] note in readme about topic branches --- README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index def2c16b..fb138c73 100644 --- a/README.rdoc +++ b/README.rdoc @@ -28,7 +28,7 @@ On OSX you may have to install libffi, you can install it via MacPorts with: Pull requests are very welcome! Make sure your patches are well tested, Capybara is a testing tool after all. Please create a topic branch for every separate change -you make, I will not pull anything from your master branch. +you make. == Using Capybara with Cucumber From 8ff36c49338dd214bee611317cf1ef8cfce2016e Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 12 May 2010 16:51:55 +0200 Subject: [PATCH 82/84] tagged 0.3.8 --- lib/capybara/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/version.rb b/lib/capybara/version.rb index 09dcf777..fd97fe03 100644 --- a/lib/capybara/version.rb +++ b/lib/capybara/version.rb @@ -1,3 +1,3 @@ module Capybara - VERSION = '0.3.7' + VERSION = '0.3.8' end From b8f423027183dfda5c3edae738058a46e8465e09 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Wed, 26 May 2010 16:37:14 +0200 Subject: [PATCH 83/84] Fail early when no rack application is set. --- lib/capybara/driver/rack_test_driver.rb | 1 + spec/driver/rack_test_driver_spec.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index 201a5ecb..79431067 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -183,6 +183,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base alias_method :request, :last_request def initialize(app) + raise ArgumentError, "rack-test requires a rack application, but none was given" unless app @app = app end diff --git a/spec/driver/rack_test_driver_spec.rb b/spec/driver/rack_test_driver_spec.rb index e4b03d5e..25427519 100644 --- a/spec/driver/rack_test_driver_spec.rb +++ b/spec/driver/rack_test_driver_spec.rb @@ -4,6 +4,12 @@ describe Capybara::Driver::RackTest do before do @driver = Capybara::Driver::RackTest.new(TestApp) end + + it "should throw an error when no rack app is given" do + running do + Capybara::Driver::RackTest.new(nil) + end.should raise_error(ArgumentError) + end it_should_behave_like "driver" it_should_behave_like "driver with header support" From c6918f307c0e41a5047af6a8582ca1996bc40c1a Mon Sep 17 00:00:00 2001 From: Jonathon Padfield Date: Tue, 1 Jun 2010 13:16:58 +1000 Subject: [PATCH 84/84] Fixed the xpath when selecting an option so that it should match labels with preceding or trailing whitespace. --- lib/capybara/driver/selenium_driver.rb | 4 ++-- lib/capybara/spec/session/select_spec.rb | 6 ++++++ lib/capybara/spec/views/form.erb | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index cc30dd6f..b24754b6 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -36,7 +36,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def select(option) - option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") + option_node = node.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") option_node.select rescue options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ') @@ -49,7 +49,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end begin - option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") + option_node = node.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]") option_node.clear rescue options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ') diff --git a/lib/capybara/spec/session/select_spec.rb b/lib/capybara/spec/session/select_spec.rb index c17395be..b6348118 100644 --- a/lib/capybara/spec/session/select_spec.rb +++ b/lib/capybara/spec/session/select_spec.rb @@ -37,6 +37,12 @@ shared_examples_for "select" do extract_results(@session)['locale'].should == 'jo' end + it "match labels with preceding or trailing whitespace" do + @session.select("Lojban", :from => 'Locale') + @session.click_button('awesome') + extract_results(@session)['locale'].should == 'jbo' + 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) diff --git a/lib/capybara/spec/views/form.erb b/lib/capybara/spec/views/form.erb index 06cf50d5..ab3f90ed 100644 --- a/lib/capybara/spec/views/form.erb +++ b/lib/capybara/spec/views/form.erb @@ -77,6 +77,7 @@ +