capybara 0.4.0 → 0.4.1.rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +35 -0
- data/README.rdoc +60 -19
- data/lib/capybara.rb +81 -5
- data/lib/capybara/driver/base.rb +1 -6
- data/lib/capybara/driver/celerity_driver.rb +19 -9
- data/lib/capybara/driver/node.rb +8 -0
- data/lib/capybara/driver/rack_test_driver.rb +42 -29
- data/lib/capybara/driver/selenium_driver.rb +11 -3
- data/lib/capybara/dsl.rb +11 -0
- data/lib/capybara/node/actions.rb +4 -14
- data/lib/capybara/node/base.rb +47 -0
- data/lib/capybara/node/document.rb +17 -0
- data/lib/capybara/node/element.rb +178 -0
- data/lib/capybara/node/finders.rb +78 -27
- data/lib/capybara/node/matchers.rb +40 -11
- data/lib/capybara/node/simple.rb +116 -0
- data/lib/capybara/rspec.rb +18 -0
- data/lib/capybara/server.rb +5 -10
- data/lib/capybara/session.rb +7 -16
- data/lib/capybara/spec/driver.rb +16 -1
- data/lib/capybara/spec/session.rb +1 -0
- data/lib/capybara/spec/session/all_spec.rb +5 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +2 -3
- data/lib/capybara/spec/session/find_spec.rb +0 -6
- data/lib/capybara/spec/session/first_spec.rb +72 -0
- data/lib/capybara/spec/session/has_css_spec.rb +107 -1
- data/lib/capybara/spec/session/has_field_spec.rb +60 -0
- data/lib/capybara/spec/session/has_select_spec.rb +40 -0
- data/lib/capybara/spec/session/javascript.rb +4 -13
- data/lib/capybara/spec/session/within_spec.rb +10 -3
- data/lib/capybara/spec/test_app.rb +20 -1
- data/lib/capybara/spec/views/form.erb +27 -0
- data/lib/capybara/spec/views/with_html.erb +21 -5
- data/lib/capybara/util/save_and_open_page.rb +8 -5
- data/lib/capybara/version.rb +1 -1
- data/spec/basic_node_spec.rb +77 -0
- data/spec/capybara_spec.rb +18 -0
- data/spec/dsl_spec.rb +26 -0
- data/spec/rspec_spec.rb +47 -0
- data/spec/save_and_open_page_spec.rb +83 -7
- data/spec/server_spec.rb +20 -0
- data/spec/session/rack_test_session_spec.rb +10 -0
- data/spec/string_spec.rb +77 -0
- metadata +306 -295
- data/lib/capybara/node.rb +0 -221
data/History.txt
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
# Version 0.4.1
|
2
|
+
|
3
|
+
Release date:
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* New click_on alias for click_link_or_button, shorter yet unambiguous. [Jonas Nicklas]
|
8
|
+
* Finders now accept :visible => false which will find all elements regardless of Capybara.ignore_hidden_elements [Jonas Nicklas]
|
9
|
+
* Configure how the server is started via Capybara.server { |app, port| ... }. [John Firebough]
|
10
|
+
* Added :between, :maximum and :minimum options to has_selector and friends [James B. Byrne]
|
11
|
+
* New Capybara.string util function which allows matchers on arbitrary strings, mostly for helper and view specs [David Chelimsky and Jonas Nicklas]
|
12
|
+
* Server boot timeout is now configurable, via Capybara.server_boot_timeout [Adam Cigánek]
|
13
|
+
* Built in support for RSpec [Jonas Nicklas]
|
14
|
+
* Capybara.using_driver to switch to a different driver temporarily [Jeff Kreeftmeijer]
|
15
|
+
* Added Session#first which is somewhat speedier than Session#all, use it internally for speed boost [John Firebaugh]
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
* Session#within now accepts the same arguments as other finders, like Session#all and Session#find [Jonas Nicklas]
|
20
|
+
|
21
|
+
### Removed
|
22
|
+
|
23
|
+
* All deprecations from 0.4.0 have been removed. [Jonas Nicklas]
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
* Don't mangle URLs in save_and_open_page when using self-closing tags [Adam Spiers]
|
28
|
+
* Catch correct error when server boot times out [Jonas Nicklas]
|
29
|
+
* Celerity driver now properly passes through options, making it configurable [Jonas Nicklas]
|
30
|
+
* Better implementation of attributes in C[ue]lerity, should fix issues with attributes with strange names [Jonas Nicklas]
|
31
|
+
* Session#find no longer swallows errors [Jonas Nicklas]
|
32
|
+
* Fix problems with multiple file inputs [Philip Arndt]
|
33
|
+
* Submit multipart forms as multipart under rack-test even if they contain no files [Ryan Kinderman]
|
34
|
+
* Matchers like has_select? and has_checked_field? now work with dynamically changed values [John Firebaugh]
|
35
|
+
|
1
36
|
# Version 0.4.0
|
2
37
|
|
3
38
|
Release date: 2010-10-22
|
data/README.rdoc
CHANGED
@@ -64,6 +64,57 @@ Now you can use it in your steps:
|
|
64
64
|
click_link 'Sign in'
|
65
65
|
end
|
66
66
|
|
67
|
+
Capybara sets up some {tags}[http://wiki.github.com/aslakhellesoy/cucumber/tags]
|
68
|
+
for you to use in Cucumber. Often you'll want to run only some scenarios with a
|
69
|
+
driver that supports JavaScript, Capybara makes this easy: simply tag the
|
70
|
+
scenario (or feature) with <tt>@javascript</tt>:
|
71
|
+
|
72
|
+
@javascript
|
73
|
+
Scenario: do something AJAXy
|
74
|
+
When I click the AJAX link
|
75
|
+
...
|
76
|
+
|
77
|
+
You can change which driver Capybara uses for JavaScript:
|
78
|
+
|
79
|
+
Capybara.javascript_driver = :culerity
|
80
|
+
|
81
|
+
There are also explicit <tt>@selenium</tt>, <tt>@culerity</tt> and
|
82
|
+
<tt>@rack_test</tt> tags set up for you.
|
83
|
+
|
84
|
+
== Using Capybara with RSpec
|
85
|
+
|
86
|
+
If you prefer RSpec to using Cucumber, you can use the built in RSpec support:
|
87
|
+
|
88
|
+
require 'capybara/rspec'
|
89
|
+
Capybara.app = MyRackApp
|
90
|
+
|
91
|
+
You can now use it in your examples:
|
92
|
+
|
93
|
+
describe "the signup process", :type => :acceptance do
|
94
|
+
it "signs me in" do
|
95
|
+
within("#session") do
|
96
|
+
fill_in 'Login', :with => 'user@example.com'
|
97
|
+
fill_in 'Password', :with => 'password'
|
98
|
+
end
|
99
|
+
click_link 'Sign in'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
Capybara is only included for examples which have the type
|
104
|
+
<tt>:acceptance</tt>.
|
105
|
+
|
106
|
+
RSpec's metadata feature can be used to switch to a different driver. Use
|
107
|
+
<tt>:js => true</tt> to switch to the javascript driver, or provide a
|
108
|
+
<tt>:driver</tt> option to switch to one specific driver. For example:
|
109
|
+
|
110
|
+
describe 'some stuff which requires js', :js => true do
|
111
|
+
it 'will use the default js driver'
|
112
|
+
it 'will switch to one specific driver', :driver => :celerity
|
113
|
+
end
|
114
|
+
|
115
|
+
Note that Capybara's built in RSpec support only works with RSpec 2.0 or later.
|
116
|
+
You'll need to roll your own for earlier versions of RSpec.
|
117
|
+
|
67
118
|
== Default and current driver
|
68
119
|
|
69
120
|
You can set up a default driver for your features. For example if you'd prefer
|
@@ -82,25 +133,6 @@ You can do this in Before and After blocks to temporarily switch to a different
|
|
82
133
|
driver. Note that switching driver creates a new session, so you may not be able
|
83
134
|
to switch in the middle of a Scenario.
|
84
135
|
|
85
|
-
== Cucumber and Tags
|
86
|
-
|
87
|
-
Capybara sets up some {tags}[http://wiki.github.com/aslakhellesoy/cucumber/tags]
|
88
|
-
for you to use in Cucumber. Often you'll want to run only some scenarios with a
|
89
|
-
driver that supports JavaScript, Capybara makes this easy: simply tag the
|
90
|
-
scenario (or feature) with <tt>@javascript</tt>:
|
91
|
-
|
92
|
-
@javascript
|
93
|
-
Scenario: do something AJAXy
|
94
|
-
When I click the AJAX link
|
95
|
-
...
|
96
|
-
|
97
|
-
You can change which driver Capybara uses for JavaScript:
|
98
|
-
|
99
|
-
Capybara.javascript_driver = :culerity
|
100
|
-
|
101
|
-
There are also explicit <tt>@selenium</tt>, <tt>@culerity</tt> and
|
102
|
-
<tt>@rack_test</tt> tags set up for you.
|
103
|
-
|
104
136
|
== Selenium
|
105
137
|
|
106
138
|
At the moment, Capybara supports Webdriver, also called Selenium 2.0, *not*
|
@@ -456,6 +488,9 @@ Whatever is returned from the block should conform to the API described by
|
|
456
488
|
Capybara::Driver::Base, it does not however have to inherit from this class.
|
457
489
|
Gems can use this API to add their own drivers to Capybara.
|
458
490
|
|
491
|
+
The {Selenium wiki}[http://code.google.com/p/selenium/wiki/RubyBindings] has
|
492
|
+
additional info about how the underlying driver can be configured.
|
493
|
+
|
459
494
|
== Gotchas:
|
460
495
|
|
461
496
|
* Access to session and request is not possible from the test, Access to
|
@@ -473,6 +508,12 @@ Gems can use this API to add their own drivers to Capybara.
|
|
473
508
|
use plugins which allow you to travel in time, rather than freeze time.
|
474
509
|
One such plugin is {Timecop}[http://github.com/jtrupiano/timecop].
|
475
510
|
|
511
|
+
* When using Rack::Test, beware if attempting to visit absolute URLs. For
|
512
|
+
example, a session might not be shared between visits to <tt>posts_path</tt>
|
513
|
+
and <tt>posts_url</tt>. If testing an absolute URL in an Action Mailer email,
|
514
|
+
set <tt>default_url_options</tt> to match the Rails default of
|
515
|
+
<tt>www.example.com</tt>.
|
516
|
+
|
476
517
|
== License:
|
477
518
|
|
478
519
|
(The MIT License)
|
data/lib/capybara.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'timeout'
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'xpath'
|
4
|
-
|
5
4
|
module Capybara
|
6
5
|
class CapybaraError < StandardError; end
|
7
6
|
class DriverNotFoundError < CapybaraError; end
|
@@ -14,7 +13,7 @@ module Capybara
|
|
14
13
|
|
15
14
|
class << self
|
16
15
|
attr_accessor :asset_root, :app_host, :run_server, :default_host
|
17
|
-
attr_accessor :server_port
|
16
|
+
attr_accessor :server_port, :server_boot_timeout
|
18
17
|
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
|
19
18
|
attr_accessor :save_and_open_page_path
|
20
19
|
|
@@ -108,6 +107,74 @@ module Capybara
|
|
108
107
|
@drivers ||= {}
|
109
108
|
end
|
110
109
|
|
110
|
+
##
|
111
|
+
#
|
112
|
+
# Register a proc that Capybara will call to run the Rack application.
|
113
|
+
#
|
114
|
+
# Capybara.server do |app, port|
|
115
|
+
# require 'rack/handler/mongrel'
|
116
|
+
# Rack::Handler::Mongrel.run(app, :Port => port)
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# By default, Capybara will try to run thin, falling back to webrick.
|
120
|
+
#
|
121
|
+
# @yield [app, port] This block recieves a rack app and port and should run a Rack handler
|
122
|
+
#
|
123
|
+
def server(&block)
|
124
|
+
if block_given?
|
125
|
+
@server = block
|
126
|
+
else
|
127
|
+
@server
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
#
|
133
|
+
# Wraps the given string, which should contain an HTML document or fragment
|
134
|
+
# in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers} and
|
135
|
+
# {Capybara::Node::Finders}. This allows you to query any string containing
|
136
|
+
# HTML in the exact same way you would query the current document in a Capybara
|
137
|
+
# session. For example:
|
138
|
+
#
|
139
|
+
# node = Capybara.string <<-HTML
|
140
|
+
# <ul>
|
141
|
+
# <li id="home">Home</li>
|
142
|
+
# <li id="projects">Projects</li>
|
143
|
+
# </ul>
|
144
|
+
# HTML
|
145
|
+
#
|
146
|
+
# node.find('#projects').text # => 'Projects'
|
147
|
+
# node.has_selector?('li#home', :text => 'Home')
|
148
|
+
# node.has_selector?(:projects)
|
149
|
+
# node.find('ul').find('li').text # => 'Home'
|
150
|
+
#
|
151
|
+
# @param [String] html An html fragment or document
|
152
|
+
# @return [Capybara::Node::Simple] A node which has Capybara's finders and matchers
|
153
|
+
#
|
154
|
+
def string(html)
|
155
|
+
Capybara::Node::Simple.new(html)
|
156
|
+
end
|
157
|
+
|
158
|
+
##
|
159
|
+
#
|
160
|
+
# Runs Capybara's default server for the given application and port
|
161
|
+
# under most circumstances you should not have to call this method
|
162
|
+
# manually.
|
163
|
+
#
|
164
|
+
# @param [Rack Application] app The rack application to run
|
165
|
+
# @param [Fixnum] port The port to run the application on
|
166
|
+
#
|
167
|
+
def run_default_server(app, port)
|
168
|
+
begin
|
169
|
+
require 'rack/handler/thin'
|
170
|
+
Thin::Logging.silent = true
|
171
|
+
Rack::Handler::Thin.run(app, :Port => port)
|
172
|
+
rescue LoadError
|
173
|
+
require 'rack/handler/webrick'
|
174
|
+
Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
111
178
|
def deprecate(method, alternate_method)
|
112
179
|
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead"
|
113
180
|
end
|
@@ -115,12 +182,19 @@ module Capybara
|
|
115
182
|
|
116
183
|
autoload :Server, 'capybara/server'
|
117
184
|
autoload :Session, 'capybara/session'
|
118
|
-
autoload :Node, 'capybara/node'
|
119
|
-
autoload :Document, 'capybara/node'
|
120
|
-
autoload :Element, 'capybara/node'
|
121
185
|
autoload :Selector, 'capybara/selector'
|
122
186
|
autoload :VERSION, 'capybara/version'
|
123
187
|
|
188
|
+
module Node
|
189
|
+
autoload :Base, 'capybara/node/base'
|
190
|
+
autoload :Simple, 'capybara/node/simple'
|
191
|
+
autoload :Element, 'capybara/node/element'
|
192
|
+
autoload :Document, 'capybara/node/document'
|
193
|
+
autoload :Finders, 'capybara/node/finders'
|
194
|
+
autoload :Matchers, 'capybara/node/matchers'
|
195
|
+
autoload :Actions, 'capybara/node/actions'
|
196
|
+
end
|
197
|
+
|
124
198
|
module Driver
|
125
199
|
autoload :Base, 'capybara/driver/base'
|
126
200
|
autoload :Node, 'capybara/driver/node'
|
@@ -133,6 +207,8 @@ end
|
|
133
207
|
|
134
208
|
Capybara.configure do |config|
|
135
209
|
config.run_server = true
|
210
|
+
config.server {|app, port| Capybara.run_default_server(app, port)}
|
211
|
+
config.server_boot_timeout = 10
|
136
212
|
config.default_selector = :css
|
137
213
|
config.default_wait_time = 2
|
138
214
|
config.ignore_hidden_elements = false
|
data/lib/capybara/driver/base.rb
CHANGED
@@ -30,7 +30,7 @@ class Capybara::Driver::Base
|
|
30
30
|
def response_headers
|
31
31
|
raise Capybara::NotSupportedByDriverError
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def status_code
|
35
35
|
raise Capybara::NotSupportedByDriverError
|
36
36
|
end
|
@@ -53,11 +53,6 @@ class Capybara::Driver::Base
|
|
53
53
|
def reset!
|
54
54
|
end
|
55
55
|
|
56
|
-
def cleanup!
|
57
|
-
Capybara.deprecate("cleanup!", "reset!")
|
58
|
-
reset!
|
59
|
-
end
|
60
|
-
|
61
56
|
def has_shortcircuit_timeout?
|
62
57
|
false
|
63
58
|
end
|
@@ -5,19 +5,15 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def [](name)
|
8
|
-
value =
|
9
|
-
native.class_name
|
10
|
-
else
|
11
|
-
native.send(name.to_sym)
|
12
|
-
end
|
8
|
+
value = native.attribute_value(name.to_sym)
|
13
9
|
return value if value and not value.to_s.empty?
|
14
10
|
end
|
15
11
|
|
16
12
|
def value
|
17
13
|
if tag_name == "select" and native.multiple?
|
18
|
-
find(".//option[@selected]").map { |n| n.value
|
14
|
+
find(".//option[@selected]").map { |n| if n.has_value? then n.value else n.text end }
|
19
15
|
else
|
20
|
-
|
16
|
+
native.value
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
@@ -60,6 +56,18 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
60
56
|
native.visible?
|
61
57
|
end
|
62
58
|
|
59
|
+
def checked?
|
60
|
+
native.checked?
|
61
|
+
rescue # https://github.com/langalex/culerity/issues/issue/33
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def selected?
|
66
|
+
native.selected?
|
67
|
+
rescue # https://github.com/langalex/culerity/issues/issue/33
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
63
71
|
def path
|
64
72
|
native.xpath
|
65
73
|
end
|
@@ -81,7 +89,9 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
81
89
|
find('./ancestor::select').first
|
82
90
|
end
|
83
91
|
|
84
|
-
|
92
|
+
def has_value?
|
93
|
+
native.object.hasAttribute('value')
|
94
|
+
end
|
85
95
|
end
|
86
96
|
|
87
97
|
attr_reader :app, :rack_server, :options
|
@@ -135,7 +145,7 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
135
145
|
def browser
|
136
146
|
unless @_browser
|
137
147
|
require 'celerity'
|
138
|
-
@_browser = ::Celerity::Browser.new(
|
148
|
+
@_browser = ::Celerity::Browser.new(options)
|
139
149
|
end
|
140
150
|
|
141
151
|
@_browser
|
data/lib/capybara/driver/node.rb
CHANGED
@@ -11,28 +11,11 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def [](name)
|
14
|
-
|
15
|
-
case
|
16
|
-
when 'select' == tag_name && 'value' == attr_name
|
17
|
-
if native['multiple'] == 'multiple'
|
18
|
-
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
|
19
|
-
else
|
20
|
-
option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
|
21
|
-
option[:value] || option.content if option
|
22
|
-
end
|
23
|
-
when 'input' == tag_name && 'checkbox' == type && 'checked' == attr_name
|
24
|
-
native[attr_name] == 'checked' ? true : false
|
25
|
-
else
|
26
|
-
native[attr_name]
|
27
|
-
end
|
14
|
+
string_node[name]
|
28
15
|
end
|
29
16
|
|
30
17
|
def value
|
31
|
-
|
32
|
-
native.content
|
33
|
-
else
|
34
|
-
self[:value]
|
35
|
-
end
|
18
|
+
string_node.value
|
36
19
|
end
|
37
20
|
|
38
21
|
def set(value)
|
@@ -82,7 +65,15 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
82
65
|
end
|
83
66
|
|
84
67
|
def visible?
|
85
|
-
|
68
|
+
string_node.visible?
|
69
|
+
end
|
70
|
+
|
71
|
+
def checked?
|
72
|
+
self[:checked]
|
73
|
+
end
|
74
|
+
|
75
|
+
def selected?
|
76
|
+
self[:selected]
|
86
77
|
end
|
87
78
|
|
88
79
|
def path
|
@@ -95,6 +86,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
95
86
|
|
96
87
|
private
|
97
88
|
|
89
|
+
def string_node
|
90
|
+
@string_node ||= Capybara::Node::Simple.new(native)
|
91
|
+
end
|
92
|
+
|
98
93
|
# a reference to the select node if this is an option node
|
99
94
|
def select_node
|
100
95
|
find('./ancestor::select').first
|
@@ -110,10 +105,25 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
110
105
|
end
|
111
106
|
|
112
107
|
class Form < Node
|
108
|
+
# This only needs to inherit from Rack::Test::UploadedFile because Rack::Test checks for
|
109
|
+
# the class specifically when determing whether to consturct the request as multipart.
|
110
|
+
# That check should be based solely on the form element's 'enctype' attribute value,
|
111
|
+
# which should probably be provided to Rack::Test in its non-GET request methods.
|
112
|
+
class NilUploadedFile < Rack::Test::UploadedFile
|
113
|
+
def initialize
|
114
|
+
@empty_file = Tempfile.new("nil_uploaded_file")
|
115
|
+
@empty_file.close
|
116
|
+
end
|
117
|
+
|
118
|
+
def original_filename; ""; end
|
119
|
+
def content_type; "application/octet-stream"; end
|
120
|
+
def path; @empty_file.path; end
|
121
|
+
end
|
122
|
+
|
113
123
|
def params(button)
|
114
124
|
params = {}
|
115
125
|
|
116
|
-
native.xpath(".//input[not(@disabled) and (not(@type) or (@type!='radio' and @type!='checkbox' and @type!='submit' and @type!='image'))]").map do |input|
|
126
|
+
native.xpath(".//input[not(@disabled) and (not(@type) or (@type!='radio' and @type!='file' and @type!='checkbox' and @type!='submit' and @type!='image'))]").map do |input|
|
117
127
|
merge_param!(params, input['name'].to_s, input['value'].to_s)
|
118
128
|
end
|
119
129
|
native.xpath(".//textarea[not(@disabled)]").map do |textarea|
|
@@ -135,14 +145,17 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
135
145
|
end
|
136
146
|
end
|
137
147
|
native.xpath(".//input[not(@disabled) and @type='file']").map do |input|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
148
|
+
if multipart?
|
149
|
+
file = \
|
150
|
+
if (value = input['value']).to_s.empty?
|
151
|
+
NilUploadedFile.new
|
152
|
+
else
|
153
|
+
content_type = MIME::Types.type_for(value).first.to_s
|
154
|
+
Rack::Test::UploadedFile.new(value, content_type)
|
155
|
+
end
|
156
|
+
merge_param!(params, input['name'].to_s, file)
|
157
|
+
else
|
158
|
+
merge_param!(params, input['name'].to_s, File.basename(input['value'].to_s))
|
146
159
|
end
|
147
160
|
end
|
148
161
|
merge_param!(params, button[:name], button[:value] || "") if button[:name]
|