capybara 3.14.0 → 3.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +13 -0
- data/README.md +2 -1
- data/lib/capybara/node/actions.rb +37 -6
- data/lib/capybara/node/matchers.rb +10 -2
- data/lib/capybara/selector.rb +117 -1
- data/lib/capybara/selector/selector.rb +7 -0
- data/lib/capybara/selector/xpath_extensions.rb +9 -0
- data/lib/capybara/selenium/driver.rb +13 -2
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +15 -0
- data/lib/capybara/selenium/extensions/find.rb +2 -1
- data/lib/capybara/selenium/node.rb +1 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/selenium/nodes/safari_node.rb +145 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +46 -27
- data/lib/capybara/spec/session/click_button_spec.rb +65 -60
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
- data/lib/capybara/spec/session/fill_in_spec.rb +3 -3
- data/lib/capybara/spec/session/find_spec.rb +5 -0
- data/lib/capybara/spec/session/has_table_spec.rb +120 -0
- data/lib/capybara/spec/session/node_spec.rb +3 -3
- data/lib/capybara/spec/session/reset_session_spec.rb +8 -7
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/window_spec.rb +44 -48
- data/lib/capybara/spec/views/form.erb +5 -0
- data/lib/capybara/spec/views/tables.erb +67 -0
- data/lib/capybara/spec/views/with_html.erb +2 -2
- data/lib/capybara/spec/views/with_js.erb +1 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/capybara_spec.rb +4 -4
- data/spec/css_builder_spec.rb +2 -0
- data/spec/dsl_spec.rb +13 -17
- data/spec/rack_test_spec.rb +77 -85
- data/spec/rspec/features_spec.rb +2 -0
- data/spec/rspec/shared_spec_matchers.rb +34 -35
- data/spec/rspec_spec.rb +11 -13
- data/spec/selector_spec.rb +31 -0
- data/spec/selenium_spec_chrome.rb +25 -25
- data/spec/selenium_spec_firefox.rb +62 -35
- data/spec/selenium_spec_firefox_remote.rb +2 -0
- data/spec/selenium_spec_safari.rb +148 -0
- data/spec/server_spec.rb +40 -44
- data/spec/shared_selenium_session.rb +27 -21
- data/spec/spec_helper.rb +4 -0
- data/spec/xpath_builder_spec.rb +2 -0
- metadata +7 -3
@@ -94,6 +94,11 @@
|
|
94
94
|
<input type="file" name="form[image]" id="form_image"/>
|
95
95
|
</p>
|
96
96
|
|
97
|
+
<p>
|
98
|
+
<label for="form_hidden_image">Hidden Image</label>
|
99
|
+
<input type="file" name="form[hidden_image]" id="form_hidden_image" style="display: none"/>
|
100
|
+
</p>
|
101
|
+
|
97
102
|
<p>
|
98
103
|
<input type="hidden" name="form[token]" value="12345" id="form_token"/>
|
99
104
|
</p>
|
@@ -61,3 +61,70 @@
|
|
61
61
|
</tr>
|
62
62
|
</table>
|
63
63
|
</form>
|
64
|
+
|
65
|
+
<table>
|
66
|
+
<caption>Horizontal Headers</caption>
|
67
|
+
<thead>
|
68
|
+
<tr>
|
69
|
+
<th>First Name</th>
|
70
|
+
<th>Last Name</th>
|
71
|
+
<th>City</th>
|
72
|
+
</tr>
|
73
|
+
</thead>
|
74
|
+
<tbody>
|
75
|
+
<tr>
|
76
|
+
<td>Thomas</td>
|
77
|
+
<td>Walpole</td>
|
78
|
+
<td>Oceanside</td>
|
79
|
+
</tr>
|
80
|
+
<tr>
|
81
|
+
<td>Danilo</td>
|
82
|
+
<td>Wilkinson</td>
|
83
|
+
<td>Johnsonville</td>
|
84
|
+
</tr>
|
85
|
+
<tr>
|
86
|
+
<td>Vern</td>
|
87
|
+
<td>Konopelski</td>
|
88
|
+
<td>Everette</td>
|
89
|
+
</tr>
|
90
|
+
<tr>
|
91
|
+
<td>Ratke</td>
|
92
|
+
<td>Lawrence</td>
|
93
|
+
<td>East Sorayashire</td>
|
94
|
+
</tr>
|
95
|
+
<tr>
|
96
|
+
<td>Palmer</td>
|
97
|
+
<td>Sawayn</td>
|
98
|
+
<td>West Trinidad</td>
|
99
|
+
</tr>
|
100
|
+
</tbody>
|
101
|
+
</table>
|
102
|
+
|
103
|
+
<table>
|
104
|
+
<caption>Vertical Headers</caption>
|
105
|
+
<tr>
|
106
|
+
<th>First Name</th>
|
107
|
+
<td>Thomas</td>
|
108
|
+
<td>Danilo</td>
|
109
|
+
<td>Vern</td>
|
110
|
+
<td>Ratke</td>
|
111
|
+
<td>Palmer</td>
|
112
|
+
</tr>
|
113
|
+
<tr>
|
114
|
+
<th>Last Name</th>
|
115
|
+
<td>Walpole</td>
|
116
|
+
<td>Wilkinson</td>
|
117
|
+
<td>Konopelski</td>
|
118
|
+
<td>Lawrence</td>
|
119
|
+
<td>Sawayn</td>
|
120
|
+
</tr>
|
121
|
+
<tr>
|
122
|
+
<th>City</th>
|
123
|
+
<td>Oceanside</td>
|
124
|
+
<td>Johnsonville</td>
|
125
|
+
<td>Everette</td>
|
126
|
+
<td>East Sorayashire</td>
|
127
|
+
<td>West Trinidad</td>
|
128
|
+
</tr>
|
129
|
+
</table>
|
130
|
+
|
@@ -21,9 +21,9 @@
|
|
21
21
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
22
22
|
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
|
23
23
|
et dolore magna aliqua. Ut enim ad minim veniam,
|
24
|
-
quis nostrud exercitation <a href="/foo" id="foo">ullamco</a> laboris nisi
|
24
|
+
quis nostrud exercitation <a href="/foo" id="foo" data-test-id="test-foo">ullamco</a> laboris nisi
|
25
25
|
ut aliquip ex ea commodo consequat.
|
26
|
-
<a href="/with_simple_html" aria-label="Go to simple"><img id="first_image" width="20" height="20" alt="awesome image" /></a>
|
26
|
+
<a href="/with_simple_html" aria-label="Go to simple" data-test-id="test-simple"><img id="first_image" width="20" height="20" alt="awesome image" src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="/></a>
|
27
27
|
</p>
|
28
28
|
|
29
29
|
<p class="para" id="second" style="display: inline;">
|
data/lib/capybara/version.rb
CHANGED
data/spec/capybara_spec.rb
CHANGED
@@ -4,12 +4,12 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
RSpec.describe Capybara do
|
6
6
|
describe 'default_max_wait_time' do
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
before { @previous_default_time = Capybara.default_max_wait_time }
|
8
|
+
|
9
|
+
after { Capybara.default_max_wait_time = @previous_default_time } # rubocop:disable RSpec/InstanceVariable
|
10
10
|
|
11
11
|
it 'should be changeable' do
|
12
|
-
|
12
|
+
expect(Capybara.default_max_wait_time).not_to eq(5)
|
13
13
|
Capybara.default_max_wait_time = 5
|
14
14
|
expect(Capybara.default_max_wait_time).to eq(5)
|
15
15
|
end
|
data/spec/css_builder_spec.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
+
# rubocop:disable RSpec/InstanceVariable
|
5
6
|
RSpec.describe Capybara::Selector::CSSBuilder do
|
6
7
|
let :builder do
|
7
8
|
::Capybara::Selector::CSSBuilder.new(@css)
|
@@ -97,3 +98,4 @@ RSpec.describe Capybara::Selector::CSSBuilder do
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
end
|
101
|
+
# rubocop:enable RSpec/InstanceVariable
|
data/spec/dsl_spec.rb
CHANGED
@@ -115,14 +115,11 @@ RSpec.describe Capybara::DSL do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
# rubocop:disable RSpec/InstanceVariable
|
118
119
|
describe '#using_wait_time' do
|
119
|
-
before
|
120
|
-
@previous_wait_time = Capybara.default_max_wait_time
|
121
|
-
end
|
120
|
+
before { @previous_wait_time = Capybara.default_max_wait_time }
|
122
121
|
|
123
|
-
after
|
124
|
-
Capybara.default_max_wait_time = @previous_wait_time
|
125
|
-
end
|
122
|
+
after { Capybara.default_max_wait_time = @previous_wait_time }
|
126
123
|
|
127
124
|
it 'should switch the wait time and switch it back' do
|
128
125
|
in_block = nil
|
@@ -142,6 +139,7 @@ RSpec.describe Capybara::DSL do
|
|
142
139
|
expect(Capybara.default_max_wait_time).to eq(@previous_wait_time)
|
143
140
|
end
|
144
141
|
end
|
142
|
+
# rubocop:enable RSpec/InstanceVariable
|
145
143
|
|
146
144
|
describe '#app' do
|
147
145
|
it 'should be changeable' do
|
@@ -249,31 +247,29 @@ RSpec.describe Capybara::DSL do
|
|
249
247
|
end
|
250
248
|
|
251
249
|
describe 'the DSL' do
|
252
|
-
|
253
|
-
@session = Class.new { include Capybara::DSL }.new
|
254
|
-
end
|
250
|
+
let(:session) { Class.new { include Capybara::DSL }.new }
|
255
251
|
|
256
252
|
it 'should be possible to include it in another class' do
|
257
|
-
|
258
|
-
|
259
|
-
expect(
|
253
|
+
session.visit('/with_html')
|
254
|
+
session.click_link('ullamco')
|
255
|
+
expect(session.body).to include('Another World')
|
260
256
|
end
|
261
257
|
|
262
258
|
it "should provide a 'page' shortcut for more expressive tests" do
|
263
|
-
|
264
|
-
|
265
|
-
expect(
|
259
|
+
session.page.visit('/with_html')
|
260
|
+
session.page.click_link('ullamco')
|
261
|
+
expect(session.page.body).to include('Another World')
|
266
262
|
end
|
267
263
|
|
268
264
|
it "should provide an 'using_session' shortcut" do
|
269
265
|
allow(Capybara).to receive(:using_session)
|
270
|
-
|
266
|
+
session.using_session(:name)
|
271
267
|
expect(Capybara).to have_received(:using_session).with(:name)
|
272
268
|
end
|
273
269
|
|
274
270
|
it "should provide a 'using_wait_time' shortcut" do
|
275
271
|
allow(Capybara).to receive(:using_wait_time)
|
276
|
-
|
272
|
+
session.using_wait_time(6)
|
277
273
|
expect(Capybara).to have_received(:using_wait_time).with(6)
|
278
274
|
end
|
279
275
|
end
|
data/spec/rack_test_spec.rb
CHANGED
@@ -37,55 +37,53 @@ end
|
|
37
37
|
|
38
38
|
RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
39
39
|
context 'with rack test driver' do
|
40
|
-
|
41
|
-
@session = TestSessions::RackTest
|
42
|
-
end
|
40
|
+
let(:session) { TestSessions::RackTest }
|
43
41
|
|
44
42
|
describe '#driver' do
|
45
43
|
it 'should be a rack test driver' do
|
46
|
-
expect(
|
44
|
+
expect(session.driver).to be_an_instance_of(Capybara::RackTest::Driver)
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
50
48
|
describe '#mode' do
|
51
49
|
it 'should remember the mode' do
|
52
|
-
expect(
|
50
|
+
expect(session.mode).to eq(:rack_test)
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
56
54
|
describe '#click_link' do
|
57
55
|
after do
|
58
|
-
|
56
|
+
session.driver.options[:respect_data_method] = false
|
59
57
|
end
|
60
58
|
|
61
59
|
it 'should use data-method if option is true' do
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
expect(
|
60
|
+
session.driver.options[:respect_data_method] = true
|
61
|
+
session.visit '/with_html'
|
62
|
+
session.click_link 'A link with data-method'
|
63
|
+
expect(session.html).to include('The requested object was deleted')
|
66
64
|
end
|
67
65
|
|
68
66
|
it 'should not use data-method if option is false' do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
expect(
|
67
|
+
session.driver.options[:respect_data_method] = false
|
68
|
+
session.visit '/with_html'
|
69
|
+
session.click_link 'A link with data-method'
|
70
|
+
expect(session.html).to include('Not deleted')
|
73
71
|
end
|
74
72
|
|
75
73
|
it "should use data-method if available even if it's capitalized" do
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
expect(
|
74
|
+
session.driver.options[:respect_data_method] = true
|
75
|
+
session.visit '/with_html'
|
76
|
+
session.click_link 'A link with capitalized data-method'
|
77
|
+
expect(session.html).to include('The requested object was deleted')
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
81
|
describe '#fill_in' do
|
84
82
|
it 'should warn that :fill_options are not supported' do
|
85
83
|
allow_any_instance_of(Capybara::RackTest::Node).to receive(:warn)
|
86
|
-
|
87
|
-
field =
|
88
|
-
expect(
|
84
|
+
session.visit '/with_html'
|
85
|
+
field = session.fill_in 'test_field', with: 'not_monkey', fill_options: { random: true }
|
86
|
+
expect(session).to have_field('test_field', with: 'not_monkey')
|
89
87
|
expect(field.base).to have_received(:warn).with("Options passed to Node#set but the RackTest driver doesn't support any - ignoring")
|
90
88
|
end
|
91
89
|
end
|
@@ -93,50 +91,50 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
|
93
91
|
describe '#attach_file' do
|
94
92
|
context 'with multipart form' do
|
95
93
|
it 'should submit an empty form-data section if no file is submitted' do
|
96
|
-
|
97
|
-
|
98
|
-
expect(
|
94
|
+
session.visit('/form')
|
95
|
+
session.click_button('Upload Empty')
|
96
|
+
expect(session.html).to include('Successfully ignored empty file field.')
|
99
97
|
end
|
100
98
|
end
|
101
99
|
|
102
100
|
it 'should not submit an obsolete mime type' do
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
expect(
|
101
|
+
test_jpg_file_path = File.expand_path('fixtures/capybara.csv', File.dirname(__FILE__))
|
102
|
+
session.visit('/form')
|
103
|
+
session.attach_file 'form_document', test_jpg_file_path
|
104
|
+
session.click_button('Upload Single')
|
105
|
+
expect(session).to have_content('Content-type: text/csv')
|
108
106
|
end
|
109
107
|
end
|
110
108
|
|
111
109
|
describe '#click' do
|
112
110
|
context 'on a label' do
|
113
111
|
it 'should toggle the associated checkbox' do
|
114
|
-
|
115
|
-
expect(
|
116
|
-
|
117
|
-
expect(
|
118
|
-
|
119
|
-
expect(
|
120
|
-
|
121
|
-
expect(
|
112
|
+
session.visit('/form')
|
113
|
+
expect(session).to have_unchecked_field('form_pets_cat')
|
114
|
+
session.find(:label, 'Cat').click
|
115
|
+
expect(session).to have_checked_field('form_pets_cat')
|
116
|
+
session.find(:label, 'Cat').click
|
117
|
+
expect(session).to have_unchecked_field('form_pets_cat')
|
118
|
+
session.find(:label, 'McLaren').click
|
119
|
+
expect(session).to have_checked_field('form_cars_mclaren', visible: :hidden)
|
122
120
|
end
|
123
121
|
|
124
122
|
it 'should toggle the associated radio' do
|
125
|
-
|
126
|
-
expect(
|
127
|
-
|
128
|
-
expect(
|
129
|
-
|
130
|
-
expect(
|
123
|
+
session.visit('/form')
|
124
|
+
expect(session).to have_unchecked_field('gender_male')
|
125
|
+
session.find(:label, 'Male').click
|
126
|
+
expect(session).to have_checked_field('gender_male')
|
127
|
+
session.find(:label, 'Female').click
|
128
|
+
expect(session).to have_unchecked_field('gender_male')
|
131
129
|
end
|
132
130
|
end
|
133
131
|
end
|
134
132
|
|
135
133
|
describe '#text' do
|
136
134
|
it 'should return original text content for textareas' do
|
137
|
-
|
138
|
-
|
139
|
-
normal =
|
135
|
+
session.visit('/with_html')
|
136
|
+
session.find_field('normal', type: 'textarea', with: 'banana').set('hello')
|
137
|
+
normal = session.find(:css, '#normal')
|
140
138
|
expect(normal.value).to eq 'hello'
|
141
139
|
expect(normal.text).to eq 'banana'
|
142
140
|
end
|
@@ -144,8 +142,8 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
|
144
142
|
|
145
143
|
describe '#style' do
|
146
144
|
it 'should raise an error' do
|
147
|
-
|
148
|
-
el =
|
145
|
+
session.visit('/with_html')
|
146
|
+
el = session.find(:css, '#first')
|
149
147
|
expect { el.style('display') }.to raise_error NotImplementedError, /not process CSS/
|
150
148
|
end
|
151
149
|
end
|
@@ -153,87 +151,81 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
|
153
151
|
end
|
154
152
|
|
155
153
|
RSpec.describe Capybara::RackTest::Driver do
|
156
|
-
|
157
|
-
@driver = TestSessions::RackTest.driver
|
158
|
-
end
|
154
|
+
let(:driver) { TestSessions::RackTest.driver }
|
159
155
|
|
160
156
|
describe ':headers option' do
|
161
157
|
it 'should always set headers' do
|
162
|
-
|
163
|
-
|
164
|
-
expect(
|
158
|
+
driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
|
159
|
+
driver.visit('/get_header')
|
160
|
+
expect(driver.html).to include('foobar')
|
165
161
|
end
|
166
162
|
|
167
163
|
it 'should keep headers on link clicks' do
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
expect(
|
164
|
+
driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
|
165
|
+
driver.visit('/header_links')
|
166
|
+
driver.find_xpath('.//a').first.click
|
167
|
+
expect(driver.html).to include('foobar')
|
172
168
|
end
|
173
169
|
|
174
170
|
it 'should keep headers on form submit' do
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
expect(
|
171
|
+
driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
|
172
|
+
driver.visit('/header_links')
|
173
|
+
driver.find_xpath('.//input').first.click
|
174
|
+
expect(driver.html).to include('foobar')
|
179
175
|
end
|
180
176
|
|
181
177
|
it 'should keep headers on redirects' do
|
182
|
-
|
183
|
-
|
184
|
-
expect(
|
178
|
+
driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
|
179
|
+
driver.visit('/get_header_via_redirect')
|
180
|
+
expect(driver.html).to include('foobar')
|
185
181
|
end
|
186
182
|
end
|
187
183
|
|
188
184
|
describe ':follow_redirects option' do
|
189
185
|
it 'defaults to following redirects' do
|
190
|
-
|
186
|
+
driver = Capybara::RackTest::Driver.new(TestApp)
|
191
187
|
|
192
|
-
|
193
|
-
expect(
|
194
|
-
expect(
|
188
|
+
driver.visit('/redirect')
|
189
|
+
expect(driver.response.header['Location']).to be_nil
|
190
|
+
expect(driver.current_url).to match %r{/landed$}
|
195
191
|
end
|
196
192
|
|
197
193
|
it 'is possible to not follow redirects' do
|
198
|
-
|
194
|
+
driver = Capybara::RackTest::Driver.new(TestApp, follow_redirects: false)
|
199
195
|
|
200
|
-
|
201
|
-
expect(
|
202
|
-
expect(
|
196
|
+
driver.visit('/redirect')
|
197
|
+
expect(driver.response.header['Location']).to match %r{/redirect_again$}
|
198
|
+
expect(driver.current_url).to match %r{/redirect$}
|
203
199
|
end
|
204
200
|
end
|
205
201
|
|
206
202
|
describe ':redirect_limit option' do
|
207
203
|
context 'with default redirect limit' do
|
208
|
-
|
209
|
-
@driver = Capybara::RackTest::Driver.new(TestApp)
|
210
|
-
end
|
204
|
+
let(:driver) { Capybara::RackTest::Driver.new(TestApp) }
|
211
205
|
|
212
206
|
it 'should follow 5 redirects' do
|
213
|
-
|
214
|
-
expect(
|
207
|
+
driver.visit('/redirect/5/times')
|
208
|
+
expect(driver.html).to include('redirection complete')
|
215
209
|
end
|
216
210
|
|
217
211
|
it 'should not follow more than 6 redirects' do
|
218
212
|
expect do
|
219
|
-
|
213
|
+
driver.visit('/redirect/6/times')
|
220
214
|
end.to raise_error(Capybara::InfiniteRedirectError)
|
221
215
|
end
|
222
216
|
end
|
223
217
|
|
224
218
|
context 'with 21 redirect limit' do
|
225
|
-
|
226
|
-
@driver = Capybara::RackTest::Driver.new(TestApp, redirect_limit: 21)
|
227
|
-
end
|
219
|
+
let(:driver) { Capybara::RackTest::Driver.new(TestApp, redirect_limit: 21) }
|
228
220
|
|
229
221
|
it 'should follow 21 redirects' do
|
230
|
-
|
231
|
-
expect(
|
222
|
+
driver.visit('/redirect/21/times')
|
223
|
+
expect(driver.html).to include('redirection complete')
|
232
224
|
end
|
233
225
|
|
234
226
|
it 'should not follow more than 21 redirects' do
|
235
227
|
expect do
|
236
|
-
|
228
|
+
driver.visit('/redirect/22/times')
|
237
229
|
end.to raise_error(Capybara::InfiniteRedirectError)
|
238
230
|
end
|
239
231
|
end
|