From f874b176daa7f4cbc3619c034f0195762a8fa41f Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Mon, 11 Jan 2010 21:59:22 +0100 Subject: [PATCH] Edge cases for links and buttons Links with anchors, without hrefs, forms without action. --- lib/capybara/driver/rack_test_driver.rb | 30 +++++++++++++------------ lib/capybara/xpath.rb | 4 ++-- spec/dsl/click_button_spec.rb | 12 ++++++++++ spec/dsl/click_link_spec.rb | 25 +++++++++++++++++++++ spec/views/postback.erb | 13 +++++++++++ spec/views/with_html.erb | 7 ++++++ 6 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 spec/views/postback.erb diff --git a/lib/capybara/driver/rack_test_driver.rb b/lib/capybara/driver/rack_test_driver.rb index ccb7e95f..abb6b0a3 100644 --- a/lib/capybara/driver/rack_test_driver.rb +++ b/lib/capybara/driver/rack_test_driver.rb @@ -38,7 +38,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base def click if tag_name == 'a' - driver.visit(self[:href]) + driver.visit(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 @@ -100,23 +100,19 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end def submit(button) - if post? - driver.submit(node['action'].to_s, params(button)) - else - driver.visit(node['action'].to_s, params(button)) - end + driver.submit(method, node['action'].to_s, params(button)) end def multipart? self[:enctype] == "multipart/form-data" end - def post? - self[:method] =~ /post/i + private + + def method + self[:method] =~ /post/i ? :post : :get end - private - def merge_param!(params, key, value) collection = key.sub!(/\[\]$/, '') if collection @@ -143,21 +139,23 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base end def visit(path, attributes = {}) + return if path.gsub(/^#{current_path}/, '') =~ /^#/ get(path, attributes) follow_redirects! cache_body end def current_url - request.url + request.url rescue "" end def response_headers response.headers end - def submit(path, attributes) - post(path, attributes) + def submit(method, path, attributes) + path = current_path if not path or path.empty? + send(method, path, attributes) follow_redirects! cache_body end @@ -166,7 +164,11 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base html.xpath(selector).map { |node| Node.new(self, node) } end - private +private + + def current_path + request.path rescue "" + end def follow_redirects! Capybara::WaitUntil.timeout(4) do diff --git a/lib/capybara/xpath.rb b/lib/capybara/xpath.rb index ce80d0e7..d357af3d 100644 --- a/lib/capybara/xpath.rb +++ b/lib/capybara/xpath.rb @@ -56,8 +56,8 @@ module Capybara end def link(locator) - xpath = append("//a[@id=#{s(locator)} or contains(.,#{s(locator)}) or contains(@title,#{s(locator)})]") - xpath.prepend("//a[text()=#{s(locator)} or @title=#{s(locator)}]") + xpath = append("//a[@href][@id=#{s(locator)} or contains(.,#{s(locator)}) or contains(@title,#{s(locator)})]") + xpath.prepend("//a[@href][text()=#{s(locator)} or @title=#{s(locator)}]") end def button(locator) diff --git a/spec/dsl/click_button_spec.rb b/spec/dsl/click_button_spec.rb index d8d7334e..319f3b20 100644 --- a/spec/dsl/click_button_spec.rb +++ b/spec/dsl/click_button_spec.rb @@ -166,6 +166,18 @@ module ClickButtonSpec @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') + @session.body.should include('Postback') + end end end end diff --git a/spec/dsl/click_link_spec.rb b/spec/dsl/click_link_spec.rb index 47695847..6e544f0d 100644 --- a/spec/dsl/click_link_spec.rb +++ b/spec/dsl/click_link_spec.rb @@ -58,6 +58,31 @@ module ClickLinkSpec @session.click_link('Redirect') @session.body.should include('You landed') end + + it "should do nothing on anchor links" do + @session.fill_in("test_field", :with => 'blah') + @session.click_link('Anchor') + @session.find_field("test_field").value.should == 'blah' + @session.click_link('Blank Anchor') + @session.find_field("test_field").value.should == 'blah' + end + + it "should do nothing on URL+anchor links for the same page" do + @session.fill_in("test_field", :with => 'blah') + @session.click_link('Anchor on same page') + @session.find_field("test_field").value.should == 'blah' + end + + it "should follow link on URL+anchor links for a different page" do + @session.click_link('Anchor on different page') + @session.body.should include('Bar') + end + + it "raise an error with links with no href" do + running do + @session.click_link('No Href') + end.should raise_error(Capybara::ElementNotFound) + end end end end \ No newline at end of file diff --git a/spec/views/postback.erb b/spec/views/postback.erb new file mode 100644 index 00000000..340c2d21 --- /dev/null +++ b/spec/views/postback.erb @@ -0,0 +1,13 @@ +

Postback

+ +
+

+ +

+
+ +
+

+ +

+
\ No newline at end of file diff --git a/spec/views/with_html.erb b/spec/views/with_html.erb index f661434d..e7984478 100644 --- a/spec/views/with_html.erb +++ b/spec/views/with_html.erb @@ -18,6 +18,13 @@ A link came first A link + No Href + Blank Href + Blank Anchor + Anchor + Anchor on different page + Anchor on same page +