From 7adeb86f2c5d4f9c0f92c00280ba8d55a9d4d2bb Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Tue, 21 Oct 2008 22:35:12 -0400 Subject: [PATCH] Add support for clicking areas of an image map (Alex Lang) --- History.txt | 9 ++-- lib/webrat/core/area.rb | 44 ++++++++++++++++++++ lib/webrat/core/scope.rb | 17 +++++++- lib/webrat/core/session.rb | 1 + spec/api/clicks_area_spec.rb | 81 ++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 lib/webrat/core/area.rb create mode 100644 spec/api/clicks_area_spec.rb 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 + + Berlin + + EOS + @session.should_receive(:get).with("/page", {}) + @session.clicks_area "Berlin" + end + + it "should assert valid response" do + @session.response_body = <<-EOS + + Berlin + + 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 + + Berlin + + EOS + + lambda { + @session.clicks_area "Missing area" + }.should raise_error + end + + it "should not be case sensitive" do + @session.response_body = <<-EOS + + Berlin + + 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 + + Berlin + + 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 + + Berlin + + 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 + + Berlin + + EOS + @session.should_receive(:get).with("/page?foo=bar", {}) + @session.clicks_area "Berlin" + end +end