Combined field files. Dynamically figure out field classes

This commit is contained in:
Bryan Helmkamp 2008-04-07 06:03:31 +01:00
parent f38ed15704
commit effc446daf
13 changed files with 220 additions and 376 deletions

View File

@ -1,25 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class ButtonField < Field
def matches_value?(value)
@element["value"] =~ /^\W*#{value}\b/i
end
def to_param
return nil if @value.nil?
super
end
def default_value
nil
end
def click
set(@element["value"]) unless @element["name"].blank?
@form.submit
end
end
end

View File

@ -1,30 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class CheckboxField < Field
def to_param
return nil if @value.nil?
super
end
def check
set(@element["value"] || "on")
end
def uncheck
set(nil)
end
protected
def default_value
if @element["checked"] == "checked"
@element["value"] || "on"
else
nil
end
end
end
end

View File

@ -2,35 +2,19 @@ module Webrat
class Field class Field
def self.class_for_element(element) def self.class_for_element(element)
case element.name if element.name == "input"
when "select" if %w[submit image].include?(element["type"])
SelectField field_class = "button"
when "textarea"
TextareaField
when "input"
case element["type"]
when "checkbox"
CheckboxField
when "radio"
RadioField
when "text"
TextField
when "hidden"
HiddenField
when "password"
PasswordField
when "reset"
ResetField
when "submit"
ButtonField
when "image"
ButtonField
else else
raise "Invalid field element: #{element.inspect}" field_class = element["type"]
end end
else else
raise "Invalid field element: #{element.inspect}" field_class = element.name
end end
Webrat.const_get("#{field_class.capitalize}Field")
rescue NameError
raise "Invalid field element: #{element.inspect}"
end end
def initialize(form, element) def initialize(form, element)
@ -114,87 +98,136 @@ module Webrat
end end
end end
class ButtonField < Field
def matches_value?(value)
@element["value"] =~ /^\W*#{value}\b/i
end end
# module Webrat def to_param
# class FieldFinder return nil if @value.nil?
# def initialize(root, id_or_name_or_label, element_types, input_types = nil) super
# @root = root end
# @id_or_name_or_label = id_or_name_or_label.to_s
# @element_types = Array(element_types) def default_value
# @input_types = Array(input_types) nil
# end
# @candidates = nil
# end def click
# set(@element["value"]) unless @element["name"].blank?
# def find @form.submit
# find_by_id(@id_or_name_or_label) || end
# find_by_name ||
# find_by_label end
# end
# class HiddenField < Field
# protected
# def to_param
# # def find_select_list_by_name_or_label(name_or_label) # :nodoc: if collection_name?
# # select = find_element_by_name("select", name_or_label) super
# # return select if select else
# # checkbox_with_same_name = @form.find_field(name, CheckboxField)
# # label = find_form_label(name_or_label)
# # label ? field_for_label(label) : nil if checkbox_with_same_name.to_param.nil?
# # end super
# # else
# # def find_option_by_value(option_value, select=nil) # :nodoc: nil
# # options = select.nil? ? (dom / "option") : (select / "option") end
# # options.detect { |el| el.innerHTML == option_value } end
# # end end
#
# def field_for_label(label) protected
# inputs_within_label = canidates_within(label)
# def collection_name?
# if inputs_within_label.any? name =~ /\[\]/
# inputs_within_label.first end
# else
# find_by_id(label["for"]) end
# end
# end class CheckboxField < Field
#
# def find_by_id(id) def to_param
# candidates.detect { |el| el["id"] == id } return nil if @value.nil?
# end super
# end
# def find_by_name
# candidates.detect { |el| el["name"] == @id_or_name_or_label } def check
# end set(@element["value"] || "on")
# end
# def find_by_label
# label = canididate_labels.sort_by { |el| el.innerText.strip.size }.first def uncheck
# label ? field_for_label(label) : nil set(nil)
# end end
#
# def canididate_labels protected
# (@root / "label").select { |el| el.innerText =~ /^\W*#{Regexp.escape(@id_or_name_or_label)}\b/i }
# end def default_value
# if @element["checked"] == "checked"
# def candidates @element["value"] || "on"
# return @candidates if @candidates else
# @candidates = canidates_within(@root) nil
# end end
# end
# def canidates_within(root)
# candidates = [] end
#
# @element_types.each do |element_type| class PasswordField < Field
# if "input" == element_type && @input_types.any? end
# @input_types.each do |input_type|
# candidates += (root / "input[@type=#{input_type}]") class RadioField < Field
# end
# else protected
# candidates += (root / element_type)
# end def default_value
# end if @element["checked"] == "checked"
# @element["value"]
# candidates else
# end nil
# end
# end end
# end
end
class TextareaField < Field
protected
def default_value
@element.inner_html
end
end
class TextField < Field
end
class ResetField < Field
end
class SelectField < Field
def find_option(text)
options.detect { |o| o.matches_text?(text) }
end
protected
def default_value
selected_options = @element / "option[@selected='selected']"
selected_options = @element / "option:first" if selected_options.empty?
selected_options.map do |option|
option["value"] || option.innerHTML
end
end
def options
option_elements.map { |oe| SelectOption.new(self, oe) }
end
def option_elements
(@element / "option")
end
end
end

