Send input with custom types

This puts the rack-test driver more inline with
how real browsers work by sending all inputs
with types it doesn't recognize as though they
were type="text".
This commit is contained in:
Jonas Nicklas 2010-03-12 20:11:21 +01:00
parent 113823e3b1
commit eef3a2c6bb
4 changed files with 34 additions and 18 deletions

View File

@ -28,9 +28,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
def set(value)
if tag_name == 'input' and %w(text password hidden file).include?(type)
node['value'] = value.to_s
elsif tag_name == 'input' and type == 'radio'
if tag_name == 'input' and type == 'radio'
driver.html.xpath("//input[@name='#{self[:name]}']").each { |node| node.remove_attribute("checked") }
node['checked'] = 'checked'
elsif tag_name == 'input' and type == 'checkbox'
@ -39,6 +37,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
else
node.remove_attribute('checked')
end
elsif tag_name == 'input'
node['value'] = value.to_s
elsif tag_name == "textarea"
node.content = value.to_s
end
@ -113,7 +113,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
text_fields = %w[text hidden password url color tel email search].map{|f| "@type='#{f}'"}.join(' or ')
node.xpath(".//input[#{text_fields}]").map do |input|
node.xpath(".//input[@type!='radio' and @type!='checkbox' and @type!='submit']").map do |input|
merge_param!(params, input['name'].to_s, input['value'].to_s)
end
node.xpath(".//textarea").map do |textarea|

View File

@ -46,9 +46,7 @@ module Capybara
end
def fillable_field(locator, options={})
[:text, :password, :email, :url, :search, :tel, :color].inject(text_area(locator, options)) do |all, type|
all.input_field(type, locator, options)
end
text_area(locator, options).text_field(locator, options)
end
def content(locator)
@ -84,6 +82,11 @@ module Capybara
xpath = xpath.prepend("//button[@value=#{s(locator)} or text()=#{s(locator)}]")
end
def text_field(locator, options={})
options = options.merge(:value => options[:with]) if options.has_key?(:with)
add_field(locator, "//input[@type!='radio' and @type!='checkbox' and @type!='hidden']", options)
end
def text_area(locator, options={})
options = options.merge(:text => options[:with]) if options.has_key?(:with)
add_field(locator, "//textarea", options)
@ -93,11 +96,6 @@ module Capybara
add_field(locator, "//select", options)
end
def input_field(type, locator, options={})
options = options.merge(:value => options[:with]) if options.has_key?(:with)
add_field(locator, "//input[@type='#{type}']", options)
end
def scope(scope)
XPath.new(*paths.map { |p| scope + p })
end
@ -122,16 +120,17 @@ module Capybara
input_field(:radio, locator, options)
end
[:text, :password, :email, :url, :search, :tel, :color, :file].each do |type|
class_eval <<-RUBY, __FILE__, __LINE__+1
def #{type}_field(locator)
input_field(:#{type}, locator)
end
RUBY
def file_field(locator, options={})
input_field(:file, locator, options)
end
protected
def input_field(type, locator, options={})
options = options.merge(:value => options[:with]) if options.has_key?(:with)
add_field(locator, "//input[@type='#{type}']", options)
end
# place this between to nodes to indicate that they should be siblings
def sibling
'/following-sibling::*[1]/self::'

View File

@ -52,6 +52,18 @@ shared_examples_for "fill_in" do
extract_results(@session)['password'].should == 'supasikrit'
end
it "should fill in a field with a custom type" do
@session.fill_in('Schmooo', :with => 'Schmooo is the game')
@session.click_button('awesome')
extract_results(@session)['schmooo'].should == 'Schmooo is the game'
end
it "should fill in a password field by name" do
@session.fill_in('form[password]', :with => 'supasikrit')
@session.click_button('awesome')
extract_results(@session)['password'].should == 'supasikrit'
end
it "should fill in a password field by label" do
@session.fill_in('Password', :with => 'supasikrit')
@session.click_button('awesome')

View File

@ -32,6 +32,11 @@
<label for="form_name">Name</label>
<input type="text" name="form[name]" value="John Smith" id="form_name"/>
</p>
<p>
<label for="form_schmooo">Schmooo</label>
<input type="schmooo" name="form[schmooo]" value="This is Schmooo!" id="form_schmooo"/>
</p>
<p>
<label>Street<br/>