diff --git a/History.txt b/History.txt
index 887bf96..378f661 100644
--- a/History.txt
+++ b/History.txt
@@ -5,17 +5,18 @@
* Added #basic_auth(user, pass) to support HTTP Basic Auth (Aslak Hellesøy)
* Added support for Sinatra and Rack (Aslak Hellesøy)
* Added #within for manipulating the current page within a selector scope
- * Add should_see and should_not_see for verifying HTML response bodys
* Add support for simulating SSL requests (Luke Melia)
* Add support for file fields via #attaches_file method (Kyle Hargraves)
+
+* Minor enhancements
+
+ * Add support for clicking areas of an image map (Alex Lang)
+ * Add should_see and should_not_see for verifying HTML response bodys
* Support relative links, including href="?foo=bar" (Kyle Hargraves)
* Separated Rails-specific code from the Webrat core to make it easier to use Webrat with other environments
* Alias visits as visit, clicks_link as click_link, etc. for better readability
* Raise error when trying to interact with a disabled form element (Luke Melia)
* Don't send disabled form elements to the server (Nicholas A. Evans)
-
-* Minor enhancements
-
* Display response body when the page load is not successful (David Leal)
* CGI escape form field values (Miha Filej)
* Add support for redirect_to :back by sending HTTP_REFERER headers (Hendrik Volkmer)
diff --git a/lib/webrat/core/area.rb b/lib/webrat/core/area.rb
new file mode 100644
index 0000000..3812654
--- /dev/null
+++ b/lib/webrat/core/area.rb
@@ -0,0 +1,44 @@
+module Webrat
+ class Area
+
+ def initialize(session, element)
+ @session = session
+ @element = element
+ end
+
+ def click(method = nil, options = {})
+ @session.request_page(absolute_href, :get, {})
+ end
+
+ def matches_text?(id_or_title)
+ matcher = /#{Regexp.escape(id_or_title.to_s)}/i
+ title =~ matcher || id =~ matcher
+ end
+
+ protected
+
+ def href
+ @element["href"]
+ end
+
+ def title
+ @element["title"]
+ end
+
+ def id
+ @element["id"]
+ end
+
+
+ def absolute_href
+ if href =~ /^\?/
+ "#{@session.current_url}#{href}"
+ elsif href !~ %r{^https?://[\w|.]+(/.*)} && (href !~ /^\//)
+ "#{@session.current_url}/#{href}"
+ else
+ href
+ end
+ end
+
+ end
+end
\ No newline at end of file
diff --git a/lib/webrat/core/scope.rb b/lib/webrat/core/scope.rb
index f74727d..99b95c6 100644
--- a/lib/webrat/core/scope.rb
+++ b/lib/webrat/core/scope.rb
@@ -91,6 +91,12 @@ module Webrat
alias_method :attach_file, :attaches_file
+ def clicks_area(area_name)
+ find_area(area_name).click
+ end
+
+ alias_method :click_area, :clicks_area
+
# Issues a request for the URL pointed to by a link on the current page,
# follows any redirects, and verifies the final page load was successful.
#
@@ -200,10 +206,19 @@ module Webrat
button = form.find_button(value)
return button if button
end
-
flunk("Could not find button #{value.inspect}")
end
+ def find_area(area_name)
+ areas.select{|area| area.matches_text?(area_name)}.first || flunk("Could not find area with name #{area_name}")
+ end
+
+ def areas
+ (dom / "area").map do |element|
+ Area.new(@session, element)
+ end
+ end
+
def find_link(text, selector = nil)
matching_links = links_within(selector).select do |possible_link|
possible_link.matches_text?(text)
diff --git a/lib/webrat/core/session.rb b/lib/webrat/core/session.rb
index ffe7eeb..04e25af 100644
--- a/lib/webrat/core/session.rb
+++ b/lib/webrat/core/session.rb
@@ -152,6 +152,7 @@ module Webrat
def_delegators :current_scope, :choose, :chooses
def_delegators :current_scope, :select, :selects
def_delegators :current_scope, :attach_file, :attaches_file
+ def_delegators :current_scope, :click_area, :clicks_area
def_delegators :current_scope, :click_link, :clicks_link
def_delegators :current_scope, :click_get_link, :clicks_get_link
def_delegators :current_scope, :click_delete_link, :clicks_delete_link
diff --git a/spec/api/clicks_area_spec.rb b/spec/api/clicks_area_spec.rb
new file mode 100644
index 0000000..c7fbc29
--- /dev/null
+++ b/spec/api/clicks_area_spec.rb
@@ -0,0 +1,81 @@
+require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
+
+describe "clicks_area" do
+ before do
+ @session = Webrat::TestSession.new
+ end
+
+ it "should use get by default" do
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.should_receive(:get).with("/page", {})
+ @session.clicks_area "Berlin"
+ end
+
+ it "should assert valid response" do
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.response_code = 404
+ lambda { @session.clicks_area "Berlin" }.should raise_error
+ end
+
+ it "should fail if the area doesn't exist" do
+ @session.response_body = <<-EOS
+
+ EOS
+
+ lambda {
+ @session.clicks_area "Missing area"
+ }.should raise_error
+ end
+
+ it "should not be case sensitive" do
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.should_receive(:get).with("/page", {})
+ @session.clicks_area "berlin"
+ end
+
+
+ it "should follow relative links" do
+ @session.stub!(:current_url).and_return("/page")
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.should_receive(:get).with("/page/sub", {})
+ @session.clicks_area "Berlin"
+ end
+
+ it "should follow fully qualified local links" do
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.should_receive(:get).with("http://www.example.com/page", {})
+ @session.clicks_area "Berlin"
+ end
+
+ it "should follow query parameters" do
+ @session.response_body = <<-EOS
+
+ EOS
+ @session.should_receive(:get).with("/page?foo=bar", {})
+ @session.clicks_area "Berlin"
+ end
+end