From 747a5381f610656b8cc07eb8603c33a6672f9888 Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Thu, 13 Mar 2008 19:36:27 -0400 Subject: [PATCH] Added clicks_link_within(selector, link_text), allowing restricting link search to within a given css selector. --- lib/webrat/session.rb | 44 +++++++++++++++++++++++++++------------- test/clicks_link_test.rb | 12 +++++++++++ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/lib/webrat/session.rb b/lib/webrat/session.rb index 4eeccaa..dec0ae1 100644 --- a/lib/webrat/session.rb +++ b/lib/webrat/session.rb @@ -24,17 +24,15 @@ module ActionController # Example: # clicks_link "Sign up" def clicks_link(link_text) - link = find_shortest_matching_link(link_text) - - return flunk("No link with text #{link_text.inspect} was found") if link.nil? - - onclick = link.attributes["onclick"] - href = link.attributes["href"] - - http_method = http_method_from_js(onclick) - authenticity_token = authenticity_token_value(onclick) - - request_page(http_method, href, authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token}) + clicks_one_link_of(all_links, link_text) + end + + # Works like clicks_link, but only looks for the link text within a given selector + # + # Example: + # clicks_link_within "#user_12", "Vote" + def clicks_link_within(selector, link_text) + clicks_one_link_of(links_within(selector), link_text) end # Works like clicks_link, but forces a GET request @@ -222,16 +220,30 @@ module ActionController end def clicks_link_with_method(link_text, http_method) # :nodoc: - link = links.detect { |el| el.innerHTML =~ /#{link_text}/i } + link = all_links.detect { |el| el.innerHTML =~ /#{link_text}/i } return flunk("No link with text #{link_text.inspect} was found") if link.nil? request_page(http_method, link.attributes["href"]) end - def find_shortest_matching_link(link_text) + def find_shortest_matching_link(links, link_text) candidates = links.select { |el| el.innerHTML =~ /#{link_text}/i } candidates.sort_by { |el| el.innerText.strip.size }.first end + def clicks_one_link_of(links, link_text) + link = find_shortest_matching_link(links, link_text) + + return flunk("No link with text #{link_text.inspect} was found") if link.nil? + + onclick = link.attributes["onclick"] + href = link.attributes["href"] + + http_method = http_method_from_js(onclick) + authenticity_token = authenticity_token_value(onclick) + + request_page(http_method, href, authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token}) + end + def find_field_by_name_or_label(name_or_label) # :nodoc: input = find_field_by_name(name_or_label) return input if input @@ -436,9 +448,13 @@ module ActionController @form_data ||= [] end - def links # :nodoc: + def all_links # :nodoc: (dom / "a[@href]") end + + def links_within(selector) # :nodoc: + (dom / selector / "a[@href]") + end def form_number(form) # :nodoc: (dom / "form").index(form) diff --git a/test/clicks_link_test.rb b/test/clicks_link_test.rb index 4131a00..8d4580e 100644 --- a/test/clicks_link_test.rb +++ b/test/clicks_link_test.rb @@ -170,4 +170,16 @@ class ClicksLinkTest < Test::Unit::TestCase @session.clicks_link "Link" end + def test_should_click_link_within_a_selector + @response.stubs(:body).returns(<<-EOS) + Link +
+ Link +
+ EOS + + @session.expects(:get_via_redirect).with("/page2", {}) + @session.clicks_link_within "#container", "Link" + end + end