Added clicks_link_within(selector, link_text), allowing restricting link search to within a given css selector.

This commit is contained in:
Luke Melia 2008-03-13 19:36:27 -04:00
parent ed8b39cccc
commit 747a5381f6
2 changed files with 42 additions and 14 deletions

View File

@ -24,17 +24,15 @@ module ActionController
# Example: # Example:
# clicks_link "Sign up" # clicks_link "Sign up"
def clicks_link(link_text) def clicks_link(link_text)
link = find_shortest_matching_link(link_text) clicks_one_link_of(all_links, link_text)
end
return flunk("No link with text #{link_text.inspect} was found") if link.nil?
# Works like clicks_link, but only looks for the link text within a given selector
onclick = link.attributes["onclick"] #
href = link.attributes["href"] # Example:
# clicks_link_within "#user_12", "Vote"
http_method = http_method_from_js(onclick) def clicks_link_within(selector, link_text)
authenticity_token = authenticity_token_value(onclick) clicks_one_link_of(links_within(selector), link_text)
request_page(http_method, href, authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token})
end end
# Works like clicks_link, but forces a GET request # Works like clicks_link, but forces a GET request
@ -222,16 +220,30 @@ module ActionController
end end
def clicks_link_with_method(link_text, http_method) # :nodoc: 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? return flunk("No link with text #{link_text.inspect} was found") if link.nil?
request_page(http_method, link.attributes["href"]) request_page(http_method, link.attributes["href"])
end 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 = links.select { |el| el.innerHTML =~ /#{link_text}/i }
candidates.sort_by { |el| el.innerText.strip.size }.first candidates.sort_by { |el| el.innerText.strip.size }.first
end 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: def find_field_by_name_or_label(name_or_label) # :nodoc:
input = find_field_by_name(name_or_label) input = find_field_by_name(name_or_label)
return input if input return input if input
@ -436,9 +448,13 @@ module ActionController
@form_data ||= [] @form_data ||= []
end end
def links # :nodoc: def all_links # :nodoc:
(dom / "a[@href]") (dom / "a[@href]")
end end
def links_within(selector) # :nodoc:
(dom / selector / "a[@href]")
end
def form_number(form) # :nodoc: def form_number(form) # :nodoc:
(dom / "form").index(form) (dom / "form").index(form)

View File

@ -170,4 +170,16 @@ class ClicksLinkTest < Test::Unit::TestCase
@session.clicks_link "Link" @session.clicks_link "Link"
end end
def test_should_click_link_within_a_selector
@response.stubs(:body).returns(<<-EOS)
<a href="/page1">Link</a>
<div id="container">
<a href="/page2">Link</a>
</div>
EOS
@session.expects(:get_via_redirect).with("/page2", {})
@session.clicks_link_within "#container", "Link"
end
end end