From 9fe0ef33af1adb0fb6a0abbf0919f12b38c465d8 Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Wed, 12 Mar 2008 02:04:41 -0400 Subject: [PATCH 1/3] Added default form values for select menus. --- lib/webrat/session.rb | 29 +++++++++++++++----------- test/clicks_button_test.rb | 42 ++++++++++++++++++++++++++++++++++++++ test/selects_test.rb | 4 ++-- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/lib/webrat/session.rb b/lib/webrat/session.rb index 28fe945..1daeb78 100644 --- a/lib/webrat/session.rb +++ b/lib/webrat/session.rb @@ -377,30 +377,25 @@ module ActionController add_default_params_from_checkboxes_for(form) add_default_params_from_radio_buttons_for(form) add_default_params_from_textareas_for(form) + add_default_params_from_selects_for(form) end def add_default_params_from_inputs_for(form) # :nodoc: - (form / "input").each do |input| - next if input.attributes["value"].blank? || !%w[text hidden].include?(input.attributes["type"]) + ((form / "input[@type='text']") + (form / "input[@type='hidden']")).each do |input| + next if input.attributes["value"].blank? add_form_data(input, input.attributes["value"]) end end def add_default_params_from_checkboxes_for(form) # :nodoc: - (form / "input").each do |input| - next if input.attributes["type"] != "checkbox" - if input.attributes["checked"] == "checked" - add_form_data(input, input.attributes["value"] || "on") - end + (form / "input[@type='checkbox][@checked='checked']").each do |input| + add_form_data(input, input.attributes["value"] || "on") end end def add_default_params_from_radio_buttons_for(form) # :nodoc: - (form / "input").each do |input| - next if input.attributes["type"] != "radio" - if input.attributes["checked"] == "checked" - add_form_data(input, input.attributes["value"]) - end + (form / "input[@type='radio][@checked='checked']").each do |input| + add_form_data(input, input.attributes["value"]) end end @@ -410,6 +405,16 @@ module ActionController end end + def add_default_params_from_selects_for(form) # :nodoc: + (form / "select").each do |select| + selected_options = select / "option[@selected='selected']" + selected_options = select / "option:first" if selected_options.empty? + selected_options.each do |option| + add_form_data(select, option.attributes["value"] || option.innerHTML) + end + end + end + def form_for_node(node) # :nodoc: return node if node.name == "form" node = node.parent until node.name == "form" diff --git a/test/clicks_button_test.rb b/test/clicks_button_test.rb index b765907..c3b9964 100644 --- a/test/clicks_button_test.rb +++ b/test/clicks_button_test.rb @@ -219,6 +219,48 @@ class ClicksButtonTest < Test::Unit::TestCase @session.clicks_button end + def test_should_send_default_selected_option_value_from_select + @response.stubs(:body).returns(<<-EOS) +
+ + +
+ EOS + @session.expects(:get_via_redirect).with("/login", "month" => "2") + @session.clicks_button + end + + def test_should_send_default_selected_option_inner_html_from_select_when_no_value_attribute + @response.stubs(:body).returns(<<-EOS) +
+ + +
+ EOS + @session.expects(:get_via_redirect).with("/login", "month" => "February") + @session.clicks_button + end + + def test_should_send_first_select_option_value_when_no_option_selected + @response.stubs(:body).returns(<<-EOS) +
+ + +
+ EOS + @session.expects(:get_via_redirect).with("/login", "month" => "1") + @session.clicks_button + end + def test_should_handle_nested_properties @response.stubs(:body).returns(<<-EOS)
diff --git a/test/selects_test.rb b/test/selects_test.rb index a602def..93e1bd2 100644 --- a/test/selects_test.rb +++ b/test/selects_test.rb @@ -59,7 +59,7 @@ class SelectsTest < Test::Unit::TestCase
EOS - @session.expects(:post_via_redirect).with("/login", "end_month" => "e1") + @session.expects(:post_via_redirect).with("/login", "start_month" => "s1", "end_month" => "e1") @session.selects "January", :from => "end_month" @session.clicks_button end @@ -74,7 +74,7 @@ class SelectsTest < Test::Unit::TestCase EOS - @session.expects(:post_via_redirect).with("/login", "end_month" => "e1") + @session.expects(:post_via_redirect).with("/login", "start_month" => "s1", "end_month" => "e1") @session.selects "January", :from => "End Month" @session.clicks_button end From ed8b39cccc659ebf99134bef85462027bf135aea Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Thu, 13 Mar 2008 18:01:00 -0400 Subject: [PATCH 2/3] Changed clicks_link to find the shortest matching link. --- lib/webrat/session.rb | 8 +++++++- test/clicks_link_test.rb | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/webrat/session.rb b/lib/webrat/session.rb index 1daeb78..4eeccaa 100644 --- a/lib/webrat/session.rb +++ b/lib/webrat/session.rb @@ -24,7 +24,8 @@ module ActionController # Example: # clicks_link "Sign up" def clicks_link(link_text) - link = links.detect { |el| el.innerHTML =~ /#{link_text}/i } + 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"] @@ -226,6 +227,11 @@ module ActionController request_page(http_method, link.attributes["href"]) end + def find_shortest_matching_link(link_text) + candidates = links.select { |el| el.innerHTML =~ /#{link_text}/i } + candidates.sort_by { |el| el.innerText.strip.size }.first + end + def find_field_by_name_or_label(name_or_label) # :nodoc: input = find_field_by_name(name_or_label) return input if input diff --git a/test/clicks_link_test.rb b/test/clicks_link_test.rb index 5f63ada..4131a00 100644 --- a/test/clicks_link_test.rb +++ b/test/clicks_link_test.rb @@ -159,4 +159,15 @@ class ClicksLinkTest < Test::Unit::TestCase @session.expects(:get_via_redirect).with("/page1", {}) @session.clicks_link "Link text" end + + def test_should_choose_the_shortest_link_text_match + @response.stubs(:body).returns(<<-EOS) + Linkerama + Link + EOS + + @session.expects(:get_via_redirect).with("/page2", {}) + @session.clicks_link "Link" + end + end From 747a5381f610656b8cc07eb8603c33a6672f9888 Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Thu, 13 Mar 2008 19:36:27 -0400 Subject: [PATCH 3/3] 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