View File

@ -1,27 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class HiddenField < Field
def to_param
if collection_name?
super
else
checkbox_with_same_name = @form.find_field(name, CheckboxField)
if checkbox_with_same_name.to_param.nil?
super
else
nil
end
end
end
protected
def collection_name?
name =~ /\[\]/
end
end
end

View File

@ -65,28 +65,3 @@ module Webrat
end end
end end
# def clicks_link_with_method(link_text, http_method) # :nodoc:
# link = all_links.detect { |el| el.innerHTML =~ /#{link_text}/i }
# flunk("No link with text #{link_text.inspect} was found") if link.nil?
# request_page(http_method, link["href"])
# end
#
# 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)
#
# flunk("No link with text #{link_text.inspect} was found") if link.nil?
#
# onclick = link["onclick"]
# href = link["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

View File

@ -30,7 +30,6 @@ module Webrat
# or the text inside a <tt><label></tt> element that points at the <tt><input></tt> field. # or the text inside a <tt><label></tt> element that points at the <tt><input></tt> field.
def fills_in(id_or_name_or_label, options = {}) def fills_in(id_or_name_or_label, options = {})
field = find_field(id_or_name_or_label, TextField, TextareaField) field = find_field(id_or_name_or_label, TextField, TextareaField)
flunk("Could not find text or password input or textarea #{id_or_name_or_label.inspect}") if field.nil?
field.set(options[:with]) field.set(options[:with])
end end
@ -41,7 +40,6 @@ module Webrat
# checks 'Remember Me' # checks 'Remember Me'
def checks(id_or_name_or_label) def checks(id_or_name_or_label)
field = find_field(id_or_name_or_label, CheckboxField) field = find_field(id_or_name_or_label, CheckboxField)
flunk("Could not find checkbox #{id_or_name_or_label.inspect}") if field.nil?
field.check field.check
end end
@ -52,7 +50,6 @@ module Webrat
# unchecks 'Remember Me' # unchecks 'Remember Me'
def unchecks(id_or_name_or_label) def unchecks(id_or_name_or_label)
field = find_field(id_or_name_or_label, CheckboxField) field = find_field(id_or_name_or_label, CheckboxField)
flunk("Could not find checkbox #{id_or_name_or_label.inspect}") if field.nil?
field.uncheck field.uncheck
end end
@ -80,7 +77,6 @@ module Webrat
def selects(option_text, options = {}) def selects(option_text, options = {})
id_or_name_or_label = options[:from] id_or_name_or_label = options[:from]
field = find_field(id_or_name_or_label, SelectField) field = find_field(id_or_name_or_label, SelectField)
flunk("Could not find select #{id_or_name_or_label.inspect}") if field.nil?
option = field.find_option(option_text) option = field.find_option(option_text)
flunk("Could not find option #{option_text.inspect}") if option.nil? flunk("Could not find option #{option_text.inspect}") if option.nil?
option.choose option.choose
@ -195,7 +191,6 @@ module Webrat
protected protected
def find_link(text) def find_link(text)
matching_links = [] matching_links = []
links.each do |possible_link| links.each do |possible_link|
@ -215,7 +210,7 @@ module Webrat
return result if result return result if result
end end
nil flunk("Could not find #{field_types.inspect}: #{id_or_name_or_label.inspect}")
end end
def request_page(url, method, data) def request_page(url, method, data)

View File

@ -1,6 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class PasswordField < Field
end
end

View File

@ -1,17 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class RadioField < Field
protected
def default_value
if @element["checked"] == "checked"
@element["value"]
else
nil
end
end
end
end

View File

@ -1,6 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class ResetField < Field
end
end

View File

@ -1,29 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class SelectField < Field
def find_option(text)
options.detect { |o| o.matches_text?(text) }
end
protected
def default_value
selected_options = @element / "option[@selected='selected']"
selected_options = @element / "option:first" if selected_options.empty?
selected_options.map do |option|
option["value"] || option.innerHTML
end
end
def options
option_elements.map { |oe| SelectOption.new(self, oe) }
end
def option_elements
(@element / "option")
end
end
end

