capybara 3.3.0 → 3.40.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/.yardopts +1 -0
- data/History.md +803 -13
- data/License.txt +1 -1
- data/README.md +257 -84
- data/lib/capybara/config.rb +25 -9
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +17 -3
- data/lib/capybara/driver/node.rb +31 -6
- data/lib/capybara/dsl.rb +9 -7
- data/lib/capybara/helpers.rb +31 -7
- data/lib/capybara/minitest/spec.rb +180 -88
- data/lib/capybara/minitest.rb +262 -149
- data/lib/capybara/node/actions.rb +202 -116
- data/lib/capybara/node/base.rb +34 -19
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +10 -12
- data/lib/capybara/node/element.rb +269 -115
- data/lib/capybara/node/finders.rb +99 -77
- data/lib/capybara/node/matchers.rb +327 -151
- data/lib/capybara/node/simple.rb +48 -13
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +8 -9
- data/lib/capybara/queries/base_query.rb +23 -16
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +1 -0
- data/lib/capybara/queries/selector_query.rb +587 -130
- data/lib/capybara/queries/sibling_query.rb +8 -6
- data/lib/capybara/queries/style_query.rb +6 -2
- data/lib/capybara/queries/text_query.rb +28 -14
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +92 -25
- data/lib/capybara/rack_test/driver.rb +16 -7
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +68 -41
- data/lib/capybara/rack_test/node.rb +106 -39
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +75 -52
- data/lib/capybara/rspec/features.rb +7 -7
- data/lib/capybara/rspec/matcher_proxies.rb +39 -18
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- 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 +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +141 -339
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +27 -25
- data/lib/capybara/selector/definition/button.rb +68 -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 +28 -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 +55 -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/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +1 -0
- data/lib/capybara/selector/filter_set.rb +73 -25
- data/lib/capybara/selector/filters/base.rb +24 -5
- data/lib/capybara/selector/filters/expression_filter.rb +3 -3
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -2
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +85 -348
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +474 -447
- 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 +255 -143
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +436 -134
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -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/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +56 -19
- data/lib/capybara/server/checker.rb +9 -3
- data/lib/capybara/server/middleware.rb +28 -12
- data/lib/capybara/server.rb +33 -10
- data/lib/capybara/session/config.rb +34 -10
- data/lib/capybara/session/matchers.rb +23 -16
- data/lib/capybara/session.rb +230 -170
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +121 -8
- data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +127 -40
- data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
- data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
- data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
- data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
- data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
- data/lib/capybara/spec/session/body_spec.rb +6 -6
- data/lib/capybara/spec/session/check_spec.rb +102 -47
- data/lib/capybara/spec/session/choose_spec.rb +58 -32
- data/lib/capybara/spec/session/click_button_spec.rb +219 -163
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
- data/lib/capybara/spec/session/click_link_spec.rb +77 -54
- data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
- data/lib/capybara/spec/session/current_url_spec.rb +38 -29
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
- data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
- data/lib/capybara/spec/session/find_field_spec.rb +32 -30
- data/lib/capybara/spec/session/find_link_spec.rb +31 -21
- data/lib/capybara/spec/session/find_spec.rb +244 -141
- data/lib/capybara/spec/session/first_spec.rb +43 -43
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +94 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -132
- data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +137 -58
- data/lib/capybara/spec/session/has_link_spec.rb +44 -4
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
- data/lib/capybara/spec/session/has_select_spec.rb +84 -50
- data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +181 -4
- data/lib/capybara/spec/session/has_text_spec.rb +101 -53
- data/lib/capybara/spec/session/has_title_spec.rb +19 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
- data/lib/capybara/spec/session/headers_spec.rb +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +894 -142
- data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
- data/lib/capybara/spec/session/response_code_spec.rb +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +37 -37
- data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +85 -85
- data/lib/capybara/spec/session/selectors_spec.rb +49 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +25 -24
- data/lib/capybara/spec/session/title_spec.rb +7 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +68 -49
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
- data/lib/capybara/spec/session/window/window_spec.rb +62 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
- data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
- data/lib/capybara/spec/session/within_spec.rb +79 -42
- data/lib/capybara/spec/spec_helper.rb +41 -53
- data/lib/capybara/spec/test_app.rb +132 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +139 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +67 -0
- data/lib/capybara/spec/views/with_animation.erb +39 -4
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +37 -9
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +26 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +19 -25
- data/lib/capybara.rb +126 -111
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +56 -44
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +8 -8
- data/spec/dsl_spec.rb +79 -52
- data/spec/filter_set_spec.rb +9 -9
- data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
- data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
- data/spec/minitest_spec.rb +45 -7
- data/spec/minitest_spec_spec.rb +87 -64
- data/spec/per_session_config_spec.rb +6 -6
- data/spec/rack_test_spec.rb +172 -116
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +80 -72
- data/spec/rspec/features_spec.rb +21 -16
- data/spec/rspec/scenarios_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +407 -365
- data/spec/rspec/views_spec.rb +3 -3
- data/spec/rspec_matchers_spec.rb +35 -10
- data/spec/rspec_spec.rb +63 -41
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +334 -89
- data/spec/selenium_spec_chrome.rb +176 -62
- data/spec/selenium_spec_chrome_remote.rb +54 -14
- data/spec/selenium_spec_edge.rb +41 -8
- data/spec/selenium_spec_firefox.rb +228 -0
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +129 -11
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +171 -97
- data/spec/session_spec.rb +34 -18
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +344 -80
- data/spec/spec_helper.rb +124 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +326 -28
- data/lib/capybara/rspec/compound.rb +0 -94
- data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
- data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
- data/lib/capybara/spec/session/has_style_spec.rb +0 -25
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -167
|
@@ -9,66 +9,67 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
9
9
|
Capybara::Selector.remove(:monkey)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
it
|
|
12
|
+
it 'should find the first element using the given locator' do
|
|
13
13
|
expect(@session.find('//h1').text).to eq('This is a test')
|
|
14
14
|
expect(@session.find("//input[@id='test_field']").value).to eq('monkey')
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
it
|
|
17
|
+
it 'should find the first element using the given locator and options' do
|
|
18
18
|
expect(@session.find('//a', text: 'Redirect')[:id]).to eq('red')
|
|
19
19
|
expect(@session.find(:css, 'a', text: 'A link came first')[:title]).to eq('twas a fine link')
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
it
|
|
22
|
+
it 'should raise an error if there are multiple matches' do
|
|
23
23
|
expect { @session.find('//a') }.to raise_error(Capybara::Ambiguous)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
it
|
|
26
|
+
it 'should wait for asynchronous load', requires: [:js] do
|
|
27
|
+
Capybara.default_max_wait_time = 2
|
|
27
28
|
@session.visit('/with_js')
|
|
28
29
|
@session.click_link('Click me')
|
|
29
|
-
expect(@session.find(:css,
|
|
30
|
+
expect(@session.find(:css, 'a#has-been-clicked').text).to include('Has been clicked')
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
context
|
|
33
|
+
context 'with :text option' do
|
|
33
34
|
it "casts text's argument to string" do
|
|
34
|
-
expect(@session.find(:css, '.number', text: 42)).to have_content(
|
|
35
|
+
expect(@session.find(:css, '.number', text: 42)).to have_content('42')
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
context
|
|
39
|
-
it
|
|
39
|
+
context 'with :wait option', requires: [:js] do
|
|
40
|
+
it 'should not wait for asynchronous load when `false` given' do
|
|
40
41
|
@session.visit('/with_js')
|
|
41
42
|
@session.click_link('Click me')
|
|
42
43
|
expect do
|
|
43
|
-
@session.find(:css,
|
|
44
|
+
@session.find(:css, 'a#has-been-clicked', wait: false)
|
|
44
45
|
end.to raise_error(Capybara::ElementNotFound)
|
|
45
46
|
end
|
|
46
47
|
|
|
47
|
-
it
|
|
48
|
+
it 'should not find element if it appears after given wait duration' do
|
|
48
49
|
@session.visit('/with_js')
|
|
49
50
|
@session.click_link('Slowly')
|
|
50
51
|
expect do
|
|
51
|
-
@session.find(:css,
|
|
52
|
+
@session.find(:css, 'a#slow-clicked', wait: 0.2)
|
|
52
53
|
end.to raise_error(Capybara::ElementNotFound)
|
|
53
54
|
end
|
|
54
55
|
|
|
55
|
-
it
|
|
56
|
+
it 'should find element if it appears before given wait duration' do
|
|
56
57
|
@session.visit('/with_js')
|
|
57
58
|
@session.click_link('Click me')
|
|
58
|
-
expect(@session.find(:css,
|
|
59
|
+
expect(@session.find(:css, 'a#has-been-clicked', wait: 3.0).text).to include('Has been clicked')
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
|
|
62
|
-
context
|
|
63
|
+
context 'with frozen time', requires: [:js] do
|
|
63
64
|
if defined?(Process::CLOCK_MONOTONIC)
|
|
64
|
-
it
|
|
65
|
+
it 'will time out even if time is frozen' do
|
|
65
66
|
@session.visit('/with_js')
|
|
66
67
|
now = Time.now
|
|
67
68
|
allow(Time).to receive(:now).and_return(now)
|
|
68
69
|
expect { @session.find('//isnotthere') }.to raise_error(Capybara::ElementNotFound)
|
|
69
70
|
end
|
|
70
71
|
else
|
|
71
|
-
it
|
|
72
|
+
it 'raises an error suggesting that Capybara is stuck in time' do
|
|
72
73
|
@session.visit('/with_js')
|
|
73
74
|
now = Time.now
|
|
74
75
|
allow(Time).to receive(:now).and_return(now)
|
|
@@ -77,31 +78,42 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
80
|
|
|
80
|
-
context
|
|
81
|
-
it
|
|
81
|
+
context 'with css selectors' do
|
|
82
|
+
it 'should find the first element using the given locator' do
|
|
82
83
|
expect(@session.find(:css, 'h1').text).to eq('This is a test')
|
|
83
84
|
expect(@session.find(:css, "input[id='test_field']").value).to eq('monkey')
|
|
84
85
|
end
|
|
85
86
|
|
|
86
|
-
it
|
|
87
|
+
it 'should support pseudo selectors' do
|
|
87
88
|
expect(@session.find(:css, 'input:disabled').value).to eq('This is disabled')
|
|
88
89
|
end
|
|
89
90
|
|
|
90
|
-
it
|
|
91
|
+
it 'should support escaping characters' do
|
|
91
92
|
expect(@session.find(:css, '#\31 escape\.me').text).to eq('needs escaping')
|
|
92
93
|
expect(@session.find(:css, '.\32 escape').text).to eq('needs escaping')
|
|
93
94
|
end
|
|
95
|
+
|
|
96
|
+
it 'should not warn about locator' do
|
|
97
|
+
expect { @session.find(:css, '#not_on_page') }.to raise_error Capybara::ElementNotFound do |e|
|
|
98
|
+
expect(e.message).not_to match(/you may be passing a CSS selector or XPath expression/)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
94
101
|
end
|
|
95
102
|
|
|
96
|
-
context
|
|
97
|
-
it
|
|
103
|
+
context 'with xpath selectors' do
|
|
104
|
+
it 'should find the first element using the given locator' do
|
|
98
105
|
expect(@session.find(:xpath, '//h1').text).to eq('This is a test')
|
|
99
106
|
expect(@session.find(:xpath, "//input[@id='test_field']").value).to eq('monkey')
|
|
100
107
|
end
|
|
108
|
+
|
|
109
|
+
it 'should warn if passed a non-valid locator type' do
|
|
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
|
+
end
|
|
101
113
|
end
|
|
102
114
|
|
|
103
|
-
context
|
|
104
|
-
it
|
|
115
|
+
context 'with custom selector' do
|
|
116
|
+
it 'should use the custom selector' do
|
|
105
117
|
Capybara.add_selector(:beatle) do
|
|
106
118
|
xpath { |name| ".//*[@id='#{name}']" }
|
|
107
119
|
end
|
|
@@ -110,8 +122,8 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
110
122
|
end
|
|
111
123
|
end
|
|
112
124
|
|
|
113
|
-
context
|
|
114
|
-
it
|
|
125
|
+
context 'with custom selector with custom `match` block' do
|
|
126
|
+
it 'should use the custom selector when locator matches the block' do
|
|
115
127
|
Capybara.add_selector(:beatle) do
|
|
116
128
|
xpath { |num| ".//*[contains(@class, 'beatle')][#{num}]" }
|
|
117
129
|
match { |value| value.is_a?(Integer) }
|
|
@@ -123,7 +135,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
123
135
|
end
|
|
124
136
|
end
|
|
125
137
|
|
|
126
|
-
context
|
|
138
|
+
context 'with custom selector with custom filter' do
|
|
127
139
|
before do
|
|
128
140
|
Capybara.add_selector(:beatle) do
|
|
129
141
|
xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
|
|
@@ -132,12 +144,12 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
132
144
|
end
|
|
133
145
|
end
|
|
134
146
|
|
|
135
|
-
it
|
|
147
|
+
it 'should find elements that match the filter' do
|
|
136
148
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
137
149
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
138
150
|
end
|
|
139
151
|
|
|
140
|
-
it
|
|
152
|
+
it 'ignores filter when it is not given' do
|
|
141
153
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
142
154
|
expect(@session.find(:beatle, 'John').text).to eq('John')
|
|
143
155
|
end
|
|
@@ -147,25 +159,25 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
147
159
|
expect { @session.find(:beatle, 'George', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
|
|
148
160
|
end
|
|
149
161
|
|
|
150
|
-
it
|
|
162
|
+
it 'should not raise an ElementNotFound error from in a filter' do
|
|
151
163
|
expect { @session.find(:beatle, 'John', fail: 'something') }.to raise_error(Capybara::ElementNotFound, /beatle "John"/)
|
|
152
164
|
end
|
|
153
165
|
end
|
|
154
166
|
|
|
155
|
-
context
|
|
167
|
+
context 'with custom selector with custom filter and default' do
|
|
156
168
|
before do
|
|
157
169
|
Capybara.add_selector(:beatle) do
|
|
158
170
|
xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
|
|
159
|
-
node_filter(:type, default:
|
|
171
|
+
node_filter(:type, default: 'drummer') { |node, type| node[:class].split(/\s+/).include?(type) }
|
|
160
172
|
end
|
|
161
173
|
end
|
|
162
174
|
|
|
163
|
-
it
|
|
175
|
+
it 'should find elements that match the filter' do
|
|
164
176
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
165
177
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
166
178
|
end
|
|
167
179
|
|
|
168
|
-
it
|
|
180
|
+
it 'should use default value when filter is not given' do
|
|
169
181
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
170
182
|
expect { @session.find(:beatle, 'John') }.to raise_error(Capybara::ElementNotFound)
|
|
171
183
|
end
|
|
@@ -176,7 +188,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
176
188
|
end
|
|
177
189
|
end
|
|
178
190
|
|
|
179
|
-
context
|
|
191
|
+
context 'with alternate filter set' do
|
|
180
192
|
before do
|
|
181
193
|
Capybara::Selector::FilterSet.add(:value) do
|
|
182
194
|
node_filter(:with) { |node, with| node.value == with.to_s }
|
|
@@ -188,255 +200,346 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
188
200
|
end
|
|
189
201
|
end
|
|
190
202
|
|
|
191
|
-
it
|
|
203
|
+
it 'should allow use of filters from custom filter set' do
|
|
192
204
|
expect(@session.find(:id, 'test_field', filter_set: :value, with: 'monkey').value).to eq('monkey')
|
|
193
205
|
expect { @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
194
206
|
end
|
|
195
207
|
|
|
196
|
-
it
|
|
208
|
+
it 'should allow use of filter set from a different selector' do
|
|
197
209
|
expect(@session.find(:id, 'test_field', filter_set: :field, with: 'monkey').value).to eq('monkey')
|
|
198
210
|
expect { @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
199
211
|
end
|
|
200
212
|
|
|
201
|
-
it
|
|
213
|
+
it 'should allow importing of filter set into selector' do
|
|
202
214
|
expect(@session.find(:id_with_field_filters, 'test_field', with: 'monkey').value).to eq('monkey')
|
|
203
215
|
expect { @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
204
216
|
end
|
|
205
217
|
end
|
|
206
218
|
|
|
207
|
-
context
|
|
219
|
+
context 'with css as default selector' do
|
|
208
220
|
before { Capybara.default_selector = :css }
|
|
209
221
|
|
|
210
|
-
|
|
222
|
+
after { Capybara.default_selector = :xpath }
|
|
223
|
+
|
|
224
|
+
it 'should find the first element using the given locator' do
|
|
211
225
|
expect(@session.find('h1').text).to eq('This is a test')
|
|
212
226
|
expect(@session.find("input[id='test_field']").value).to eq('monkey')
|
|
213
227
|
end
|
|
214
|
-
after { Capybara.default_selector = :xpath }
|
|
215
228
|
end
|
|
216
229
|
|
|
217
|
-
it
|
|
230
|
+
it 'should raise ElementNotFound with a useful default message if nothing was found' do
|
|
218
231
|
expect do
|
|
219
232
|
@session.find(:xpath, '//div[@id="nosuchthing"]').to be_nil
|
|
220
|
-
end.to raise_error(Capybara::ElementNotFound,
|
|
233
|
+
end.to raise_error(Capybara::ElementNotFound, 'Unable to find xpath "//div[@id=\\"nosuchthing\\"]"')
|
|
221
234
|
end
|
|
222
235
|
|
|
223
|
-
|
|
236
|
+
context 'without locator' do
|
|
237
|
+
it 'should not output `nil` in the ElementNotFound message if nothing was found' do
|
|
238
|
+
expect do
|
|
239
|
+
@session.find(:label, text: 'no such thing').to be_nil
|
|
240
|
+
end.to raise_error(Capybara::ElementNotFound, 'Unable to find label')
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it 'should accept an XPath instance' do
|
|
224
245
|
@session.visit('/form')
|
|
225
|
-
@xpath = Capybara::Selector.
|
|
226
|
-
expect(@xpath).to be_a(
|
|
246
|
+
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
|
247
|
+
expect(@xpath).to be_a(XPath::Union)
|
|
227
248
|
expect(@session.find(@xpath).value).to eq('John')
|
|
228
249
|
end
|
|
229
250
|
|
|
230
|
-
context
|
|
231
|
-
it
|
|
232
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
251
|
+
context 'with :exact option' do
|
|
252
|
+
it 'matches exactly when true' do
|
|
253
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('test_field')], exact: true).value).to eq('monkey')
|
|
233
254
|
expect do
|
|
234
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
255
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')], exact: true)
|
|
235
256
|
end.to raise_error(Capybara::ElementNotFound)
|
|
236
257
|
end
|
|
237
258
|
|
|
238
|
-
it
|
|
239
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
240
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
259
|
+
it 'matches loosely when false' do
|
|
260
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('test_field')], exact: false).value).to eq('monkey')
|
|
261
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')], exact: false).value).to eq('monkey')
|
|
241
262
|
end
|
|
242
263
|
|
|
243
|
-
it
|
|
264
|
+
it 'defaults to `Capybara.exact`' do
|
|
244
265
|
Capybara.exact = true
|
|
245
266
|
expect do
|
|
246
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
267
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
247
268
|
end.to raise_error(Capybara::ElementNotFound)
|
|
248
269
|
Capybara.exact = false
|
|
249
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
270
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
250
271
|
end
|
|
251
272
|
|
|
252
|
-
it
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
@session.find(:css, '#test_field', exact: true)
|
|
273
|
+
it 'warns when the option has no effect' do
|
|
274
|
+
expect { @session.find(:css, '#test_field', exact: true) }.to \
|
|
275
|
+
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
|
|
256
276
|
end
|
|
257
277
|
end
|
|
258
278
|
|
|
259
|
-
context
|
|
260
|
-
context
|
|
261
|
-
it
|
|
279
|
+
context 'with :match option' do
|
|
280
|
+
context 'when set to `one`' do
|
|
281
|
+
it 'raises an error when multiple matches exist' do
|
|
262
282
|
expect do
|
|
263
|
-
@session.find(:css,
|
|
283
|
+
@session.find(:css, '.multiple', match: :one)
|
|
264
284
|
end.to raise_error(Capybara::Ambiguous)
|
|
265
285
|
end
|
|
266
|
-
|
|
286
|
+
|
|
287
|
+
it 'raises an error even if there the match is exact and the others are inexact' do
|
|
267
288
|
expect do
|
|
268
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
289
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], exact: false, match: :one)
|
|
269
290
|
end.to raise_error(Capybara::Ambiguous)
|
|
270
291
|
end
|
|
271
|
-
|
|
272
|
-
|
|
292
|
+
|
|
293
|
+
it 'returns the element if there is only one' do
|
|
294
|
+
expect(@session.find(:css, '.singular', match: :one).text).to eq('singular')
|
|
273
295
|
end
|
|
274
|
-
|
|
296
|
+
|
|
297
|
+
it 'raises an error if there is no match' do
|
|
275
298
|
expect do
|
|
276
|
-
@session.find(:css,
|
|
299
|
+
@session.find(:css, '.does-not-exist', match: :one)
|
|
277
300
|
end.to raise_error(Capybara::ElementNotFound)
|
|
278
301
|
end
|
|
279
302
|
end
|
|
280
303
|
|
|
281
|
-
context
|
|
282
|
-
it
|
|
283
|
-
expect(@session.find(:css,
|
|
304
|
+
context 'when set to `first`' do
|
|
305
|
+
it 'returns the first matched element' do
|
|
306
|
+
expect(@session.find(:css, '.multiple', match: :first).text).to eq('multiple one')
|
|
284
307
|
end
|
|
285
|
-
|
|
308
|
+
|
|
309
|
+
it 'raises an error if there is no match' do
|
|
286
310
|
expect do
|
|
287
|
-
@session.find(:css,
|
|
311
|
+
@session.find(:css, '.does-not-exist', match: :first)
|
|
288
312
|
end.to raise_error(Capybara::ElementNotFound)
|
|
289
313
|
end
|
|
290
314
|
end
|
|
291
315
|
|
|
292
|
-
context
|
|
293
|
-
context
|
|
294
|
-
it
|
|
316
|
+
context 'when set to `smart`' do
|
|
317
|
+
context 'and `exact` set to `false`' do
|
|
318
|
+
it 'raises an error when there are multiple exact matches' do
|
|
295
319
|
expect do
|
|
296
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
320
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: false)
|
|
297
321
|
end.to raise_error(Capybara::Ambiguous)
|
|
298
322
|
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
|
|
324
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
325
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: false)
|
|
326
|
+
expect(result.text).to eq('almost singular')
|
|
302
327
|
end
|
|
303
|
-
|
|
328
|
+
|
|
329
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
304
330
|
expect do
|
|
305
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
331
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: false)
|
|
306
332
|
end.to raise_error(Capybara::Ambiguous)
|
|
307
333
|
end
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
334
|
+
|
|
335
|
+
it 'finds a single inexact match' do
|
|
336
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: false)
|
|
337
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
311
338
|
end
|
|
312
|
-
|
|
339
|
+
|
|
340
|
+
it 'raises an error if there is no match' do
|
|
313
341
|
expect do
|
|
314
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
342
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: false)
|
|
315
343
|
end.to raise_error(Capybara::ElementNotFound)
|
|
316
344
|
end
|
|
317
345
|
end
|
|
318
346
|
|
|
319
|
-
context
|
|
320
|
-
it
|
|
347
|
+
context 'with `exact` set to `true`' do
|
|
348
|
+
it 'raises an error when there are multiple exact matches' do
|
|
321
349
|
expect do
|
|
322
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
350
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: true)
|
|
323
351
|
end.to raise_error(Capybara::Ambiguous)
|
|
324
352
|
end
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
353
|
+
|
|
354
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
355
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: true)
|
|
356
|
+
expect(result.text).to eq('almost singular')
|
|
328
357
|
end
|
|
329
|
-
|
|
358
|
+
|
|
359
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
330
360
|
expect do
|
|
331
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
361
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: true)
|
|
332
362
|
end.to raise_error(Capybara::ElementNotFound)
|
|
333
363
|
end
|
|
334
|
-
|
|
364
|
+
|
|
365
|
+
it 'raises an error when there is a single inexact matches' do
|
|
335
366
|
expect do
|
|
336
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
367
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: true)
|
|
337
368
|
end.to raise_error(Capybara::ElementNotFound)
|
|
338
369
|
end
|
|
339
|
-
|
|
370
|
+
|
|
371
|
+
it 'raises an error if there is no match' do
|
|
340
372
|
expect do
|
|
341
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
373
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: true)
|
|
342
374
|
end.to raise_error(Capybara::ElementNotFound)
|
|
343
375
|
end
|
|
344
376
|
end
|
|
345
377
|
end
|
|
346
378
|
|
|
347
|
-
context
|
|
348
|
-
context
|
|
349
|
-
it
|
|
350
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
351
|
-
expect(result.text).to eq(
|
|
379
|
+
context 'when set to `prefer_exact`' do
|
|
380
|
+
context 'and `exact` set to `false`' do
|
|
381
|
+
it 'picks the first one when there are multiple exact matches' do
|
|
382
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: false)
|
|
383
|
+
expect(result.text).to eq('multiple one')
|
|
352
384
|
end
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
385
|
+
|
|
386
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
387
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: false)
|
|
388
|
+
expect(result.text).to eq('almost singular')
|
|
356
389
|
end
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
390
|
+
|
|
391
|
+
it 'picks the first one when there are multiple inexact matches' do
|
|
392
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: false)
|
|
393
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
360
394
|
end
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
395
|
+
|
|
396
|
+
it 'finds a single inexact match' do
|
|
397
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: false)
|
|
398
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
364
399
|
end
|
|
365
|
-
|
|
400
|
+
|
|
401
|
+
it 'raises an error if there is no match' do
|
|
366
402
|
expect do
|
|
367
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
403
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: false)
|
|
368
404
|
end.to raise_error(Capybara::ElementNotFound)
|
|
369
405
|
end
|
|
370
406
|
end
|
|
371
407
|
|
|
372
|
-
context
|
|
373
|
-
it
|
|
374
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
375
|
-
expect(result.text).to eq(
|
|
408
|
+
context 'with `exact` set to `true`' do
|
|
409
|
+
it 'picks the first one when there are multiple exact matches' do
|
|
410
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: true)
|
|
411
|
+
expect(result.text).to eq('multiple one')
|
|
376
412
|
end
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
413
|
+
|
|
414
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
415
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: true)
|
|
416
|
+
expect(result.text).to eq('almost singular')
|
|
380
417
|
end
|
|
381
|
-
|
|
418
|
+
|
|
419
|
+
it 'raises an error if there are multiple inexact matches' do
|
|
382
420
|
expect do
|
|
383
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
421
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: true)
|
|
384
422
|
end.to raise_error(Capybara::ElementNotFound)
|
|
385
423
|
end
|
|
386
|
-
|
|
424
|
+
|
|
425
|
+
it 'raises an error if there is a single inexact match' do
|
|
387
426
|
expect do
|
|
388
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
427
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: true)
|
|
389
428
|
end.to raise_error(Capybara::ElementNotFound)
|
|
390
429
|
end
|
|
391
|
-
|
|
430
|
+
|
|
431
|
+
it 'raises an error if there is no match' do
|
|
392
432
|
expect do
|
|
393
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
433
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: true)
|
|
394
434
|
end.to raise_error(Capybara::ElementNotFound)
|
|
395
435
|
end
|
|
396
436
|
end
|
|
397
437
|
end
|
|
398
438
|
|
|
399
|
-
it
|
|
439
|
+
it 'defaults to `Capybara.match`' do
|
|
400
440
|
Capybara.match = :one
|
|
401
441
|
expect do
|
|
402
|
-
@session.find(:css,
|
|
442
|
+
@session.find(:css, '.multiple')
|
|
403
443
|
end.to raise_error(Capybara::Ambiguous)
|
|
404
444
|
Capybara.match = :first
|
|
405
|
-
expect(@session.find(:css,
|
|
445
|
+
expect(@session.find(:css, '.multiple').text).to eq('multiple one')
|
|
406
446
|
end
|
|
407
447
|
|
|
408
|
-
it
|
|
448
|
+
it 'raises an error when unknown option given' do
|
|
409
449
|
expect do
|
|
410
|
-
@session.find(:css,
|
|
450
|
+
@session.find(:css, '.singular', match: :schmoo)
|
|
411
451
|
end.to raise_error(ArgumentError)
|
|
412
452
|
end
|
|
413
453
|
end
|
|
414
454
|
|
|
415
|
-
it
|
|
455
|
+
it 'supports a custom filter block' do
|
|
416
456
|
expect(@session.find(:css, 'input', &:disabled?)[:name]).to eq('disabled_text')
|
|
417
457
|
end
|
|
418
458
|
|
|
419
|
-
context
|
|
459
|
+
context 'with spatial filters', requires: [:spatial] do
|
|
460
|
+
before do
|
|
461
|
+
@session.visit('/spatial')
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
let :center do
|
|
465
|
+
@session.find(:css, 'div.center')
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it 'should find an element above another element' do
|
|
469
|
+
expect(@session.find(:css, 'div:not(.corner)', above: center).text).to eq('2')
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it 'should find an element below another element' do
|
|
473
|
+
expect(@session.find(:css, 'div:not(.corner):not(.footer)', below: center).text).to eq('8')
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it 'should find an element left of another element' do
|
|
477
|
+
expect(@session.find(:css, 'div:not(.corner)', left_of: center).text).to eq('4')
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
it 'should find an element right of another element' do
|
|
481
|
+
expect(@session.find(:css, 'div:not(.corner)', right_of: center).text).to eq('6')
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it 'should combine spatial filters' do
|
|
485
|
+
expect(@session.find(:css, 'div', left_of: center, above: center).text).to eq('1')
|
|
486
|
+
expect(@session.find(:css, 'div', right_of: center, below: center).text).to eq('9')
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it 'should find an element "near" another element' do
|
|
490
|
+
expect(@session.find(:css, 'div.distance', near: center).text).to eq('2')
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
context 'within a scope' do
|
|
420
495
|
before do
|
|
421
496
|
@session.visit('/with_scope')
|
|
422
497
|
end
|
|
423
498
|
|
|
424
|
-
it
|
|
499
|
+
it 'should find the an element using the given locator' do
|
|
425
500
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
426
501
|
expect(@session.find('.//li[1]').text).to match(/With Simple HTML/)
|
|
427
502
|
end
|
|
428
503
|
end
|
|
429
504
|
|
|
430
|
-
it
|
|
505
|
+
it 'should support pseudo selectors' do
|
|
431
506
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
432
507
|
expect(@session.find(:css, 'input:disabled').value).to eq('James')
|
|
433
508
|
end
|
|
434
509
|
end
|
|
435
510
|
end
|
|
436
511
|
|
|
437
|
-
it
|
|
512
|
+
it 'should raise if selector type is unknown' do
|
|
438
513
|
expect do
|
|
439
514
|
@session.find(:unknown, '//h1')
|
|
440
515
|
end.to raise_error(ArgumentError)
|
|
441
516
|
end
|
|
517
|
+
|
|
518
|
+
context 'with Capybara.test_id' do
|
|
519
|
+
it 'should not match on it when nil' do
|
|
520
|
+
Capybara.test_id = nil
|
|
521
|
+
expect(@session).not_to have_field('test_id')
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
it 'should work with the attribute set to `data-test-id` attribute' do
|
|
525
|
+
Capybara.test_id = 'data-test-id'
|
|
526
|
+
expect(@session.find(:field, 'test_id')[:id]).to eq 'test_field'
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it 'should use a different attribute if set' do
|
|
530
|
+
Capybara.test_id = 'data-other-test-id'
|
|
531
|
+
expect(@session.find(:field, 'test_id')[:id]).to eq 'normal'
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
it 'should find a link with the test_id' do
|
|
535
|
+
Capybara.test_id = 'data-test-id'
|
|
536
|
+
expect(@session.find(:link, 'test-foo')[:id]).to eq 'foo'
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
it 'should warn if passed count options' do
|
|
541
|
+
allow(Capybara::Helpers).to receive(:warn)
|
|
542
|
+
@session.find('//h1', count: 44)
|
|
543
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/'find' does not support count options/)
|
|
544
|
+
end
|
|
442
545
|
end
|