capybara 3.16.1 → 3.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/History.md +321 -0
- data/README.md +51 -60
- data/lib/capybara.rb +71 -114
- data/lib/capybara/config.rb +8 -5
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/node.rb +15 -3
- data/lib/capybara/dsl.rb +10 -2
- data/lib/capybara/helpers.rb +5 -3
- data/lib/capybara/minitest.rb +242 -141
- data/lib/capybara/minitest/spec.rb +159 -90
- data/lib/capybara/node/actions.rb +85 -74
- data/lib/capybara/node/base.rb +4 -4
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +216 -117
- data/lib/capybara/node/finders.rb +65 -65
- data/lib/capybara/node/matchers.rb +228 -126
- data/lib/capybara/node/simple.rb +9 -4
- data/lib/capybara/queries/ancestor_query.rb +5 -7
- data/lib/capybara/queries/base_query.rb +2 -1
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +296 -30
- data/lib/capybara/queries/sibling_query.rb +5 -4
- data/lib/capybara/queries/style_query.rb +2 -2
- data/lib/capybara/queries/text_query.rb +13 -1
- data/lib/capybara/queries/title_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +7 -2
- data/lib/capybara/rack_test/driver.rb +1 -1
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/rack_test/node.rb +43 -7
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/drivers.rb +36 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
- data/lib/capybara/registrations/servers.rb +44 -0
- data/lib/capybara/result.rb +36 -8
- data/lib/capybara/rspec/matcher_proxies.rb +6 -4
- data/lib/capybara/rspec/matchers.rb +100 -63
- data/lib/capybara/rspec/matchers/base.rb +23 -10
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
- data/lib/capybara/rspec/matchers/have_selector.rb +16 -8
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +4 -4
- data/lib/capybara/rspec/matchers/have_title.rb +2 -2
- data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
- data/lib/capybara/rspec/matchers/match_style.rb +2 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/selector.rb +219 -588
- data/lib/capybara/selector/builders/css_builder.rb +10 -6
- data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
- data/lib/capybara/selector/css.rb +4 -2
- data/lib/capybara/selector/definition.rb +277 -0
- data/lib/capybara/selector/definition/button.rb +52 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +27 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +54 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/filter_set.rb +13 -9
- data/lib/capybara/selector/filters/base.rb +11 -2
- data/lib/capybara/selector/filters/locator_filter.rb +13 -3
- data/lib/capybara/selector/regexp_disassembler.rb +9 -2
- data/lib/capybara/selector/selector.rb +43 -448
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +125 -56
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +73 -17
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +41 -2
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +14 -1
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +14 -5
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +67 -45
- data/lib/capybara/selenium/extensions/html5_drag.rb +152 -36
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/logger_suppressor.rb +34 -0
- data/lib/capybara/selenium/node.rb +227 -56
- data/lib/capybara/selenium/nodes/chrome_node.rb +93 -8
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +37 -59
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +27 -54
- data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/server.rb +19 -3
- data/lib/capybara/server/animation_disabler.rb +2 -2
- data/lib/capybara/server/checker.rb +6 -2
- data/lib/capybara/server/middleware.rb +23 -13
- data/lib/capybara/session.rb +124 -106
- data/lib/capybara/session/config.rb +12 -10
- data/lib/capybara/session/matchers.rb +6 -6
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +94 -5
- data/lib/capybara/spec/session/all_spec.rb +84 -6
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
- data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
- data/lib/capybara/spec/session/attach_file_spec.rb +14 -6
- data/lib/capybara/spec/session/check_spec.rb +10 -4
- data/lib/capybara/spec/session/choose_spec.rb +8 -2
- data/lib/capybara/spec/session/click_button_spec.rb +44 -1
- data/lib/capybara/spec/session/click_link_spec.rb +11 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +12 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +37 -2
- data/lib/capybara/spec/session/find_spec.rb +60 -6
- data/lib/capybara/spec/session/first_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_button_spec.rb +16 -0
- data/lib/capybara/spec/session/has_css_spec.rb +35 -6
- data/lib/capybara/spec/session/has_current_path_spec.rb +6 -4
- data/lib/capybara/spec/session/has_field_spec.rb +34 -0
- data/lib/capybara/spec/session/has_select_spec.rb +32 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +51 -5
- data/lib/capybara/spec/session/has_text_spec.rb +47 -0
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
- data/lib/capybara/spec/session/node_spec.rb +574 -16
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
- data/lib/capybara/spec/session/scroll_spec.rb +1 -1
- data/lib/capybara/spec/session/select_spec.rb +5 -10
- data/lib/capybara/spec/session/selectors_spec.rb +24 -3
- data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
- data/lib/capybara/spec/session/unselect_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +10 -9
- data/lib/capybara/spec/spec_helper.rb +7 -2
- data/lib/capybara/spec/test_app.rb +26 -21
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +25 -4
- data/lib/capybara/spec/views/frame_child.erb +2 -1
- data/lib/capybara/spec/views/frame_one.erb +1 -0
- data/lib/capybara/spec/views/obscured.erb +9 -9
- data/lib/capybara/spec/views/offset.erb +32 -0
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/with_animation.erb +29 -1
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_html.erb +28 -2
- data/lib/capybara/spec/views/with_js.erb +2 -1
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +10 -10
- data/spec/basic_node_spec.rb +6 -6
- data/spec/capybara_spec.rb +28 -28
- data/spec/dsl_spec.rb +16 -3
- data/spec/filter_set_spec.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
- data/spec/minitest_spec.rb +12 -2
- data/spec/minitest_spec_spec.rb +56 -45
- data/spec/rack_test_spec.rb +25 -12
- data/spec/regexp_dissassembler_spec.rb +53 -39
- data/spec/result_spec.rb +50 -54
- data/spec/rspec/features_spec.rb +1 -0
- data/spec/rspec/shared_spec_matchers.rb +78 -62
- data/spec/rspec_spec.rb +5 -5
- data/spec/sauce_spec_chrome.rb +1 -0
- data/spec/selector_spec.rb +26 -16
- data/spec/selenium_spec_chrome.rb +84 -5
- data/spec/selenium_spec_chrome_remote.rb +23 -8
- data/spec/selenium_spec_edge.rb +23 -8
- data/spec/selenium_spec_firefox.rb +16 -21
- data/spec/selenium_spec_firefox_remote.rb +4 -13
- data/spec/selenium_spec_ie.rb +23 -15
- data/spec/selenium_spec_safari.rb +17 -17
- data/spec/server_spec.rb +87 -42
- data/spec/session_spec.rb +11 -4
- data/spec/shared_selenium_node.rb +83 -0
- data/spec/shared_selenium_session.rb +62 -72
- data/spec/spec_helper.rb +43 -5
- metadata +114 -16
@@ -157,32 +157,36 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
157
157
|
minimum: 6,
|
158
158
|
maximum: 0,
|
159
159
|
between: 0..4 }
|
160
|
-
expect { @session.assert_text('Header', o) }.not_to raise_error
|
160
|
+
expect { @session.assert_text('Header', **o) }.not_to raise_error
|
161
161
|
end
|
162
|
+
|
162
163
|
context 'with no :count expectation' do
|
163
164
|
it 'fails if :minimum is not met' do
|
164
165
|
o = { minimum: 6,
|
165
166
|
maximum: 5,
|
166
167
|
between: 2..7 }
|
167
|
-
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
168
|
+
expect { @session.assert_text('Header', **o) }.to raise_error(Capybara::ExpectationNotMet)
|
168
169
|
end
|
170
|
+
|
169
171
|
it 'fails if :maximum is not met' do
|
170
172
|
o = { minimum: 0,
|
171
173
|
maximum: 0,
|
172
174
|
between: 2..7 }
|
173
|
-
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
175
|
+
expect { @session.assert_text('Header', **o) }.to raise_error(Capybara::ExpectationNotMet)
|
174
176
|
end
|
177
|
+
|
175
178
|
it 'fails if :between is not met' do
|
176
179
|
o = { minimum: 0,
|
177
180
|
maximum: 5,
|
178
181
|
between: 0..4 }
|
179
|
-
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
182
|
+
expect { @session.assert_text('Header', **o) }.to raise_error(Capybara::ExpectationNotMet)
|
180
183
|
end
|
184
|
+
|
181
185
|
it 'succeeds if all combineable expectations are met' do
|
182
186
|
o = { minimum: 0,
|
183
187
|
maximum: 5,
|
184
188
|
between: 2..7 }
|
185
|
-
expect { @session.assert_text('Header', o) }.not_to raise_error
|
189
|
+
expect { @session.assert_text('Header', **o) }.not_to raise_error
|
186
190
|
end
|
187
191
|
end
|
188
192
|
end
|
@@ -121,7 +121,7 @@ Capybara::SpecHelper.spec '#attach_file' do
|
|
121
121
|
|
122
122
|
context "with a locator that doesn't exist" do
|
123
123
|
it 'should raise an error' do
|
124
|
-
msg =
|
124
|
+
msg = /Unable to find file field "does not exist"/
|
125
125
|
expect do
|
126
126
|
@session.attach_file('does not exist', with_os_path_separators(test_file_path))
|
127
127
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -180,6 +180,12 @@ Capybara::SpecHelper.spec '#attach_file' do
|
|
180
180
|
@session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
|
181
181
|
expect(@session.evaluate_script('arguments[0].style.display', @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
|
182
182
|
end
|
183
|
+
|
184
|
+
it 'should fire change' do
|
185
|
+
@session.visit('/with_js')
|
186
|
+
@session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
|
187
|
+
expect(@session).to have_css('.file_change')
|
188
|
+
end
|
183
189
|
end
|
184
190
|
|
185
191
|
context 'with a block', requires: %i[js] do
|
@@ -198,11 +204,13 @@ Capybara::SpecHelper.spec '#attach_file' do
|
|
198
204
|
@session.click_button('awesome')
|
199
205
|
expect(extract_results(@session)['hidden_image']).to end_with(File.basename(__FILE__))
|
200
206
|
end
|
201
|
-
end
|
202
207
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
208
|
+
it 'should fire change' do
|
209
|
+
@session.visit('/with_js')
|
210
|
+
@session.attach_file(with_os_path_separators(__FILE__)) do
|
211
|
+
@session.find(:label, 'Label for hidden file input').click
|
212
|
+
end
|
213
|
+
expect(@session).to have_css('.file_change')
|
214
|
+
end
|
207
215
|
end
|
208
216
|
end
|
@@ -83,7 +83,7 @@ Capybara::SpecHelper.spec '#check' do
|
|
83
83
|
|
84
84
|
context "with a locator that doesn't exist" do
|
85
85
|
it 'should raise an error' do
|
86
|
-
msg =
|
86
|
+
msg = /Unable to find checkbox "does not exist"/
|
87
87
|
expect do
|
88
88
|
@session.check('does not exist')
|
89
89
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -120,6 +120,12 @@ Capybara::SpecHelper.spec '#check' do
|
|
120
120
|
expect(extract_results(@session)['pets']).to include('cat')
|
121
121
|
end
|
122
122
|
|
123
|
+
it 'should alias `with`' do
|
124
|
+
@session.check('form[pets][]', with: 'cat')
|
125
|
+
@session.click_button('awesome')
|
126
|
+
expect(extract_results(@session)['pets']).to include('cat')
|
127
|
+
end
|
128
|
+
|
123
129
|
it 'should raise an error if option not found' do
|
124
130
|
expect do
|
125
131
|
@session.check('form[pets][]', option: 'elephant')
|
@@ -171,11 +177,11 @@ Capybara::SpecHelper.spec '#check' do
|
|
171
177
|
end
|
172
178
|
|
173
179
|
it 'should raise original error when no label available' do
|
174
|
-
expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound,
|
180
|
+
expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_ariel"/)
|
175
181
|
end
|
176
182
|
|
177
183
|
it 'should raise error if not allowed to click label' do
|
178
|
-
expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound,
|
184
|
+
expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/)
|
179
185
|
end
|
180
186
|
end
|
181
187
|
|
@@ -187,7 +193,7 @@ Capybara::SpecHelper.spec '#check' do
|
|
187
193
|
end
|
188
194
|
|
189
195
|
it 'should raise error if checkbox not visible' do
|
190
|
-
expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound,
|
196
|
+
expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/)
|
191
197
|
end
|
192
198
|
|
193
199
|
it 'should include node filter in error if verified' do
|
@@ -38,7 +38,7 @@ Capybara::SpecHelper.spec '#choose' do
|
|
38
38
|
|
39
39
|
context "with a locator that doesn't exist" do
|
40
40
|
it 'should raise an error' do
|
41
|
-
msg =
|
41
|
+
msg = /Unable to find radio button "does not exist"/
|
42
42
|
expect do
|
43
43
|
@session.choose('does not exist')
|
44
44
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -74,6 +74,12 @@ Capybara::SpecHelper.spec '#choose' do
|
|
74
74
|
expect(extract_results(@session)['gender']).to eq('male')
|
75
75
|
end
|
76
76
|
|
77
|
+
it 'should alias `:with` option' do
|
78
|
+
@session.choose('form[gender]', with: 'male')
|
79
|
+
@session.click_button('awesome')
|
80
|
+
expect(extract_results(@session)['gender']).to eq('male')
|
81
|
+
end
|
82
|
+
|
77
83
|
it 'should raise an error if option not found' do
|
78
84
|
expect do
|
79
85
|
@session.choose('form[gender]', option: 'hermaphrodite')
|
@@ -103,7 +109,7 @@ Capybara::SpecHelper.spec '#choose' do
|
|
103
109
|
end
|
104
110
|
|
105
111
|
it 'should raise error if not allowed to click label' do
|
106
|
-
expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound,
|
112
|
+
expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible radio button "party_democrat"/)
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
@@ -162,6 +162,11 @@ Capybara::SpecHelper.spec '#click_button' do
|
|
162
162
|
expect(extract_results(@session)['first_name']).to eq('John')
|
163
163
|
end
|
164
164
|
|
165
|
+
it 'should submit by specific button id' do
|
166
|
+
@session.click_button(id: 'awe123')
|
167
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
168
|
+
end
|
169
|
+
|
165
170
|
it 'should submit by button title' do
|
166
171
|
@session.click_button('What an Awesome Button')
|
167
172
|
expect(extract_results(@session)['first_name']).to eq('John')
|
@@ -171,6 +176,32 @@ Capybara::SpecHelper.spec '#click_button' do
|
|
171
176
|
@session.click_button('What an Awesome')
|
172
177
|
expect(extract_results(@session)['first_name']).to eq('John')
|
173
178
|
end
|
179
|
+
|
180
|
+
it 'should submit by button name' do
|
181
|
+
@session.click_button('form[awesome]')
|
182
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should submit by specific button name' do
|
186
|
+
@session.click_button(name: 'form[awesome]')
|
187
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should submit by specific button name regex' do
|
191
|
+
@session.click_button(name: /form\[awes.*\]/)
|
192
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'when Capybara.enable_aria_role = true' do
|
197
|
+
it 'should click on a button role', requires: [:js] do
|
198
|
+
Capybara.enable_aria_role = true
|
199
|
+
@session.using_wait_time(1.5) do
|
200
|
+
@session.visit('/with_js')
|
201
|
+
@session.click_button('ARIA button')
|
202
|
+
expect(@session).to have_button('ARIA button has been clicked')
|
203
|
+
end
|
204
|
+
end
|
174
205
|
end
|
175
206
|
|
176
207
|
context 'with fields associated with the form using the form attribute', requires: [:form_attribute] do
|
@@ -314,6 +345,18 @@ Capybara::SpecHelper.spec '#click_button' do
|
|
314
345
|
end
|
315
346
|
end
|
316
347
|
|
348
|
+
context 'with name given on a button defined by <button> tag' do
|
349
|
+
it 'should submit the associated form when name is locator' do
|
350
|
+
@session.click_button('form[no_value]')
|
351
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should submit the associated form when name is specific' do
|
355
|
+
@session.click_button(name: 'form[no_value]')
|
356
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
317
360
|
context 'with value given on a button defined by <button> tag' do
|
318
361
|
it 'should submit the associated form' do
|
319
362
|
@session.click_button('click_me')
|
@@ -352,7 +395,7 @@ Capybara::SpecHelper.spec '#click_button' do
|
|
352
395
|
|
353
396
|
context "with a locator that doesn't exist" do
|
354
397
|
it 'should raise an error' do
|
355
|
-
msg =
|
398
|
+
msg = /Unable to find button "does not exist"/
|
356
399
|
expect do
|
357
400
|
@session.click_button('does not exist')
|
358
401
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -118,6 +118,17 @@ Capybara::SpecHelper.spec '#click_link' do
|
|
118
118
|
expect { @session.click_link('Normal Anchor', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
|
119
119
|
end
|
120
120
|
end
|
121
|
+
|
122
|
+
context 'href: false' do
|
123
|
+
it 'should not raise an error on links with no href attribute' do
|
124
|
+
expect { @session.click_link('No Href', href: false) }.not_to raise_error
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should not raise an error if href attribute exists' do
|
128
|
+
expect { @session.click_link('Blank Href', href: false) }.not_to raise_error
|
129
|
+
expect { @session.click_link('Normal Anchor', href: false) }.not_to raise_error
|
130
|
+
end
|
131
|
+
end
|
121
132
|
end
|
122
133
|
|
123
134
|
it 'should follow relative links' do
|
@@ -34,4 +34,16 @@ Capybara::SpecHelper.spec '#evaluate_script', requires: [:js] do
|
|
34
34
|
expect(el).to be_instance_of(Capybara::Node::Element)
|
35
35
|
expect(el).to eq(@session.find(:css, '#change'))
|
36
36
|
end
|
37
|
+
|
38
|
+
it 'should support multi statement via IIFE' do
|
39
|
+
@session.visit('/with_js')
|
40
|
+
@session.find(:css, '#change')
|
41
|
+
el = @session.evaluate_script(<<~JS)
|
42
|
+
(function(){
|
43
|
+
var el = document.getElementById('change');
|
44
|
+
return el;
|
45
|
+
})()
|
46
|
+
JS
|
47
|
+
expect(el).to eq(@session.find(:css, '#change'))
|
48
|
+
end
|
37
49
|
end
|
@@ -47,6 +47,15 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
47
47
|
expect(extract_results(@session)['description']).to eq('Texty text')
|
48
48
|
end
|
49
49
|
|
50
|
+
it 'should fill in a textarea in a reasonable time by default' do
|
51
|
+
textarea = @session.find(:fillable_field, 'form[description]')
|
52
|
+
value = 'a' * 4000
|
53
|
+
start = Time.now
|
54
|
+
textarea.fill_in(with: value)
|
55
|
+
expect(Time.now.to_f).to be_within(0.25).of start.to_f
|
56
|
+
expect(textarea.value).to eq value
|
57
|
+
end
|
58
|
+
|
50
59
|
it 'should fill in a password field by id' do
|
51
60
|
@session.fill_in('form_password', with: 'supasikrit')
|
52
61
|
@session.click_button('awesome')
|
@@ -89,6 +98,32 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
89
98
|
expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
|
90
99
|
end
|
91
100
|
|
101
|
+
it 'should fill in a color field' do
|
102
|
+
@session.fill_in('Html5 Color', with: '#112233')
|
103
|
+
@session.click_button('html5_submit')
|
104
|
+
expect(extract_results(@session)['html5_color']).to eq('#112233')
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'with input[type="range"]' do
|
108
|
+
it 'should set the range slider correctly' do
|
109
|
+
@session.fill_in('form_age', with: 51)
|
110
|
+
@session.click_button('awesome')
|
111
|
+
expect(extract_results(@session)['age'].to_f).to eq 51
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should set the range slider to valid values' do
|
115
|
+
@session.fill_in('form_age', with: '37.6')
|
116
|
+
@session.click_button('awesome')
|
117
|
+
expect(extract_results(@session)['age'].to_f).to eq 37.5
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should respect the range slider limits' do
|
121
|
+
@session.fill_in('form_age', with: '3')
|
122
|
+
@session.click_button('awesome')
|
123
|
+
expect(extract_results(@session)['age'].to_f).to eq 13
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
92
127
|
it 'should fill in a field with a custom type' do
|
93
128
|
@session.fill_in('Schmooo', with: 'Schmooo is the game')
|
94
129
|
@session.click_button('awesome')
|
@@ -200,7 +235,7 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
200
235
|
after { Capybara.ignore_hidden_elements = false }
|
201
236
|
|
202
237
|
it 'should not find a hidden field' do
|
203
|
-
msg =
|
238
|
+
msg = /Unable to find visible field "Super Secret"/
|
204
239
|
expect do
|
205
240
|
@session.fill_in('Super Secret', with: '777')
|
206
241
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -209,7 +244,7 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
209
244
|
|
210
245
|
context "with a locator that doesn't exist" do
|
211
246
|
it 'should raise an error' do
|
212
|
-
msg =
|
247
|
+
msg = /Unable to find field "does not exist"/
|
213
248
|
expect do
|
214
249
|
@session.fill_in('does not exist', with: 'Blah blah')
|
215
250
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
@@ -107,8 +107,8 @@ Capybara::SpecHelper.spec '#find' do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'should warn if passed a non-valid locator type' do
|
110
|
-
|
111
|
-
|
110
|
+
expect { @session.find(:xpath, 123) }.to raise_error(Exception) # The exact error is not yet well defined
|
111
|
+
.and output(/must respond to to_xpath or be an instance of String/).to_stderr
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -235,7 +235,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
235
235
|
|
236
236
|
it 'should accept an XPath instance' do
|
237
237
|
@session.visit('/form')
|
238
|
-
@xpath = Capybara::Selector
|
238
|
+
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
239
239
|
expect(@xpath).to be_a(::XPath::Union)
|
240
240
|
expect(@session.find(@xpath).value).to eq('John')
|
241
241
|
end
|
@@ -263,9 +263,8 @@ Capybara::SpecHelper.spec '#find' do
|
|
263
263
|
end
|
264
264
|
|
265
265
|
it 'warns when the option has no effect' do
|
266
|
-
|
267
|
-
|
268
|
-
@session.find(:css, '#test_field', exact: true)
|
266
|
+
expect { @session.find(:css, '#test_field', exact: true) }.to \
|
267
|
+
output(/^The :exact option only has an effect on queries using the XPath#is method. Using it with the query "#test_field" has no effect/).to_stderr
|
269
268
|
end
|
270
269
|
end
|
271
270
|
|
@@ -276,14 +275,17 @@ Capybara::SpecHelper.spec '#find' do
|
|
276
275
|
@session.find(:css, '.multiple', match: :one)
|
277
276
|
end.to raise_error(Capybara::Ambiguous)
|
278
277
|
end
|
278
|
+
|
279
279
|
it 'raises an error even if there the match is exact and the others are inexact' do
|
280
280
|
expect do
|
281
281
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], exact: false, match: :one)
|
282
282
|
end.to raise_error(Capybara::Ambiguous)
|
283
283
|
end
|
284
|
+
|
284
285
|
it 'returns the element if there is only one' do
|
285
286
|
expect(@session.find(:css, '.singular', match: :one).text).to eq('singular')
|
286
287
|
end
|
288
|
+
|
287
289
|
it 'raises an error if there is no match' do
|
288
290
|
expect do
|
289
291
|
@session.find(:css, '.does-not-exist', match: :one)
|
@@ -295,6 +297,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
295
297
|
it 'returns the first matched element' do
|
296
298
|
expect(@session.find(:css, '.multiple', match: :first).text).to eq('multiple one')
|
297
299
|
end
|
300
|
+
|
298
301
|
it 'raises an error if there is no match' do
|
299
302
|
expect do
|
300
303
|
@session.find(:css, '.does-not-exist', match: :first)
|
@@ -309,19 +312,23 @@ Capybara::SpecHelper.spec '#find' do
|
|
309
312
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: false)
|
310
313
|
end.to raise_error(Capybara::Ambiguous)
|
311
314
|
end
|
315
|
+
|
312
316
|
it 'finds a single exact match when there also are inexact matches' do
|
313
317
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: false)
|
314
318
|
expect(result.text).to eq('almost singular')
|
315
319
|
end
|
320
|
+
|
316
321
|
it 'raises an error when there are multiple inexact matches' do
|
317
322
|
expect do
|
318
323
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: false)
|
319
324
|
end.to raise_error(Capybara::Ambiguous)
|
320
325
|
end
|
326
|
+
|
321
327
|
it 'finds a single inexact match' do
|
322
328
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: false)
|
323
329
|
expect(result.text).to eq('almost singular but not quite')
|
324
330
|
end
|
331
|
+
|
325
332
|
it 'raises an error if there is no match' do
|
326
333
|
expect do
|
327
334
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: false)
|
@@ -335,20 +342,24 @@ Capybara::SpecHelper.spec '#find' do
|
|
335
342
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: true)
|
336
343
|
end.to raise_error(Capybara::Ambiguous)
|
337
344
|
end
|
345
|
+
|
338
346
|
it 'finds a single exact match when there also are inexact matches' do
|
339
347
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: true)
|
340
348
|
expect(result.text).to eq('almost singular')
|
341
349
|
end
|
350
|
+
|
342
351
|
it 'raises an error when there are multiple inexact matches' do
|
343
352
|
expect do
|
344
353
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: true)
|
345
354
|
end.to raise_error(Capybara::ElementNotFound)
|
346
355
|
end
|
356
|
+
|
347
357
|
it 'raises an error when there is a single inexact matches' do
|
348
358
|
expect do
|
349
359
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: true)
|
350
360
|
end.to raise_error(Capybara::ElementNotFound)
|
351
361
|
end
|
362
|
+
|
352
363
|
it 'raises an error if there is no match' do
|
353
364
|
expect do
|
354
365
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: true)
|
@@ -363,18 +374,22 @@ Capybara::SpecHelper.spec '#find' do
|
|
363
374
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: false)
|
364
375
|
expect(result.text).to eq('multiple one')
|
365
376
|
end
|
377
|
+
|
366
378
|
it 'finds a single exact match when there also are inexact matches' do
|
367
379
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: false)
|
368
380
|
expect(result.text).to eq('almost singular')
|
369
381
|
end
|
382
|
+
|
370
383
|
it 'picks the first one when there are multiple inexact matches' do
|
371
384
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: false)
|
372
385
|
expect(result.text).to eq('almost singular but not quite')
|
373
386
|
end
|
387
|
+
|
374
388
|
it 'finds a single inexact match' do
|
375
389
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: false)
|
376
390
|
expect(result.text).to eq('almost singular but not quite')
|
377
391
|
end
|
392
|
+
|
378
393
|
it 'raises an error if there is no match' do
|
379
394
|
expect do
|
380
395
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: false)
|
@@ -387,20 +402,24 @@ Capybara::SpecHelper.spec '#find' do
|
|
387
402
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: true)
|
388
403
|
expect(result.text).to eq('multiple one')
|
389
404
|
end
|
405
|
+
|
390
406
|
it 'finds a single exact match when there also are inexact matches' do
|
391
407
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: true)
|
392
408
|
expect(result.text).to eq('almost singular')
|
393
409
|
end
|
410
|
+
|
394
411
|
it 'raises an error if there are multiple inexact matches' do
|
395
412
|
expect do
|
396
413
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: true)
|
397
414
|
end.to raise_error(Capybara::ElementNotFound)
|
398
415
|
end
|
416
|
+
|
399
417
|
it 'raises an error if there is a single inexact match' do
|
400
418
|
expect do
|
401
419
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: true)
|
402
420
|
end.to raise_error(Capybara::ElementNotFound)
|
403
421
|
end
|
422
|
+
|
404
423
|
it 'raises an error if there is no match' do
|
405
424
|
expect do
|
406
425
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: true)
|
@@ -429,6 +448,41 @@ Capybara::SpecHelper.spec '#find' do
|
|
429
448
|
expect(@session.find(:css, 'input', &:disabled?)[:name]).to eq('disabled_text')
|
430
449
|
end
|
431
450
|
|
451
|
+
context 'with spatial filters', requires: [:spatial] do
|
452
|
+
before do
|
453
|
+
@session.visit('/spatial')
|
454
|
+
end
|
455
|
+
|
456
|
+
let :center do
|
457
|
+
@session.find(:css, 'div.center')
|
458
|
+
end
|
459
|
+
|
460
|
+
it 'should find an element above another element' do
|
461
|
+
expect(@session.find(:css, 'div:not(.corner)', above: center).text).to eq('2')
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'should find an element below another element' do
|
465
|
+
expect(@session.find(:css, 'div:not(.corner):not(.footer)', below: center).text).to eq('8')
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'should find an element left of another element' do
|
469
|
+
expect(@session.find(:css, 'div:not(.corner)', left_of: center).text).to eq('4')
|
470
|
+
end
|
471
|
+
|
472
|
+
it 'should find an element right of another element' do
|
473
|
+
expect(@session.find(:css, 'div:not(.corner)', right_of: center).text).to eq('6')
|
474
|
+
end
|
475
|
+
|
476
|
+
it 'should combine spatial filters' do
|
477
|
+
expect(@session.find(:css, 'div', left_of: center, above: center).text).to eq('1')
|
478
|
+
expect(@session.find(:css, 'div', right_of: center, below: center).text).to eq('9')
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'should find an element "near" another element' do
|
482
|
+
expect(@session.find(:css, 'div.distance', near: center).text).to eq('2')
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
432
486
|
context 'within a scope' do
|
433
487
|
before do
|
434
488
|
@session.visit('/with_scope')
|