capybara 3.14.0 → 3.15.0
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.
- 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
|