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
def self.class_for_element(element)
case element.name
when "select"
SelectField
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
if element.name == "input"
if %w[submit image].include?(element["type"])
field_class = "button"
else
raise "Invalid field element: #{element.inspect}"
field_class = element["type"]
end
else
raise "Invalid field element: #{element.inspect}"
field_class = element.name
end
Webrat.const_get("#{field_class.capitalize}Field")
rescue NameError
raise "Invalid field element: #{element.inspect}"
end
def initialize(form, element)
@ -114,87 +98,136 @@ module Webrat
end
end
end
class ButtonField < Field
# module Webrat
# class FieldFinder
# def initialize(root, id_or_name_or_label, element_types, input_types = nil)
# @root = root
# @id_or_name_or_label = id_or_name_or_label.to_s
# @element_types = Array(element_types)
# @input_types = Array(input_types)
#
# @candidates = nil
# end
#
# def find
# find_by_id(@id_or_name_or_label) ||
# find_by_name ||
# find_by_label
# end
#
# protected
#
# # def find_select_list_by_name_or_label(name_or_label) # :nodoc:
# # select = find_element_by_name("select", name_or_label)
# # return select if select
# #
# # label = find_form_label(name_or_label)
# # label ? field_for_label(label) : nil
# # end
# #
# # def find_option_by_value(option_value, select=nil) # :nodoc:
# # options = select.nil? ? (dom / "option") : (select / "option")
# # options.detect { |el| el.innerHTML == option_value }
# # end
#
# def field_for_label(label)
# inputs_within_label = canidates_within(label)
#
# if inputs_within_label.any?
# inputs_within_label.first
# else
# find_by_id(label["for"])
# end
# end
#
# def find_by_id(id)
# candidates.detect { |el| el["id"] == id }
# end
#
# def find_by_name
# candidates.detect { |el| el["name"] == @id_or_name_or_label }
# end
#
# def find_by_label
# label = canididate_labels.sort_by { |el| el.innerText.strip.size }.first
# label ? field_for_label(label) : nil
# end
#
# def canididate_labels
# (@root / "label").select { |el| el.innerText =~ /^\W*#{Regexp.escape(@id_or_name_or_label)}\b/i }
# end
#
# def candidates
# return @candidates if @candidates
# @candidates = canidates_within(@root)
# end
#
# def canidates_within(root)
# candidates = []
#
# @element_types.each do |element_type|
# if "input" == element_type && @input_types.any?
# @input_types.each do |input_type|
# candidates += (root / "input[@type=#{input_type}]")
# end
# else
# candidates += (root / element_type)
# end
# end
#
# candidates
# end
#
# end
# end
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
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
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
class PasswordField < Field
end
class RadioField < Field
protected
def default_value
if @element["checked"] == "checked"
@element["value"]
else
nil
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
# 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.
def fills_in(id_or_name_or_label, options = {})
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])
end
@ -41,7 +40,6 @@ module Webrat
# checks 'Remember Me'
def checks(id_or_name_or_label)
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
end
@ -52,7 +50,6 @@ module Webrat
# unchecks 'Remember Me'
def unchecks(id_or_name_or_label)
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
end
@ -80,7 +77,6 @@ module Webrat
def selects(option_text, options = {})
id_or_name_or_label = options[:from]
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)
flunk("Could not find option #{option_text.inspect}") if option.nil?
option.choose
@ -195,7 +191,6 @@ module Webrat
protected
def find_link(text)
matching_links = []
links.each do |possible_link|
@ -215,7 +210,7 @@ module Webrat
return result if result
end
nil
flunk("Could not find #{field_types.inspect}: #{id_or_name_or_label.inspect}")
end
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"
class ChoosesTest < Test::Unit::TestCase
def setup
@session = ActionController::Integration::Session.new
@session.stubs(:assert_response)
@session.stubs(:get_via_redirect)
@session.stubs(:response).returns(@response=mock)
end
def test_should_fail_if_no_radio_buttons_found
@response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login">
</form>
EOS
assert_raises RuntimeError do
@session.chooses "first option"
end
end
def test_should_fail_if_input_is_not_a_radio_button
@response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login">
<input type="text" name="first_option" />
</form>
EOS
assert_raises RuntimeError do
@session.chooses "first_option"
end
end
def test_should_check_rails_style_radio_buttons
@response.stubs(:body).returns(<<-EOS)
<form method="get" action="/login">
<input id="user_gender_male" name="user[gender]" type="radio" value="M" />
<label for="user_gender_male">Male</label>
<input id="user_gender_female" name="user[gender]" type="radio" value="F" />
<label for="user_gender_female">Female</label>
<input type="submit" />
</form>
EOS
@session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
@session.chooses "Male"
@session.clicks_button
end
def test_should_only_submit_last_chosen_value
@response.stubs(:body).returns(<<-EOS)
<form method="get" action="/login">
<input id="user_gender_male" name="user[gender]" type="radio" value="M" />
<label for="user_gender_male">Male</label>
<input id="user_gender_female" name="user[gender]" type="radio" value="F" />
<label for="user_gender_female">Female</label>
<input type="submit" />
</form>
EOS
@session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
@session.chooses "Female"
@session.chooses "Male"
@session.clicks_button
end
def test_should_result_in_the_value_on_being_posted_if_not_specified
@response.stubs(:body).returns(<<-EOS)
<form method="post" action="/login">
<input type="radio" name="first_option" />
<input type="submit" />
</form>
EOS
@session.expects(:post_via_redirect).with("/login", "first_option" => "on")
@session.chooses "first_option"
@session.clicks_button
end
end
# require File.dirname(__FILE__) + "/helper"
#
# class ChoosesTest < Test::Unit::TestCase
#
# def setup
# @session = ActionController::Integration::Session.new
# @session.stubs(:assert_response)
# @session.stubs(:get_via_redirect)
# @session.stubs(:response).returns(@response=mock)
# end
#
# def test_should_fail_if_no_radio_buttons_found
# @response.stubs(:body).returns(<<-EOS)
# <form method="post" action="/login">
# </form>
# EOS
#
# assert_raises RuntimeError do
# @session.chooses "first option"
# end
# end
#
# def test_should_fail_if_input_is_not_a_radio_button
# @response.stubs(:body).returns(<<-EOS)
# <form method="post" action="/login">
# <input type="text" name="first_option" />
# </form>
# EOS
#
# assert_raises RuntimeError do
# @session.chooses "first_option"
# end
# end
#
# def test_should_check_rails_style_radio_buttons
# @response.stubs(:body).returns(<<-EOS)
# <form method="get" action="/login">
# <input id="user_gender_male" name="user[gender]" type="radio" value="M" />
# <label for="user_gender_male">Male</label>
# <input id="user_gender_female" name="user[gender]" type="radio" value="F" />
# <label for="user_gender_female">Female</label>
# <input type="submit" />
# </form>
# EOS
# @session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
# @session.chooses "Male"
# @session.clicks_button
# end
#
# def test_should_only_submit_last_chosen_value
# @response.stubs(:body).returns(<<-EOS)
# <form method="get" action="/login">
# <input id="user_gender_male" name="user[gender]" type="radio" value="M" />
# <label for="user_gender_male">Male</label>
# <input id="user_gender_female" name="user[gender]" type="radio" value="F" />
# <label for="user_gender_female">Female</label>
# <input type="submit" />
# </form>
# EOS
# @session.expects(:get_via_redirect).with("/login", "user" => {"gender" => "M"})
# @session.chooses "Female"
# @session.chooses "Male"
# @session.clicks_button
# end
#
# def test_should_result_in_the_value_on_being_posted_if_not_specified
# @response.stubs(:body).returns(<<-EOS)
# <form method="post" action="/login">
# <input type="radio" name="first_option" />
# <input type="submit" />
# </form>
# EOS
# @session.expects(:post_via_redirect).with("/login", "first_option" => "on")
# @session.chooses "first_option"
# @session.clicks_button
# end
#
# end