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 @@
+