capybara 2.18.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 -1
- data/History.md +945 -12
- data/License.txt +1 -1
- data/README.md +264 -90
- data/lib/capybara/config.rb +29 -57
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +35 -18
- data/lib/capybara/driver/node.rb +40 -10
- data/lib/capybara/dsl.rb +10 -7
- data/lib/capybara/helpers.rb +70 -31
- data/lib/capybara/minitest/spec.rb +185 -83
- data/lib/capybara/minitest.rb +232 -112
- data/lib/capybara/node/actions.rb +274 -171
- data/lib/capybara/node/base.rb +42 -34
- data/lib/capybara/node/document.rb +15 -3
- data/lib/capybara/node/document_matchers.rb +19 -21
- data/lib/capybara/node/element.rb +362 -135
- data/lib/capybara/node/finders.rb +151 -137
- data/lib/capybara/node/matchers.rb +394 -209
- data/lib/capybara/node/simple.rb +59 -26
- 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 +12 -9
- data/lib/capybara/queries/base_query.rb +39 -28
- data/lib/capybara/queries/current_path_query.rb +21 -27
- data/lib/capybara/queries/match_query.rb +14 -7
- data/lib/capybara/queries/selector_query.rb +659 -149
- data/lib/capybara/queries/sibling_query.rb +11 -9
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +56 -38
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +114 -42
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +22 -17
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +93 -58
- data/lib/capybara/rack_test/node.rb +184 -81
- data/lib/capybara/rails.rb +3 -7
- 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 +97 -63
- data/lib/capybara/rspec/features.rb +17 -50
- data/lib/capybara/rspec/matcher_proxies.rb +52 -15
- 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 +146 -310
- data/lib/capybara/rspec.rb +7 -11
- 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 +85 -13
- 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 +2 -17
- data/lib/capybara/selector/filter_set.rb +80 -33
- data/lib/capybara/selector/filters/base.rb +50 -6
- data/lib/capybara/selector/filters/expression_filter.rb +8 -26
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -12
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +93 -210
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +475 -523
- 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 +298 -267
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- 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 +517 -145
- 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 +80 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +59 -67
- data/lib/capybara/session/config.rb +81 -67
- data/lib/capybara/session/matchers.rb +28 -20
- data/lib/capybara/session.rb +337 -365
- 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 +151 -12
- data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +161 -57
- data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +22 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +117 -55
- data/lib/capybara/spec/session/choose_spec.rb +64 -31
- data/lib/capybara/spec/session/click_button_spec.rb +231 -173
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
- data/lib/capybara/spec/session/click_link_spec.rb +93 -58
- data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
- data/lib/capybara/spec/session/current_url_spec.rb +57 -39
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
- data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
- data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
- data/lib/capybara/spec/session/find_button_spec.rb +25 -24
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +37 -41
- data/lib/capybara/spec/session/find_link_spec.rb +46 -17
- data/lib/capybara/spec/session/find_spec.rb +260 -145
- data/lib/capybara/spec/session/first_spec.rb +80 -52
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +33 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
- data/lib/capybara/spec/session/go_back_spec.rb +2 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +31 -31
- 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 +100 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +139 -59
- data/lib/capybara/spec/session/has_link_spec.rb +47 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
- data/lib/capybara/spec/session/has_select_spec.rb +107 -72
- data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +183 -5
- data/lib/capybara/spec/session/has_text_spec.rb +106 -62
- data/lib/capybara/spec/session/has_title_spec.rb +20 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +1024 -153
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +12 -6
- data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- 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 +107 -81
- data/lib/capybara/spec/session/selectors_spec.rb +52 -19
- data/lib/capybara/spec/session/sibling_spec.rb +10 -10
- data/lib/capybara/spec/session/text_spec.rb +37 -21
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
- data/lib/capybara/spec/session/unselect_spec.rb +39 -38
- data/lib/capybara/spec/session/visit_spec.rb +85 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
- data/lib/capybara/spec/session/window/window_spec.rb +97 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
- data/lib/capybara/spec/session/within_spec.rb +83 -44
- data/lib/capybara/spec/spec_helper.rb +54 -44
- data/lib/capybara/spec/test_app.rb +158 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +163 -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 +68 -1
- data/lib/capybara/spec/views/with_animation.erb +81 -0
- 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 +69 -12
- 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 +30 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +21 -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 +5 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +36 -34
- data/lib/capybara.rb +134 -107
- data/spec/basic_node_spec.rb +60 -34
- data/spec/capybara_spec.rb +63 -88
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +85 -64
- data/spec/filter_set_spec.rb +27 -9
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
- data/spec/minitest_spec.rb +52 -7
- data/spec/minitest_spec_spec.rb +94 -63
- data/spec/per_session_config_spec.rb +14 -13
- data/spec/rack_test_spec.rb +194 -125
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +111 -50
- data/spec/rspec/features_spec.rb +37 -31
- data/spec/rspec/scenarios_spec.rb +10 -8
- data/spec/rspec/shared_spec_matchers.rb +473 -422
- data/spec/rspec/views_spec.rb +5 -3
- data/spec/rspec_matchers_spec.rb +52 -11
- data/spec/rspec_spec.rb +109 -89
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +397 -68
- data/spec/selenium_spec_chrome.rb +187 -40
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +60 -0
- data/spec/selenium_spec_firefox.rb +201 -41
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +149 -0
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +213 -102
- data/spec/session_spec.rb +53 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +473 -122
- data/spec/spec_helper.rb +126 -7
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +355 -73
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/rspec/compound.rb +0 -95
- data/lib/capybara/spec/session/assert_current_path.rb +0 -72
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -234
- 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 -127
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
Capybara::SpecHelper.spec '#find' do
|
|
3
4
|
before do
|
|
4
5
|
@session.visit('/with_html')
|
|
@@ -8,66 +9,67 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
8
9
|
Capybara::Selector.remove(:monkey)
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
it
|
|
12
|
+
it 'should find the first element using the given locator' do
|
|
12
13
|
expect(@session.find('//h1').text).to eq('This is a test')
|
|
13
14
|
expect(@session.find("//input[@id='test_field']").value).to eq('monkey')
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
it
|
|
17
|
+
it 'should find the first element using the given locator and options' do
|
|
17
18
|
expect(@session.find('//a', text: 'Redirect')[:id]).to eq('red')
|
|
18
19
|
expect(@session.find(:css, 'a', text: 'A link came first')[:title]).to eq('twas a fine link')
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
it
|
|
22
|
+
it 'should raise an error if there are multiple matches' do
|
|
22
23
|
expect { @session.find('//a') }.to raise_error(Capybara::Ambiguous)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
it
|
|
26
|
+
it 'should wait for asynchronous load', requires: [:js] do
|
|
27
|
+
Capybara.default_max_wait_time = 2
|
|
26
28
|
@session.visit('/with_js')
|
|
27
29
|
@session.click_link('Click me')
|
|
28
|
-
expect(@session.find(:css,
|
|
30
|
+
expect(@session.find(:css, 'a#has-been-clicked').text).to include('Has been clicked')
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
context
|
|
33
|
+
context 'with :text option' do
|
|
32
34
|
it "casts text's argument to string" do
|
|
33
|
-
expect(@session.find(:css, '.number', text: 42)).to have_content(
|
|
35
|
+
expect(@session.find(:css, '.number', text: 42)).to have_content('42')
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
context
|
|
38
|
-
it
|
|
39
|
+
context 'with :wait option', requires: [:js] do
|
|
40
|
+
it 'should not wait for asynchronous load when `false` given' do
|
|
39
41
|
@session.visit('/with_js')
|
|
40
42
|
@session.click_link('Click me')
|
|
41
43
|
expect do
|
|
42
|
-
@session.find(:css,
|
|
44
|
+
@session.find(:css, 'a#has-been-clicked', wait: false)
|
|
43
45
|
end.to raise_error(Capybara::ElementNotFound)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
it
|
|
48
|
+
it 'should not find element if it appears after given wait duration' do
|
|
47
49
|
@session.visit('/with_js')
|
|
48
50
|
@session.click_link('Slowly')
|
|
49
51
|
expect do
|
|
50
|
-
@session.find(:css,
|
|
52
|
+
@session.find(:css, 'a#slow-clicked', wait: 0.2)
|
|
51
53
|
end.to raise_error(Capybara::ElementNotFound)
|
|
52
54
|
end
|
|
53
55
|
|
|
54
|
-
it
|
|
56
|
+
it 'should find element if it appears before given wait duration' do
|
|
55
57
|
@session.visit('/with_js')
|
|
56
58
|
@session.click_link('Click me')
|
|
57
|
-
expect(@session.find(:css,
|
|
59
|
+
expect(@session.find(:css, 'a#has-been-clicked', wait: 3.0).text).to include('Has been clicked')
|
|
58
60
|
end
|
|
59
61
|
end
|
|
60
62
|
|
|
61
|
-
context
|
|
63
|
+
context 'with frozen time', requires: [:js] do
|
|
62
64
|
if defined?(Process::CLOCK_MONOTONIC)
|
|
63
|
-
it
|
|
65
|
+
it 'will time out even if time is frozen' do
|
|
64
66
|
@session.visit('/with_js')
|
|
65
67
|
now = Time.now
|
|
66
68
|
allow(Time).to receive(:now).and_return(now)
|
|
67
69
|
expect { @session.find('//isnotthere') }.to raise_error(Capybara::ElementNotFound)
|
|
68
70
|
end
|
|
69
71
|
else
|
|
70
|
-
it
|
|
72
|
+
it 'raises an error suggesting that Capybara is stuck in time' do
|
|
71
73
|
@session.visit('/with_js')
|
|
72
74
|
now = Time.now
|
|
73
75
|
allow(Time).to receive(:now).and_return(now)
|
|
@@ -76,26 +78,42 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
context
|
|
80
|
-
it
|
|
81
|
+
context 'with css selectors' do
|
|
82
|
+
it 'should find the first element using the given locator' do
|
|
81
83
|
expect(@session.find(:css, 'h1').text).to eq('This is a test')
|
|
82
84
|
expect(@session.find(:css, "input[id='test_field']").value).to eq('monkey')
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
it
|
|
87
|
+
it 'should support pseudo selectors' do
|
|
86
88
|
expect(@session.find(:css, 'input:disabled').value).to eq('This is disabled')
|
|
87
89
|
end
|
|
90
|
+
|
|
91
|
+
it 'should support escaping characters' do
|
|
92
|
+
expect(@session.find(:css, '#\31 escape\.me').text).to eq('needs escaping')
|
|
93
|
+
expect(@session.find(:css, '.\32 escape').text).to eq('needs escaping')
|
|
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
|
|
88
101
|
end
|
|
89
102
|
|
|
90
|
-
context
|
|
91
|
-
it
|
|
103
|
+
context 'with xpath selectors' do
|
|
104
|
+
it 'should find the first element using the given locator' do
|
|
92
105
|
expect(@session.find(:xpath, '//h1').text).to eq('This is a test')
|
|
93
106
|
expect(@session.find(:xpath, "//input[@id='test_field']").value).to eq('monkey')
|
|
94
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
|
|
95
113
|
end
|
|
96
114
|
|
|
97
|
-
context
|
|
98
|
-
it
|
|
115
|
+
context 'with custom selector' do
|
|
116
|
+
it 'should use the custom selector' do
|
|
99
117
|
Capybara.add_selector(:beatle) do
|
|
100
118
|
xpath { |name| ".//*[@id='#{name}']" }
|
|
101
119
|
end
|
|
@@ -104,8 +122,8 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
104
122
|
end
|
|
105
123
|
end
|
|
106
124
|
|
|
107
|
-
context
|
|
108
|
-
it
|
|
125
|
+
context 'with custom selector with custom `match` block' do
|
|
126
|
+
it 'should use the custom selector when locator matches the block' do
|
|
109
127
|
Capybara.add_selector(:beatle) do
|
|
110
128
|
xpath { |num| ".//*[contains(@class, 'beatle')][#{num}]" }
|
|
111
129
|
match { |value| value.is_a?(Integer) }
|
|
@@ -117,20 +135,21 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
117
135
|
end
|
|
118
136
|
end
|
|
119
137
|
|
|
120
|
-
context
|
|
138
|
+
context 'with custom selector with custom filter' do
|
|
121
139
|
before do
|
|
122
140
|
Capybara.add_selector(:beatle) do
|
|
123
141
|
xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
|
|
124
|
-
|
|
142
|
+
node_filter(:type) { |node, type| node[:class].split(/\s+/).include?(type) }
|
|
143
|
+
node_filter(:fail) { |_node, _val| raise Capybara::ElementNotFound, 'fail' }
|
|
125
144
|
end
|
|
126
145
|
end
|
|
127
146
|
|
|
128
|
-
it
|
|
147
|
+
it 'should find elements that match the filter' do
|
|
129
148
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
130
149
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
131
150
|
end
|
|
132
151
|
|
|
133
|
-
it
|
|
152
|
+
it 'ignores filter when it is not given' do
|
|
134
153
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
135
154
|
expect(@session.find(:beatle, 'John').text).to eq('John')
|
|
136
155
|
end
|
|
@@ -139,22 +158,26 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
139
158
|
expect { @session.find(:beatle, 'John', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
|
|
140
159
|
expect { @session.find(:beatle, 'George', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
|
|
141
160
|
end
|
|
161
|
+
|
|
162
|
+
it 'should not raise an ElementNotFound error from in a filter' do
|
|
163
|
+
expect { @session.find(:beatle, 'John', fail: 'something') }.to raise_error(Capybara::ElementNotFound, /beatle "John"/)
|
|
164
|
+
end
|
|
142
165
|
end
|
|
143
166
|
|
|
144
|
-
context
|
|
167
|
+
context 'with custom selector with custom filter and default' do
|
|
145
168
|
before do
|
|
146
169
|
Capybara.add_selector(:beatle) do
|
|
147
170
|
xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
|
|
148
|
-
|
|
171
|
+
node_filter(:type, default: 'drummer') { |node, type| node[:class].split(/\s+/).include?(type) }
|
|
149
172
|
end
|
|
150
173
|
end
|
|
151
174
|
|
|
152
|
-
it
|
|
175
|
+
it 'should find elements that match the filter' do
|
|
153
176
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
154
177
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
155
178
|
end
|
|
156
179
|
|
|
157
|
-
it
|
|
180
|
+
it 'should use default value when filter is not given' do
|
|
158
181
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
159
182
|
expect { @session.find(:beatle, 'John') }.to raise_error(Capybara::ElementNotFound)
|
|
160
183
|
end
|
|
@@ -165,10 +188,10 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
165
188
|
end
|
|
166
189
|
end
|
|
167
190
|
|
|
168
|
-
context
|
|
191
|
+
context 'with alternate filter set' do
|
|
169
192
|
before do
|
|
170
193
|
Capybara::Selector::FilterSet.add(:value) do
|
|
171
|
-
|
|
194
|
+
node_filter(:with) { |node, with| node.value == with.to_s }
|
|
172
195
|
end
|
|
173
196
|
|
|
174
197
|
Capybara.add_selector(:id_with_field_filters) do
|
|
@@ -177,254 +200,346 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
177
200
|
end
|
|
178
201
|
end
|
|
179
202
|
|
|
180
|
-
it
|
|
203
|
+
it 'should allow use of filters from custom filter set' do
|
|
181
204
|
expect(@session.find(:id, 'test_field', filter_set: :value, with: 'monkey').value).to eq('monkey')
|
|
182
|
-
expect{ @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
205
|
+
expect { @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
183
206
|
end
|
|
184
207
|
|
|
185
|
-
it
|
|
208
|
+
it 'should allow use of filter set from a different selector' do
|
|
186
209
|
expect(@session.find(:id, 'test_field', filter_set: :field, with: 'monkey').value).to eq('monkey')
|
|
187
|
-
expect{ @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
210
|
+
expect { @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
188
211
|
end
|
|
189
212
|
|
|
190
|
-
it
|
|
213
|
+
it 'should allow importing of filter set into selector' do
|
|
191
214
|
expect(@session.find(:id_with_field_filters, 'test_field', with: 'monkey').value).to eq('monkey')
|
|
192
|
-
expect{ @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
215
|
+
expect { @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
193
216
|
end
|
|
194
217
|
end
|
|
195
218
|
|
|
196
|
-
context
|
|
219
|
+
context 'with css as default selector' do
|
|
197
220
|
before { Capybara.default_selector = :css }
|
|
198
|
-
|
|
221
|
+
|
|
222
|
+
after { Capybara.default_selector = :xpath }
|
|
223
|
+
|
|
224
|
+
it 'should find the first element using the given locator' do
|
|
199
225
|
expect(@session.find('h1').text).to eq('This is a test')
|
|
200
226
|
expect(@session.find("input[id='test_field']").value).to eq('monkey')
|
|
201
227
|
end
|
|
202
|
-
after { Capybara.default_selector = :xpath }
|
|
203
228
|
end
|
|
204
229
|
|
|
205
|
-
it
|
|
230
|
+
it 'should raise ElementNotFound with a useful default message if nothing was found' do
|
|
206
231
|
expect do
|
|
207
232
|
@session.find(:xpath, '//div[@id="nosuchthing"]').to be_nil
|
|
208
|
-
end.to raise_error(Capybara::ElementNotFound,
|
|
233
|
+
end.to raise_error(Capybara::ElementNotFound, 'Unable to find xpath "//div[@id=\\"nosuchthing\\"]"')
|
|
234
|
+
end
|
|
235
|
+
|
|
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
|
|
209
242
|
end
|
|
210
243
|
|
|
211
|
-
it
|
|
244
|
+
it 'should accept an XPath instance' do
|
|
212
245
|
@session.visit('/form')
|
|
213
|
-
@xpath = Capybara::Selector.
|
|
214
|
-
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)
|
|
215
248
|
expect(@session.find(@xpath).value).to eq('John')
|
|
216
249
|
end
|
|
217
250
|
|
|
218
|
-
context
|
|
219
|
-
it
|
|
220
|
-
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')
|
|
221
254
|
expect do
|
|
222
|
-
@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)
|
|
223
256
|
end.to raise_error(Capybara::ElementNotFound)
|
|
224
257
|
end
|
|
225
258
|
|
|
226
|
-
it
|
|
227
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
228
|
-
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')
|
|
229
262
|
end
|
|
230
263
|
|
|
231
|
-
it
|
|
264
|
+
it 'defaults to `Capybara.exact`' do
|
|
232
265
|
Capybara.exact = true
|
|
233
266
|
expect do
|
|
234
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
267
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
235
268
|
end.to raise_error(Capybara::ElementNotFound)
|
|
236
269
|
Capybara.exact = false
|
|
237
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
270
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
238
271
|
end
|
|
239
272
|
|
|
240
|
-
it
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
@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
|
|
244
276
|
end
|
|
245
277
|
end
|
|
246
278
|
|
|
247
|
-
context
|
|
248
|
-
context
|
|
249
|
-
it
|
|
279
|
+
context 'with :match option' do
|
|
280
|
+
context 'when set to `one`' do
|
|
281
|
+
it 'raises an error when multiple matches exist' do
|
|
250
282
|
expect do
|
|
251
|
-
@session.find(:css,
|
|
283
|
+
@session.find(:css, '.multiple', match: :one)
|
|
252
284
|
end.to raise_error(Capybara::Ambiguous)
|
|
253
285
|
end
|
|
254
|
-
|
|
286
|
+
|
|
287
|
+
it 'raises an error even if there the match is exact and the others are inexact' do
|
|
255
288
|
expect do
|
|
256
|
-
@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)
|
|
257
290
|
end.to raise_error(Capybara::Ambiguous)
|
|
258
291
|
end
|
|
259
|
-
|
|
260
|
-
|
|
292
|
+
|
|
293
|
+
it 'returns the element if there is only one' do
|
|
294
|
+
expect(@session.find(:css, '.singular', match: :one).text).to eq('singular')
|
|
261
295
|
end
|
|
262
|
-
|
|
296
|
+
|
|
297
|
+
it 'raises an error if there is no match' do
|
|
263
298
|
expect do
|
|
264
|
-
@session.find(:css,
|
|
299
|
+
@session.find(:css, '.does-not-exist', match: :one)
|
|
265
300
|
end.to raise_error(Capybara::ElementNotFound)
|
|
266
301
|
end
|
|
267
302
|
end
|
|
268
303
|
|
|
269
|
-
context
|
|
270
|
-
it
|
|
271
|
-
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')
|
|
272
307
|
end
|
|
273
|
-
|
|
308
|
+
|
|
309
|
+
it 'raises an error if there is no match' do
|
|
274
310
|
expect do
|
|
275
|
-
@session.find(:css,
|
|
311
|
+
@session.find(:css, '.does-not-exist', match: :first)
|
|
276
312
|
end.to raise_error(Capybara::ElementNotFound)
|
|
277
313
|
end
|
|
278
314
|
end
|
|
279
315
|
|
|
280
|
-
context
|
|
281
|
-
context
|
|
282
|
-
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
|
|
283
319
|
expect do
|
|
284
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
320
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: false)
|
|
285
321
|
end.to raise_error(Capybara::Ambiguous)
|
|
286
322
|
end
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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')
|
|
290
327
|
end
|
|
291
|
-
|
|
328
|
+
|
|
329
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
292
330
|
expect do
|
|
293
|
-
@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)
|
|
294
332
|
end.to raise_error(Capybara::Ambiguous)
|
|
295
333
|
end
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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')
|
|
299
338
|
end
|
|
300
|
-
|
|
339
|
+
|
|
340
|
+
it 'raises an error if there is no match' do
|
|
301
341
|
expect do
|
|
302
|
-
@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)
|
|
303
343
|
end.to raise_error(Capybara::ElementNotFound)
|
|
304
344
|
end
|
|
305
345
|
end
|
|
306
346
|
|
|
307
|
-
context
|
|
308
|
-
it
|
|
347
|
+
context 'with `exact` set to `true`' do
|
|
348
|
+
it 'raises an error when there are multiple exact matches' do
|
|
309
349
|
expect do
|
|
310
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
350
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: true)
|
|
311
351
|
end.to raise_error(Capybara::Ambiguous)
|
|
312
352
|
end
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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')
|
|
316
357
|
end
|
|
317
|
-
|
|
358
|
+
|
|
359
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
318
360
|
expect do
|
|
319
|
-
@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)
|
|
320
362
|
end.to raise_error(Capybara::ElementNotFound)
|
|
321
363
|
end
|
|
322
|
-
|
|
364
|
+
|
|
365
|
+
it 'raises an error when there is a single inexact matches' do
|
|
323
366
|
expect do
|
|
324
|
-
@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)
|
|
325
368
|
end.to raise_error(Capybara::ElementNotFound)
|
|
326
369
|
end
|
|
327
|
-
|
|
370
|
+
|
|
371
|
+
it 'raises an error if there is no match' do
|
|
328
372
|
expect do
|
|
329
|
-
@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)
|
|
330
374
|
end.to raise_error(Capybara::ElementNotFound)
|
|
331
375
|
end
|
|
332
376
|
end
|
|
333
377
|
end
|
|
334
378
|
|
|
335
|
-
context
|
|
336
|
-
context
|
|
337
|
-
it
|
|
338
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
339
|
-
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')
|
|
340
384
|
end
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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')
|
|
344
389
|
end
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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')
|
|
348
394
|
end
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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')
|
|
352
399
|
end
|
|
353
|
-
|
|
400
|
+
|
|
401
|
+
it 'raises an error if there is no match' do
|
|
354
402
|
expect do
|
|
355
|
-
@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)
|
|
356
404
|
end.to raise_error(Capybara::ElementNotFound)
|
|
357
405
|
end
|
|
358
406
|
end
|
|
359
407
|
|
|
360
|
-
context
|
|
361
|
-
it
|
|
362
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
363
|
-
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')
|
|
364
412
|
end
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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')
|
|
368
417
|
end
|
|
369
|
-
|
|
418
|
+
|
|
419
|
+
it 'raises an error if there are multiple inexact matches' do
|
|
370
420
|
expect do
|
|
371
|
-
@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)
|
|
372
422
|
end.to raise_error(Capybara::ElementNotFound)
|
|
373
423
|
end
|
|
374
|
-
|
|
424
|
+
|
|
425
|
+
it 'raises an error if there is a single inexact match' do
|
|
375
426
|
expect do
|
|
376
|
-
@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)
|
|
377
428
|
end.to raise_error(Capybara::ElementNotFound)
|
|
378
429
|
end
|
|
379
|
-
|
|
430
|
+
|
|
431
|
+
it 'raises an error if there is no match' do
|
|
380
432
|
expect do
|
|
381
|
-
@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)
|
|
382
434
|
end.to raise_error(Capybara::ElementNotFound)
|
|
383
435
|
end
|
|
384
436
|
end
|
|
385
437
|
end
|
|
386
438
|
|
|
387
|
-
it
|
|
439
|
+
it 'defaults to `Capybara.match`' do
|
|
388
440
|
Capybara.match = :one
|
|
389
441
|
expect do
|
|
390
|
-
@session.find(:css,
|
|
442
|
+
@session.find(:css, '.multiple')
|
|
391
443
|
end.to raise_error(Capybara::Ambiguous)
|
|
392
444
|
Capybara.match = :first
|
|
393
|
-
expect(@session.find(:css,
|
|
445
|
+
expect(@session.find(:css, '.multiple').text).to eq('multiple one')
|
|
394
446
|
end
|
|
395
447
|
|
|
396
|
-
it
|
|
448
|
+
it 'raises an error when unknown option given' do
|
|
397
449
|
expect do
|
|
398
|
-
@session.find(:css,
|
|
450
|
+
@session.find(:css, '.singular', match: :schmoo)
|
|
399
451
|
end.to raise_error(ArgumentError)
|
|
400
452
|
end
|
|
401
453
|
end
|
|
402
454
|
|
|
403
|
-
it
|
|
404
|
-
expect(@session.find(:css, 'input'
|
|
455
|
+
it 'supports a custom filter block' do
|
|
456
|
+
expect(@session.find(:css, 'input', &:disabled?)[:name]).to eq('disabled_text')
|
|
405
457
|
end
|
|
406
458
|
|
|
407
|
-
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
|
|
408
495
|
before do
|
|
409
496
|
@session.visit('/with_scope')
|
|
410
497
|
end
|
|
411
498
|
|
|
412
|
-
it
|
|
499
|
+
it 'should find the an element using the given locator' do
|
|
413
500
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
414
501
|
expect(@session.find('.//li[1]').text).to match(/With Simple HTML/)
|
|
415
502
|
end
|
|
416
503
|
end
|
|
417
504
|
|
|
418
|
-
it
|
|
505
|
+
it 'should support pseudo selectors' do
|
|
419
506
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
420
507
|
expect(@session.find(:css, 'input:disabled').value).to eq('James')
|
|
421
508
|
end
|
|
422
509
|
end
|
|
423
510
|
end
|
|
424
511
|
|
|
425
|
-
it
|
|
512
|
+
it 'should raise if selector type is unknown' do
|
|
426
513
|
expect do
|
|
427
514
|
@session.find(:unknown, '//h1')
|
|
428
515
|
end.to raise_error(ArgumentError)
|
|
429
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
|
|
430
545
|
end
|