webrat 0.7.0 → 0.7.1
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/Gemfile +0 -6
- data/History.txt +17 -0
- data/Rakefile +7 -9
- data/lib/webrat.rb +1 -1
- data/lib/webrat/adapters/mechanize.rb +22 -6
- data/lib/webrat/adapters/rack.rb +4 -0
- data/lib/webrat/adapters/rails.rb +4 -0
- data/lib/webrat/core/configuration.rb +16 -1
- data/lib/webrat/core/elements/field.rb +40 -89
- data/lib/webrat/core/elements/form.rb +55 -31
- data/lib/webrat/core/locators/form_locator.rb +1 -1
- data/lib/webrat/core/matchers/have_xpath.rb +4 -2
- data/lib/webrat/core/methods.rb +1 -1
- data/lib/webrat/core/mime.rb +2 -2
- data/lib/webrat/core/scope.rb +1 -0
- data/lib/webrat/core/session.rb +4 -3
- data/lib/webrat/core_extensions/{nil_to_param.rb → nil_to_query_string.rb} +1 -1
- data/lib/webrat/selenium/location_strategy_javascript/label.js +9 -3
- data/lib/webrat/selenium/selenium_rc_server.rb +4 -1
- data/lib/webrat/selenium/selenium_session.rb +9 -4
- data/spec/fakes/test_adapter.rb +1 -1
- data/spec/integration/mechanize/sample_app.rb +16 -1
- data/spec/integration/mechanize/spec/mechanize_spec.rb +9 -1
- data/spec/integration/rack/app.rb +2 -2
- data/spec/integration/rack/test/helper.rb +0 -1
- data/spec/integration/rack/test/webrat_rack_test.rb +3 -2
- data/spec/integration/sinatra/classic_app.rb +0 -1
- data/spec/integration/sinatra/modular_app.rb +0 -1
- data/spec/integration/sinatra/test/classic_app_test.rb +1 -0
- data/spec/integration/sinatra/test/test_helper.rb +0 -1
- data/spec/private/core/field_spec.rb +1 -1
- data/spec/private/core/form_spec.rb +51 -0
- data/spec/private/core/session_spec.rb +5 -18
- data/spec/private/mechanize/mechanize_adapter_spec.rb +24 -1
- data/spec/private/rails/attaches_file_spec.rb +33 -0
- data/spec/public/matchers/have_xpath_spec.rb +6 -0
- data/spec/public/submit_form_spec.rb +52 -1
- data/spec/spec_helper.rb +0 -1
- data/webrat.gemspec +6 -4
- metadata +38 -18
@@ -38,15 +38,24 @@ module Webrat
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
# iterate over all form fields to build a request querystring to get params from it,
|
42
|
+
# for file_field we made a work around to pass a digest as value to later replace it
|
43
|
+
# in params hash with the real file.
|
41
44
|
def params
|
42
|
-
|
45
|
+
query_string = []
|
46
|
+
replaces = {}
|
43
47
|
|
44
48
|
fields.each do |field|
|
45
|
-
next if field.
|
46
|
-
merge(
|
49
|
+
next if field.to_query_string.nil?
|
50
|
+
replaces.merge!({field.digest_value => field.test_uploaded_file}) if field.is_a?(FileField)
|
51
|
+
query_string << field.to_query_string
|
47
52
|
end
|
48
53
|
|
49
|
-
|
54
|
+
query_params = self.class.query_string_to_params(query_string.join('&'))
|
55
|
+
|
56
|
+
query_params = self.class.replace_params_values(query_params, replaces)
|
57
|
+
|
58
|
+
self.class.unescape_params(query_params)
|
50
59
|
end
|
51
60
|
|
52
61
|
def form_method
|
@@ -57,47 +66,62 @@ module Webrat
|
|
57
66
|
@element["action"].blank? ? @session.current_url : @element["action"]
|
58
67
|
end
|
59
68
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
69
|
+
def self.replace_param_value(params, oval, nval)
|
70
|
+
output = Hash.new
|
71
|
+
params.each do |key, value|
|
72
|
+
case value
|
73
|
+
when Hash
|
74
|
+
value = replace_param_value(value, oval, nval)
|
65
75
|
when Array
|
66
|
-
|
67
|
-
|
68
|
-
|
76
|
+
value = value.map { |o| o == oval ? nval : ( o.is_a?(Hash) ? replace_param_value(o, oval, nval) : o) }
|
77
|
+
when oval
|
78
|
+
value = nval
|
69
79
|
end
|
80
|
+
output[key] = value
|
70
81
|
end
|
82
|
+
output
|
71
83
|
end
|
72
84
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
case [a[k], b[k]].map{|value| value.class}
|
77
|
-
when *hash_classes.zip(hash_classes)
|
78
|
-
a[k] = merge_hash_values(a[k], b[k])
|
79
|
-
b.delete(k)
|
80
|
-
when [Array, Array]
|
81
|
-
a[k] += b[k]
|
82
|
-
b.delete(k)
|
83
|
-
end
|
84
|
-
end
|
85
|
+
def self.replace_params_values(params, values)
|
86
|
+
values.each do |key, value|
|
87
|
+
params = replace_param_value(params, key, value)
|
85
88
|
end
|
86
|
-
|
89
|
+
params
|
87
90
|
end
|
88
91
|
|
89
|
-
def
|
90
|
-
|
92
|
+
def self.unescape_params(params)
|
93
|
+
case params.class.name
|
94
|
+
when 'Hash', 'Mash'
|
95
|
+
params.each { |key,value| params[key] = unescape_params(value) }
|
96
|
+
params
|
97
|
+
when 'Array'
|
98
|
+
params.collect { |value| unescape_params(value) }
|
99
|
+
else
|
100
|
+
params.is_a?(String) ? CGI.unescapeHTML(params) : params
|
101
|
+
end
|
102
|
+
end
|
91
103
|
|
104
|
+
def self.query_string_to_params(query_string)
|
92
105
|
case Webrat.configuration.mode
|
93
106
|
when :rails
|
94
|
-
|
107
|
+
parse_rails_request_params(query_string)
|
95
108
|
when :merb
|
96
|
-
|
109
|
+
::Merb::Parse.query(query_string)
|
110
|
+
when :rack, :sinatra
|
111
|
+
Rack::Utils.parse_nested_query(query_string)
|
112
|
+
else
|
113
|
+
query_string.split('&').map {|query| { query.split('=').first => query.split('=').last }}
|
97
114
|
end
|
98
|
-
|
99
|
-
klasses
|
100
115
|
end
|
101
116
|
|
117
|
+
def self.parse_rails_request_params(query_string)
|
118
|
+
if defined?(ActionController::AbstractRequest)
|
119
|
+
ActionController::AbstractRequest.parse_query_parameters(query_string)
|
120
|
+
elsif defined?(ActionController::UrlEncodedPairParser)
|
121
|
+
ActionController::UrlEncodedPairParser.parse_query_parameters(query_string)
|
122
|
+
else
|
123
|
+
Rack::Utils.parse_nested_query(query_string)
|
124
|
+
end
|
125
|
+
end
|
102
126
|
end
|
103
127
|
end
|
@@ -14,10 +14,12 @@ module Webrat
|
|
14
14
|
@block ||= block
|
15
15
|
matched = matches(stringlike)
|
16
16
|
|
17
|
+
@block.call(matched) if @block
|
18
|
+
|
17
19
|
if @options[:count]
|
18
|
-
matched.size == @options[:count].to_i
|
20
|
+
matched.size == @options[:count].to_i
|
19
21
|
else
|
20
|
-
matched.any?
|
22
|
+
matched.any?
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
data/lib/webrat/core/methods.rb
CHANGED
data/lib/webrat/core/mime.rb
CHANGED
@@ -8,8 +8,8 @@ module Webrat #:nodoc:
|
|
8
8
|
def mime_type(type)
|
9
9
|
return type if type.nil? || type.to_s.include?("/")
|
10
10
|
type = ".#{type}" unless type.to_s[0] == ?.
|
11
|
-
MIME_TYPES.fetch(type) { |
|
12
|
-
raise ArgumentError.new("Invalid Mime type: #{
|
11
|
+
MIME_TYPES.fetch(type) { |invalid_type|
|
12
|
+
raise ArgumentError.new("Invalid Mime type: #{invalid_type}")
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
data/lib/webrat/core/scope.rb
CHANGED
data/lib/webrat/core/session.rb
CHANGED
@@ -65,7 +65,7 @@ For example:
|
|
65
65
|
attr_reader :current_url
|
66
66
|
attr_reader :elements
|
67
67
|
|
68
|
-
def_delegators :@adapter, :response, :response_code, :response_body,
|
68
|
+
def_delegators :@adapter, :response, :response_code, :response_body, :response_headers,
|
69
69
|
:response_body=, :response_code=,
|
70
70
|
:get, :post, :put, :delete
|
71
71
|
|
@@ -75,6 +75,7 @@ For example:
|
|
75
75
|
@data = {}
|
76
76
|
@default_headers = {}
|
77
77
|
@custom_headers = {}
|
78
|
+
@current_url = nil
|
78
79
|
reset
|
79
80
|
end
|
80
81
|
|
@@ -155,7 +156,7 @@ For example:
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def redirect? #:nodoc:
|
158
|
-
(response_code
|
159
|
+
[301, 302, 303, 307].include?(response_code)
|
159
160
|
end
|
160
161
|
|
161
162
|
def internal_redirect?
|
@@ -281,7 +282,7 @@ For example:
|
|
281
282
|
end
|
282
283
|
|
283
284
|
def response_location
|
284
|
-
|
285
|
+
response_headers['Location']
|
285
286
|
end
|
286
287
|
|
287
288
|
def current_host
|
@@ -10,7 +10,7 @@ RegExp.escape = function(text) {
|
|
10
10
|
);
|
11
11
|
}
|
12
12
|
return text.replace(arguments.callee.sRE, '\\$1');
|
13
|
-
}
|
13
|
+
};
|
14
14
|
|
15
15
|
var allLabels = inDocument.getElementsByTagName("label");
|
16
16
|
var regExp = new RegExp('^\\W*' + RegExp.escape(locator) + '(\\b|$)', 'i');
|
@@ -21,7 +21,7 @@ var candidateLabels = $A(allLabels).select(function(candidateLabel){
|
|
21
21
|
});
|
22
22
|
|
23
23
|
if (candidateLabels.length == 0) {
|
24
|
-
return null;
|
24
|
+
return null;
|
25
25
|
}
|
26
26
|
|
27
27
|
//reverse length sort
|
@@ -30,7 +30,13 @@ candidateLabels = candidateLabels.sortBy(function(s) {
|
|
30
30
|
});
|
31
31
|
|
32
32
|
var locatedLabel = candidateLabels.first();
|
33
|
-
var labelFor =
|
33
|
+
var labelFor = null;
|
34
|
+
|
35
|
+
if (locatedLabel.getAttribute('for')) {
|
36
|
+
labelFor = locatedLabel.getAttribute('for');
|
37
|
+
} else if (locatedLabel.attributes['for']) { // IE
|
38
|
+
labelFor = locatedLabel.attributes['for'].nodeValue;
|
39
|
+
}
|
34
40
|
|
35
41
|
if ((labelFor == null) && (locatedLabel.hasChildNodes())) {
|
36
42
|
return locatedLabel.getElementsByTagName('button')[0]
|
@@ -31,10 +31,13 @@ module Webrat
|
|
31
31
|
|
32
32
|
def remote_control
|
33
33
|
return @remote_control if @remote_control
|
34
|
+
server_options = { :timeout => Webrat.configuration.selenium_browser_startup_timeout }
|
35
|
+
server_options[:firefox_profile] = Webrat.configuration.selenium_firefox_profile if Webrat.configuration.selenium_firefox_profile
|
34
36
|
|
35
37
|
@remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
|
36
38
|
Webrat.configuration.selenium_server_port,
|
37
|
-
|
39
|
+
server_options)
|
40
|
+
|
38
41
|
@remote_control.jar_file = jar_path
|
39
42
|
|
40
43
|
return @remote_control
|
@@ -3,7 +3,12 @@ require "webrat/selenium/selenium_rc_server"
|
|
3
3
|
require "webrat/selenium/application_server_factory"
|
4
4
|
require "webrat/selenium/application_servers/base"
|
5
5
|
|
6
|
-
|
6
|
+
begin
|
7
|
+
require "selenium"
|
8
|
+
rescue LoadError => e
|
9
|
+
e.message << " (You may need to install the selenium-rc gem)"
|
10
|
+
raise e
|
11
|
+
end
|
7
12
|
|
8
13
|
module Webrat
|
9
14
|
class TimeoutError < WebratError
|
@@ -170,8 +175,8 @@ module Webrat
|
|
170
175
|
end
|
171
176
|
|
172
177
|
error_message = "#{message} (after #{timeout} sec)"
|
173
|
-
|
174
|
-
if $browser
|
178
|
+
|
179
|
+
if $browser && Webrat.configuration.selenium_verbose_output
|
175
180
|
error_message += <<-EOS
|
176
181
|
|
177
182
|
|
@@ -232,7 +237,7 @@ EOS
|
|
232
237
|
|
233
238
|
def create_browser
|
234
239
|
$browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
|
235
|
-
Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.
|
240
|
+
Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port_for_selenium}")
|
236
241
|
$browser.set_speed(0) unless Webrat.configuration.selenium_server_address
|
237
242
|
|
238
243
|
at_exit do
|
data/spec/fakes/test_adapter.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require "rubygems"
|
2
1
|
require "sinatra/base"
|
3
2
|
|
4
3
|
class SampleApp < Sinatra::Default
|
@@ -17,4 +16,20 @@ class SampleApp < Sinatra::Default
|
|
17
16
|
get "/redirected" do
|
18
17
|
"Redirected"
|
19
18
|
end
|
19
|
+
|
20
|
+
get "/form" do
|
21
|
+
<<-EOS
|
22
|
+
<html>
|
23
|
+
<form action="/form" method="post">
|
24
|
+
<input type="hidden" name="_method" value="put" />
|
25
|
+
<label for="email">Email:</label> <input type="text" id="email" name="email" /></label>
|
26
|
+
<input type="submit" value="Add" />
|
27
|
+
</form>
|
28
|
+
</html>
|
29
|
+
EOS
|
30
|
+
end
|
31
|
+
|
32
|
+
put "/form" do
|
33
|
+
"Welcome #{params[:email]}"
|
34
|
+
end
|
20
35
|
end
|
@@ -12,7 +12,15 @@ describe "Webrat's Mechanize mode" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should follow links"
|
15
|
-
|
15
|
+
|
16
|
+
it "should submit forms" do
|
17
|
+
visit "http://localhost:9292/form"
|
18
|
+
fill_in "Email", :with => "albert@example.com"
|
19
|
+
response = click_button "Add"
|
20
|
+
|
21
|
+
response.should contain("Welcome albert@example.com")
|
22
|
+
end
|
23
|
+
|
16
24
|
it "should not follow external redirects" do
|
17
25
|
pending do
|
18
26
|
response = visit("http://localhost:9292/external_redirect")
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require "rubygems"
|
2
1
|
require "sinatra/base"
|
3
2
|
|
4
3
|
class RackApp < Sinatra::Base
|
@@ -39,7 +38,8 @@ class RackApp < Sinatra::Base
|
|
39
38
|
end
|
40
39
|
|
41
40
|
post "/upload" do
|
42
|
-
params[:uploaded_file]
|
41
|
+
uploaded_file = params[:uploaded_file]
|
42
|
+
Marshal.dump(:tempfile => uploaded_file[:tempfile].read, :type => uploaded_file[:type], :filename => uploaded_file[:filename])
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "rubygems"
|
1
2
|
require File.dirname(__FILE__) + "/helper"
|
2
3
|
|
3
4
|
class WebratRackTest < Test::Unit::TestCase
|
@@ -52,10 +53,10 @@ class WebratRackTest < Test::Unit::TestCase
|
|
52
53
|
attach_file "File", __FILE__, "text/ruby"
|
53
54
|
click_button "Upload"
|
54
55
|
|
55
|
-
upload =
|
56
|
+
upload = Marshal.load(response_body)
|
56
57
|
assert_equal "text/ruby", upload[:type]
|
57
58
|
assert_equal "webrat_rack_test.rb", upload[:filename]
|
58
|
-
|
59
|
+
assert_equal File.read(__FILE__), upload[:tempfile]
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -77,7 +77,7 @@ module Webrat
|
|
77
77
|
|
78
78
|
element = Webrat::XML.document(html).css('input').first
|
79
79
|
text_field = TextField.new(nil, element)
|
80
|
-
text_field.
|
80
|
+
text_field.to_query_string.should == 'email=user@example.com'
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe "Multiple nested params" do
|
4
|
+
it "should be corretly posted" do
|
5
|
+
Webrat.configuration.mode = :rails
|
6
|
+
|
7
|
+
with_html <<-HTML
|
8
|
+
<html>
|
9
|
+
<form method="post" action="/family">
|
10
|
+
<div class="couple">
|
11
|
+
<div class="parent">
|
12
|
+
<select name="user[family][parents][0][][gender]">
|
13
|
+
<option selected="selected" value="Mother">Mother</option>
|
14
|
+
<option value="Father">Father</option>
|
15
|
+
</select>
|
16
|
+
<input type="text" value="Alice" name="user[family][parents][0][][name]" />
|
17
|
+
</div>
|
18
|
+
<div class="parent">
|
19
|
+
<select name="user[family][parents][0][][gender]">
|
20
|
+
<option value="Mother">Mother</option>
|
21
|
+
<option selected="selected" value="Father">Father</option>
|
22
|
+
</select>
|
23
|
+
<input type="text" value="Michael" name="user[family][parents][0][][name]" />
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<div class="couple">
|
27
|
+
<div class="parent">
|
28
|
+
<select name="user[family][parents][1][][gender]">
|
29
|
+
<option selected="selected" value="Mother">Mother</option>
|
30
|
+
<option value="Father">Father</option>
|
31
|
+
</select>
|
32
|
+
<input type="text" value="Jenny" name="user[family][parents][1][][name]" />
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
<input type="submit" />
|
36
|
+
</form>
|
37
|
+
</html>
|
38
|
+
HTML
|
39
|
+
|
40
|
+
params = { "user" => { "family" => { "parents" => {
|
41
|
+
"0" => [ {"name" => "Alice", "gender"=>"Mother"}, {"name" => "Michael", "gender"=>"Father"} ],
|
42
|
+
"1" => [ {"name" => "Jenny", "gender"=>"Mother"} ]
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
webrat_session.should_receive(:post).with("/family", params)
|
49
|
+
click_button
|
50
|
+
end
|
51
|
+
end
|