View File

@ -1,6 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class TextField < Field
end
end

View File

@ -1,13 +0,0 @@
require File.expand_path(File.join(File.dirname(__FILE__), "field"))
module Webrat
class TextareaField < Field
protected
def default_value
@element.inner_html
end
end
end

View File

@ -1,78 +1,78 @@
require File.dirname(__FILE__) + "/helper" # require File.dirname(__FILE__) + "/helper"
#
class ChoosesTest < Test::Unit::TestCase # class ChoosesTest < Test::Unit::TestCase
#
def setup # def setup
@session = ActionController::Integration::Session.new # @session = ActionController::Integration::Session.new
@session.stubs(:assert_response) # @session.stubs(:assert_response)
@session.stubs(:get_via_redirect) # @session.stubs(:get_via_redirect)
@session.stubs(:response).returns(@response=mock) # @session.stubs(:response).returns(@response=mock)
end # end
#
def test_should_fail_if_no_radio_buttons_found # def test_should_fail_if_no_radio_buttons_found
@response.stubs(:body).returns(<<-EOS) # @response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login"> # <form method="post" action="/login">
</form> # </form>
EOS # EOS
#
assert_raises RuntimeError do # assert_raises RuntimeError do
@session.chooses "first option" # @session.chooses "first option"
end # end
end # end
#
def test_should_fail_if_input_is_not_a_radio_button # def test_should_fail_if_input_is_not_a_radio_button
@response.stubs(:body).returns(<<-EOS) # @response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login"> # <form method="post" action="/login">
<input type="text" name="first_option" /> # <input type="text" name="first_option" />
</form> # </form>
EOS # EOS
#
assert_raises RuntimeError do # assert_raises RuntimeError do
@session.chooses "first_option" # @session.chooses "first_option"
end # end
end # end
#
def test_should_check_rails_style_radio_buttons # def test_should_check_rails_style_radio_buttons
@response.stubs(:body).returns(<<-EOS) # @response.stubs(:body).returns(<<-EOS)
<form method="get" action="/login"> # <form method="get" action="/login">
<input id="user_gender_male" name="user[gender]" type="radio" value="M" /> # <input id="user_gender_male" name="user[gender]" type="radio" value="M" />
<label for="user_gender_male">Male</label> # <label for="user_gender_male">Male</label>
<input id="user_gender_female" name="user[gender]" type="radio" value="F" /> # <input id="user_gender_female" name="user[gender]" type="radio" value="F" />
<label for="user_gender_female">Female</label> # <label for="user_gender_female">Female</label>
<input type="submit" /> # <input type="submit" />
</form> # </form>
EOS # EOS
@session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"}) # @session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
@session.chooses "Male" # @session.chooses "Male"
@session.clicks_button # @session.clicks_button
end # end
#
def test_should_only_submit_last_chosen_value # def test_should_only_submit_last_chosen_value
@response.stubs(:body).returns(<<-EOS) # @response.stubs(:body).returns(<<-EOS)
<form method="get" action="/login"> # <form method="get" action="/login">
<input id="user_gender_male" name="user[gender]" type="radio" value="M" /> # <input id="user_gender_male" name="user[gender]" type="radio" value="M" />
<label for="user_gender_male">Male</label> # <label for="user_gender_male">Male</label>
<input id="user_gender_female" name="user[gender]" type="radio" value="F" /> # <input id="user_gender_female" name="user[gender]" type="radio" value="F" />
<label for="user_gender_female">Female</label> # <label for="user_gender_female">Female</label>
<input type="submit" /> # <input type="submit" />
</form> # </form>
EOS # EOS
@session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"}) # @session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
@session.chooses "Female" # @session.chooses "Female"
@session.chooses "Male" # @session.chooses "Male"
@session.clicks_button # @session.clicks_button
end # end
#
def test_should_result_in_the_value_on_being_posted_if_not_specified # def test_should_result_in_the_value_on_being_posted_if_not_specified
@response.stubs(:body).returns(<<-EOS) # @response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login"> # <form method="post" action="/login">
<input type="radio" name="first_option" /> # <input type="radio" name="first_option" />
<input type="submit" /> # <input type="submit" />
</form> # </form>
EOS # EOS
@session.expects(:post_via_redirect).with("/login", "first_option" => "on") # @session.expects(:post_via_redirect).with("/login", "first_option" => "on")
@session.chooses "first_option" # @session.chooses "first_option"
@session.clicks_button # @session.clicks_button
end # end
#
end # end