capybara 0.4.1.rc → 0.4.1.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/History.txt +3 -1
- data/lib/capybara.rb +1 -1
- data/lib/capybara/driver/rack_test_driver.rb +43 -32
- data/lib/capybara/node/matchers.rb +9 -7
- data/lib/capybara/spec/session.rb +11 -4
- data/lib/capybara/spec/session/has_link_spec.rb +4 -0
- data/lib/capybara/spec/session/headers.rb +2 -2
- data/lib/capybara/spec/test_app.rb +4 -0
- data/lib/capybara/spec/views/form.erb +18 -6
- data/lib/capybara/util/save_and_open_page.rb +2 -1
- data/lib/capybara/version.rb +1 -1
- data/spec/driver/rack_test_driver_spec.rb +28 -0
- metadata +9 -11
data/History.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Version 0.4.1
|
2
2
|
|
3
|
-
Release date:
|
3
|
+
Release date: 2011-01-21
|
4
4
|
|
5
5
|
### Added
|
6
6
|
|
@@ -32,6 +32,8 @@ Release date:
|
|
32
32
|
* Fix problems with multiple file inputs [Philip Arndt]
|
33
33
|
* Submit multipart forms as multipart under rack-test even if they contain no files [Ryan Kinderman]
|
34
34
|
* Matchers like has_select? and has_checked_field? now work with dynamically changed values [John Firebaugh]
|
35
|
+
* Preserve order of rack params [Joel Chippindale]
|
36
|
+
* RackTest#reset! is more thorough [Joel Chippindale]
|
35
37
|
|
36
38
|
# Version 0.4.0
|
37
39
|
|
data/lib/capybara.rb
CHANGED
@@ -73,7 +73,7 @@ module Capybara
|
|
73
73
|
# xpath { |num| ".//tbody/tr[#{num}]" }
|
74
74
|
# end
|
75
75
|
#
|
76
|
-
# This makes it possible to use this selector in a
|
76
|
+
# This makes it possible to use this selector in a variety of ways:
|
77
77
|
#
|
78
78
|
# find(:row, 3)
|
79
79
|
# page.find('table#myTable').find(:row, 3).text
|
@@ -123,39 +123,43 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
123
123
|
def params(button)
|
124
124
|
params = {}
|
125
125
|
|
126
|
-
native.xpath(".//input[not(@disabled)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
merge_param!(params, select['name'].to_s, (option['value'] || option.text).to_s) if option
|
145
|
-
end
|
146
|
-
end
|
147
|
-
native.xpath(".//input[not(@disabled) and @type='file']").map do |input|
|
148
|
-
if multipart?
|
149
|
-
file = \
|
150
|
-
if (value = input['value']).to_s.empty?
|
151
|
-
NilUploadedFile.new
|
126
|
+
native.xpath("(.//input|.//select|.//textarea)[not(@disabled)]").map do |field|
|
127
|
+
case field.name
|
128
|
+
when 'input'
|
129
|
+
if %w(radio checkbox).include? field['type']
|
130
|
+
merge_param!(params, field['name'].to_s, field['value'].to_s) if field['checked']
|
131
|
+
elsif %w(submit image).include? field['type']
|
132
|
+
# TO DO identify the click button here (in document order, rather
|
133
|
+
# than leaving until the end of the params)
|
134
|
+
elsif field['type'] =='file'
|
135
|
+
if multipart?
|
136
|
+
file = \
|
137
|
+
if (value = field['value']).to_s.empty?
|
138
|
+
NilUploadedFile.new
|
139
|
+
else
|
140
|
+
content_type = MIME::Types.type_for(value).first.to_s
|
141
|
+
Rack::Test::UploadedFile.new(value, content_type)
|
142
|
+
end
|
143
|
+
merge_param!(params, field['name'].to_s, file)
|
152
144
|
else
|
153
|
-
|
154
|
-
Rack::Test::UploadedFile.new(value, content_type)
|
145
|
+
merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s))
|
155
146
|
end
|
156
|
-
|
157
|
-
|
158
|
-
|
147
|
+
else
|
148
|
+
merge_param!(params, field['name'].to_s, field['value'].to_s)
|
149
|
+
end
|
150
|
+
when 'select'
|
151
|
+
if field['multiple'] == 'multiple'
|
152
|
+
options = field.xpath(".//option[@selected]")
|
153
|
+
options.each do |option|
|
154
|
+
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s)
|
155
|
+
end
|
156
|
+
else
|
157
|
+
option = field.xpath(".//option[@selected]").first
|
158
|
+
option ||= field.xpath('.//option').first
|
159
|
+
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
|
160
|
+
end
|
161
|
+
when 'textarea'
|
162
|
+
merge_param!(params, field['name'].to_s, field.text.to_s)
|
159
163
|
end
|
160
164
|
end
|
161
165
|
merge_param!(params, button[:name], button[:value] || "") if button[:name]
|
@@ -249,7 +253,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
249
253
|
alias_method :source, :body
|
250
254
|
|
251
255
|
def reset!
|
252
|
-
|
256
|
+
clear_rack_mock_session
|
253
257
|
end
|
254
258
|
|
255
259
|
def get(*args, &block); reset_cache; super; end
|
@@ -275,6 +279,13 @@ private
|
|
275
279
|
Rack::MockSession.new(app, Capybara.default_host || "www.example.com")
|
276
280
|
end
|
277
281
|
|
282
|
+
# Rack::Test::Methods does not provide methods for manipulating the session
|
283
|
+
# list so these must be manipulated directly.
|
284
|
+
def clear_rack_mock_session
|
285
|
+
@_rack_test_sessions = nil
|
286
|
+
@_rack_mock_sessions = nil
|
287
|
+
end
|
288
|
+
|
278
289
|
def request_path
|
279
290
|
request.path rescue ""
|
280
291
|
end
|
@@ -201,11 +201,13 @@ module Capybara
|
|
201
201
|
# Checks if the page or current node has a link with the given
|
202
202
|
# text or id.
|
203
203
|
#
|
204
|
-
# @param [String] locator
|
205
|
-
# @
|
204
|
+
# @param [String] locator The text or id of a link to check for
|
205
|
+
# @param options
|
206
|
+
# @option options [String] :href The value the href attribute must be
|
207
|
+
# @return [Boolean] Whether it exists
|
206
208
|
#
|
207
|
-
def has_link?(locator)
|
208
|
-
has_xpath?(XPath::HTML.link(locator))
|
209
|
+
def has_link?(locator, options={})
|
210
|
+
has_xpath?(XPath::HTML.link(locator, options))
|
209
211
|
end
|
210
212
|
|
211
213
|
##
|
@@ -213,11 +215,11 @@ module Capybara
|
|
213
215
|
# Checks if the page or current node has no link with the given
|
214
216
|
# text or id.
|
215
217
|
#
|
216
|
-
# @param
|
218
|
+
# @param (see Capybara::Node::Finders#has_link?)
|
217
219
|
# @return [Boolean] Whether it doesn't exist
|
218
220
|
#
|
219
|
-
def has_no_link?(locator)
|
220
|
-
has_no_xpath?(XPath::HTML.link(locator))
|
221
|
+
def has_no_link?(locator, options={})
|
222
|
+
has_no_xpath?(XPath::HTML.link(locator, options))
|
221
223
|
end
|
222
224
|
|
223
225
|
##
|
@@ -75,18 +75,25 @@ shared_examples_for "session" do
|
|
75
75
|
@session.visit('/form')
|
76
76
|
@session.fill_in('address1_city', :with =>'Paris')
|
77
77
|
@session.fill_in('address1_street', :with =>'CDG')
|
78
|
+
@session.fill_in('address1_street', :with =>'CDG')
|
79
|
+
@session.select("France", :from => 'address1_country')
|
80
|
+
|
78
81
|
@session.fill_in('address2_city', :with => 'Mikolaiv')
|
79
82
|
@session.fill_in('address2_street', :with => 'PGS')
|
83
|
+
@session.select("Ukraine", :from => 'address2_country')
|
84
|
+
|
80
85
|
@session.click_button "awesome"
|
81
86
|
|
82
87
|
addresses=extract_results(@session)["addresses"]
|
83
88
|
addresses.should have(2).addresses
|
84
89
|
|
85
|
-
addresses[0]["street"].should
|
86
|
-
addresses[0]["city"].should
|
90
|
+
addresses[0]["street"].should == 'CDG'
|
91
|
+
addresses[0]["city"].should == 'Paris'
|
92
|
+
addresses[0]["country"].should == 'France'
|
87
93
|
|
88
|
-
addresses[1]["street"].should
|
89
|
-
addresses[1]["city"].should
|
94
|
+
addresses[1]["street"].should == 'PGS'
|
95
|
+
addresses[1]["city"].should == 'Mikolaiv'
|
96
|
+
addresses[1]["country"].should == 'Ukraine'
|
90
97
|
end
|
91
98
|
|
92
99
|
end
|
@@ -8,10 +8,12 @@ shared_examples_for "has_link" do
|
|
8
8
|
it "should be true if the given link is on the page" do
|
9
9
|
@session.should have_link('foo')
|
10
10
|
@session.should have_link('awesome title')
|
11
|
+
@session.should have_link('A link', :href => '/with_simple_html')
|
11
12
|
end
|
12
13
|
|
13
14
|
it "should be false if the given link is not on the page" do
|
14
15
|
@session.should_not have_link('monkey')
|
16
|
+
@session.should_not have_link('A link', :href => '/non-existant-href')
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
@@ -23,10 +25,12 @@ shared_examples_for "has_link" do
|
|
23
25
|
it "should be false if the given link is on the page" do
|
24
26
|
@session.should_not have_no_link('foo')
|
25
27
|
@session.should_not have_no_link('awesome title')
|
28
|
+
@session.should_not have_no_link('A link', :href => '/with_simple_html')
|
26
29
|
end
|
27
30
|
|
28
31
|
it "should be true if the given link is not on the page" do
|
29
32
|
@session.should have_no_link('monkey')
|
33
|
+
@session.should have_no_link('A link', :href => '/non-existant-href')
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
shared_examples_for "session with headers support" do
|
2
2
|
describe '#response_headers' do
|
3
3
|
it "should return response headers" do
|
4
|
-
@session.visit('/with_simple_html')
|
5
|
-
@session.response_headers['Content-Type'].should
|
4
|
+
@session.visit('/with_simple_html')
|
5
|
+
@session.response_headers['Content-Type'].should =~ %r(text/html)
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
@@ -163,18 +163,30 @@
|
|
163
163
|
<span>First address<span>
|
164
164
|
<label for='address1_street'>Street</label>
|
165
165
|
<input type="text" name="form[addresses][][street]" value="" id="address1_street">
|
166
|
-
|
166
|
+
|
167
167
|
<label for='address1_city'>City</label>
|
168
|
-
<input type="text" name="form[addresses][][city]" value="" id="address1_city">
|
169
|
-
|
168
|
+
<input type="text" name="form[addresses][][city]" value="" id="address1_city">
|
169
|
+
|
170
|
+
<label for='address1_country'>Country</label>
|
171
|
+
<select name="form[addresses][][country]" id="address1_country">
|
172
|
+
<option>France</option>
|
173
|
+
<option>Ukraine</option>
|
174
|
+
</select>
|
175
|
+
</p>
|
170
176
|
|
171
|
-
<p>
|
177
|
+
<p>
|
172
178
|
<span>Second address<span>
|
173
179
|
<label for='address2_street'>Street</label>
|
174
180
|
<input type="text" name="form[addresses][][street]" value="" id="address2_street">
|
175
|
-
|
181
|
+
|
176
182
|
<label for='address2_city'>City</label>
|
177
183
|
<input type="text" name="form[addresses][][city]" value="" id="address2_city">
|
184
|
+
|
185
|
+
<label for='address2_country'>Country</label>
|
186
|
+
<select name="form[addresses][][country]" id="address2_country">
|
187
|
+
<option>France</option>
|
188
|
+
<option>Ukraine</option>
|
189
|
+
</select>
|
178
190
|
</p>
|
179
191
|
|
180
192
|
<div style="display:none;">
|
@@ -207,7 +219,7 @@
|
|
207
219
|
|
208
220
|
<p>
|
209
221
|
<label for="form_disabled_radio">
|
210
|
-
Disabled
|
222
|
+
Disabled Radio
|
211
223
|
<input type="radio" name="form[disabled_radio]" value="Should not see me" id="form_disabled_radio" checked="checked" disabled="disabled" />
|
212
224
|
</label>
|
213
225
|
</p>
|
@@ -21,7 +21,8 @@ module Capybara
|
|
21
21
|
require "launchy"
|
22
22
|
Launchy::Browser.run(path)
|
23
23
|
rescue LoadError
|
24
|
-
warn "Sorry, you need to install launchy
|
24
|
+
warn "Sorry, you need to install launchy (`gem install launchy`) and " <<
|
25
|
+
"make sure it's available to open pages with `save_and_open_page`."
|
25
26
|
end
|
26
27
|
|
27
28
|
def rewrite_css_and_image_references(response_html) # :nodoc:
|
data/lib/capybara/version.rb
CHANGED
@@ -53,4 +53,32 @@ describe Capybara::Driver::RackTest do
|
|
53
53
|
it_should_behave_like "driver with status code support"
|
54
54
|
it_should_behave_like "driver with cookies support"
|
55
55
|
it_should_behave_like "driver with infinite redirect detection"
|
56
|
+
|
57
|
+
describe '#reset!' do
|
58
|
+
it { @driver.visit('/foo'); lambda { @driver.reset! }.should change(@driver, :current_url).to('') }
|
59
|
+
|
60
|
+
it 'should reset headers' do
|
61
|
+
@driver.header('FOO', 'BAR')
|
62
|
+
@driver.visit('/get_header')
|
63
|
+
@driver.body.should include('BAR')
|
64
|
+
|
65
|
+
@driver.reset!
|
66
|
+
@driver.visit('/get_header')
|
67
|
+
@driver.body.should_not include('BAR')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should reset response' do
|
71
|
+
@driver.visit('/foo')
|
72
|
+
lambda { @driver.response }.should_not raise_error
|
73
|
+
@driver.reset!
|
74
|
+
lambda { @driver.response }.should raise_error
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should request response' do
|
78
|
+
@driver.visit('/foo')
|
79
|
+
lambda { @driver.request }.should_not raise_error
|
80
|
+
@driver.reset!
|
81
|
+
lambda { @driver.request }.should raise_error
|
82
|
+
end
|
83
|
+
end
|
56
84
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.4.1.
|
9
|
+
- 1
|
10
|
+
version: 0.4.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jonas Nicklas
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-21 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -125,8 +125,8 @@ dependencies:
|
|
125
125
|
segments:
|
126
126
|
- 0
|
127
127
|
- 1
|
128
|
-
-
|
129
|
-
version: 0.1.
|
128
|
+
- 3
|
129
|
+
version: 0.1.3
|
130
130
|
type: :runtime
|
131
131
|
version_requirements: *id008
|
132
132
|
- !ruby/object:Gem::Dependency
|
@@ -327,13 +327,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
327
327
|
version: "0"
|
328
328
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
329
329
|
requirements:
|
330
|
-
- - "
|
330
|
+
- - ">="
|
331
331
|
- !ruby/object:Gem::Version
|
332
332
|
segments:
|
333
|
-
-
|
334
|
-
|
335
|
-
- 1
|
336
|
-
version: 1.3.1
|
333
|
+
- 0
|
334
|
+
version: "0"
|
337
335
|
requirements: []
|
338
336
|
|
339
337
|
rubyforge_project: capybara
|