capybara 3.0.0 → 3.36.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 +777 -10
- data/License.txt +1 -1
- data/README.md +75 -58
- data/lib/capybara/config.rb +29 -10
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +22 -4
- data/lib/capybara/driver/node.rb +34 -9
- data/lib/capybara/dsl.rb +14 -6
- data/lib/capybara/helpers.rb +52 -7
- data/lib/capybara/minitest/spec.rb +173 -84
- data/lib/capybara/minitest.rb +250 -144
- data/lib/capybara/node/actions.rb +248 -124
- data/lib/capybara/node/base.rb +34 -20
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +13 -15
- data/lib/capybara/node/element.rb +339 -113
- data/lib/capybara/node/finders.rb +95 -82
- data/lib/capybara/node/matchers.rb +338 -157
- data/lib/capybara/node/simple.rb +54 -15
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +9 -10
- data/lib/capybara/queries/base_query.rb +25 -18
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +11 -0
- data/lib/capybara/queries/selector_query.rb +600 -103
- data/lib/capybara/queries/sibling_query.rb +9 -7
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +40 -22
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +47 -28
- data/lib/capybara/rack_test/driver.rb +12 -3
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +53 -50
- data/lib/capybara/rack_test/node.rb +114 -37
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/registration_container.rb +44 -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 +45 -0
- data/lib/capybara/result.rb +86 -52
- data/lib/capybara/rspec/features.rb +8 -10
- data/lib/capybara/rspec/matcher_proxies.rb +39 -18
- data/lib/capybara/rspec/matchers/base.rb +111 -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 +77 -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 +138 -316
- data/lib/capybara/rspec.rb +3 -2
- 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 +89 -12
- 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 +54 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +279 -0
- data/lib/capybara/selector/filter.rb +1 -0
- data/lib/capybara/selector/filter_set.rb +72 -27
- data/lib/capybara/selector/filters/base.rb +45 -2
- data/lib/capybara/selector/filters/expression_filter.rb +5 -6
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +18 -4
- data/lib/capybara/selector/regexp_disassembler.rb +214 -0
- data/lib/capybara/selector/selector.rb +85 -200
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +226 -537
- 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 +296 -238
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -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 +228 -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/logger_suppressor.rb +40 -0
- data/lib/capybara/selenium/node.rb +436 -166
- data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -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/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/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 +69 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +58 -67
- data/lib/capybara/session/config.rb +38 -6
- data/lib/capybara/session/matchers.rb +26 -19
- data/lib/capybara/session.rb +258 -190
- 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 +122 -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 +135 -42
- 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.rb → assert_current_path_spec.rb} +20 -18
- 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.rb → assert_text_spec.rb} +62 -38
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +120 -72
- data/lib/capybara/spec/session/body_spec.rb +11 -13
- data/lib/capybara/spec/session/check_spec.rb +111 -51
- data/lib/capybara/spec/session/choose_spec.rb +62 -30
- data/lib/capybara/spec/session/click_button_spec.rb +227 -161
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -30
- data/lib/capybara/spec/session/click_link_spec.rb +78 -55
- data/lib/capybara/spec/session/current_scope_spec.rb +7 -7
- data/lib/capybara/spec/session/current_url_spec.rb +44 -37
- 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.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 +8 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +70 -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 +104 -44
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +8 -8
- data/lib/capybara/spec/session/find_field_spec.rb +33 -31
- data/lib/capybara/spec/session/find_link_spec.rb +32 -14
- data/lib/capybara/spec/session/find_spec.rb +236 -141
- data/lib/capybara/spec/session/first_spec.rb +44 -43
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +32 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +44 -19
- 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 +18 -18
- 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 +92 -12
- data/lib/capybara/spec/session/has_css_spec.rb +271 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +48 -33
- data/lib/capybara/spec/session/has_field_spec.rb +137 -58
- data/lib/capybara/spec/session/has_link_spec.rb +30 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +26 -24
- data/lib/capybara/spec/session/has_select_spec.rb +75 -47
- data/lib/capybara/spec/session/has_selector_spec.rb +102 -69
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +170 -4
- data/lib/capybara/spec/session/has_text_spec.rb +108 -52
- 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.rb → headers_spec.rb} +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
- data/lib/capybara/spec/session/node_spec.rb +871 -122
- data/lib/capybara/spec/session/node_wrapper_spec.rb +15 -12
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +52 -37
- data/lib/capybara/spec/session/{response_code.rb → 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 +5 -4
- data/lib/capybara/spec/session/save_page_spec.rb +41 -38
- data/lib/capybara/spec/session/save_screenshot_spec.rb +13 -11
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +117 -0
- data/lib/capybara/spec/session/select_spec.rb +102 -76
- data/lib/capybara/spec/session/selectors_spec.rb +51 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +26 -24
- data/lib/capybara/spec/session/title_spec.rb +8 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +40 -21
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +59 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +22 -19
- data/lib/capybara/spec/session/window/current_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +25 -21
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +10 -5
- data/lib/capybara/spec/session/window/window_spec.rb +88 -54
- data/lib/capybara/spec/session/window/windows_spec.rb +10 -7
- data/lib/capybara/spec/session/window/within_window_spec.rb +17 -16
- data/lib/capybara/spec/session/within_spec.rb +69 -44
- data/lib/capybara/spec/spec_helper.rb +41 -53
- data/lib/capybara/spec/test_app.rb +79 -40
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +134 -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 +43 -10
- 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_other.erb +6 -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 +31 -25
- data/lib/capybara.rb +120 -100
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +54 -52
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +80 -53
- data/spec/filter_set_spec.rb +24 -7
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- 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 +38 -5
- data/spec/minitest_spec_spec.rb +88 -62
- data/spec/per_session_config_spec.rb +5 -5
- data/spec/rack_test_spec.rb +169 -115
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +86 -33
- data/spec/rspec/features_spec.rb +26 -23
- data/spec/rspec/scenarios_spec.rb +8 -4
- data/spec/rspec/shared_spec_matchers.rb +393 -363
- data/spec/rspec/views_spec.rb +4 -3
- data/spec/rspec_matchers_spec.rb +10 -10
- data/spec/rspec_spec.rb +109 -85
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +391 -61
- data/spec/selenium_spec_chrome.rb +180 -41
- data/spec/selenium_spec_chrome_remote.rb +101 -0
- data/spec/selenium_spec_edge.rb +28 -8
- data/spec/selenium_spec_firefox.rb +211 -0
- data/spec/selenium_spec_firefox_remote.rb +80 -0
- data/spec/selenium_spec_ie.rb +127 -11
- data/spec/selenium_spec_safari.rb +156 -0
- data/spec/server_spec.rb +177 -78
- data/spec/session_spec.rb +52 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +455 -123
- data/spec/spec_helper.rb +91 -2
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +343 -42
- 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/rspec/compound.rb +0 -90
- data/lib/capybara/spec/session/assert_selector.rb +0 -149
- 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 -143
|
@@ -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,20 +135,21 @@ 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}')]" }
|
|
130
|
-
|
|
142
|
+
node_filter(:type) { |node, type| node[:class].split(/\s+/).include?(type) }
|
|
143
|
+
node_filter(:fail) { |_node, _val| raise Capybara::ElementNotFound, 'fail' }
|
|
131
144
|
end
|
|
132
145
|
end
|
|
133
146
|
|
|
134
|
-
it
|
|
147
|
+
it 'should find elements that match the filter' do
|
|
135
148
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
136
149
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
137
150
|
end
|
|
138
151
|
|
|
139
|
-
it
|
|
152
|
+
it 'ignores filter when it is not given' do
|
|
140
153
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
141
154
|
expect(@session.find(:beatle, 'John').text).to eq('John')
|
|
142
155
|
end
|
|
@@ -145,22 +158,26 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
145
158
|
expect { @session.find(:beatle, 'John', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
|
|
146
159
|
expect { @session.find(:beatle, 'George', type: 'drummer') }.to raise_error(Capybara::ElementNotFound)
|
|
147
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
|
|
148
165
|
end
|
|
149
166
|
|
|
150
|
-
context
|
|
167
|
+
context 'with custom selector with custom filter and default' do
|
|
151
168
|
before do
|
|
152
169
|
Capybara.add_selector(:beatle) do
|
|
153
170
|
xpath { |name| ".//li[contains(@class, 'beatle')][contains(text(), '#{name}')]" }
|
|
154
|
-
|
|
171
|
+
node_filter(:type, default: 'drummer') { |node, type| node[:class].split(/\s+/).include?(type) }
|
|
155
172
|
end
|
|
156
173
|
end
|
|
157
174
|
|
|
158
|
-
it
|
|
175
|
+
it 'should find elements that match the filter' do
|
|
159
176
|
expect(@session.find(:beatle, 'Paul', type: 'drummer').text).to eq('Paul')
|
|
160
177
|
expect(@session.find(:beatle, 'Ringo', type: 'drummer').text).to eq('Ringo')
|
|
161
178
|
end
|
|
162
179
|
|
|
163
|
-
it
|
|
180
|
+
it 'should use default value when filter is not given' do
|
|
164
181
|
expect(@session.find(:beatle, 'Paul').text).to eq('Paul')
|
|
165
182
|
expect { @session.find(:beatle, 'John') }.to raise_error(Capybara::ElementNotFound)
|
|
166
183
|
end
|
|
@@ -171,10 +188,10 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
171
188
|
end
|
|
172
189
|
end
|
|
173
190
|
|
|
174
|
-
context
|
|
191
|
+
context 'with alternate filter set' do
|
|
175
192
|
before do
|
|
176
193
|
Capybara::Selector::FilterSet.add(:value) do
|
|
177
|
-
|
|
194
|
+
node_filter(:with) { |node, with| node.value == with.to_s }
|
|
178
195
|
end
|
|
179
196
|
|
|
180
197
|
Capybara.add_selector(:id_with_field_filters) do
|
|
@@ -183,254 +200,332 @@ Capybara::SpecHelper.spec '#find' do
|
|
|
183
200
|
end
|
|
184
201
|
end
|
|
185
202
|
|
|
186
|
-
it
|
|
203
|
+
it 'should allow use of filters from custom filter set' do
|
|
187
204
|
expect(@session.find(:id, 'test_field', filter_set: :value, with: 'monkey').value).to eq('monkey')
|
|
188
205
|
expect { @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
189
206
|
end
|
|
190
207
|
|
|
191
|
-
it
|
|
208
|
+
it 'should allow use of filter set from a different selector' do
|
|
192
209
|
expect(@session.find(:id, 'test_field', filter_set: :field, with: 'monkey').value).to eq('monkey')
|
|
193
210
|
expect { @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
194
211
|
end
|
|
195
212
|
|
|
196
|
-
it
|
|
213
|
+
it 'should allow importing of filter set into selector' do
|
|
197
214
|
expect(@session.find(:id_with_field_filters, 'test_field', with: 'monkey').value).to eq('monkey')
|
|
198
215
|
expect { @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
|
199
216
|
end
|
|
200
217
|
end
|
|
201
218
|
|
|
202
|
-
context
|
|
219
|
+
context 'with css as default selector' do
|
|
203
220
|
before { Capybara.default_selector = :css }
|
|
204
|
-
|
|
221
|
+
|
|
222
|
+
after { Capybara.default_selector = :xpath }
|
|
223
|
+
|
|
224
|
+
it 'should find the first element using the given locator' do
|
|
205
225
|
expect(@session.find('h1').text).to eq('This is a test')
|
|
206
226
|
expect(@session.find("input[id='test_field']").value).to eq('monkey')
|
|
207
227
|
end
|
|
208
|
-
after { Capybara.default_selector = :xpath }
|
|
209
228
|
end
|
|
210
229
|
|
|
211
|
-
it
|
|
230
|
+
it 'should raise ElementNotFound with a useful default message if nothing was found' do
|
|
212
231
|
expect do
|
|
213
232
|
@session.find(:xpath, '//div[@id="nosuchthing"]').to be_nil
|
|
214
|
-
end.to raise_error(Capybara::ElementNotFound,
|
|
233
|
+
end.to raise_error(Capybara::ElementNotFound, 'Unable to find xpath "//div[@id=\\"nosuchthing\\"]"')
|
|
215
234
|
end
|
|
216
235
|
|
|
217
|
-
it
|
|
236
|
+
it 'should accept an XPath instance' do
|
|
218
237
|
@session.visit('/form')
|
|
219
|
-
@xpath = Capybara::Selector.
|
|
238
|
+
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
|
220
239
|
expect(@xpath).to be_a(::XPath::Union)
|
|
221
240
|
expect(@session.find(@xpath).value).to eq('John')
|
|
222
241
|
end
|
|
223
242
|
|
|
224
|
-
context
|
|
225
|
-
it
|
|
226
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
243
|
+
context 'with :exact option' do
|
|
244
|
+
it 'matches exactly when true' do
|
|
245
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('test_field')], exact: true).value).to eq('monkey')
|
|
227
246
|
expect do
|
|
228
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
247
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')], exact: true)
|
|
229
248
|
end.to raise_error(Capybara::ElementNotFound)
|
|
230
249
|
end
|
|
231
250
|
|
|
232
|
-
it
|
|
233
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
234
|
-
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
251
|
+
it 'matches loosely when false' do
|
|
252
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('test_field')], exact: false).value).to eq('monkey')
|
|
253
|
+
expect(@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')], exact: false).value).to eq('monkey')
|
|
235
254
|
end
|
|
236
255
|
|
|
237
|
-
it
|
|
256
|
+
it 'defaults to `Capybara.exact`' do
|
|
238
257
|
Capybara.exact = true
|
|
239
258
|
expect do
|
|
240
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
259
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
241
260
|
end.to raise_error(Capybara::ElementNotFound)
|
|
242
261
|
Capybara.exact = false
|
|
243
|
-
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is(
|
|
262
|
+
@session.find(:xpath, XPath.descendant(:input)[XPath.attr(:id).is('est_fiel')])
|
|
244
263
|
end
|
|
245
264
|
|
|
246
|
-
it
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
@session.find(:css, '#test_field', exact: true)
|
|
265
|
+
it 'warns when the option has no effect' do
|
|
266
|
+
expect { @session.find(:css, '#test_field', exact: true) }.to \
|
|
267
|
+
output(/^The :exact option only has an effect on queries using the XPath#is method. Using it with the query "#test_field" has no effect/).to_stderr
|
|
250
268
|
end
|
|
251
269
|
end
|
|
252
270
|
|
|
253
|
-
context
|
|
254
|
-
context
|
|
255
|
-
it
|
|
271
|
+
context 'with :match option' do
|
|
272
|
+
context 'when set to `one`' do
|
|
273
|
+
it 'raises an error when multiple matches exist' do
|
|
256
274
|
expect do
|
|
257
|
-
@session.find(:css,
|
|
275
|
+
@session.find(:css, '.multiple', match: :one)
|
|
258
276
|
end.to raise_error(Capybara::Ambiguous)
|
|
259
277
|
end
|
|
260
|
-
|
|
278
|
+
|
|
279
|
+
it 'raises an error even if there the match is exact and the others are inexact' do
|
|
261
280
|
expect do
|
|
262
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
281
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], exact: false, match: :one)
|
|
263
282
|
end.to raise_error(Capybara::Ambiguous)
|
|
264
283
|
end
|
|
265
|
-
|
|
266
|
-
|
|
284
|
+
|
|
285
|
+
it 'returns the element if there is only one' do
|
|
286
|
+
expect(@session.find(:css, '.singular', match: :one).text).to eq('singular')
|
|
267
287
|
end
|
|
268
|
-
|
|
288
|
+
|
|
289
|
+
it 'raises an error if there is no match' do
|
|
269
290
|
expect do
|
|
270
|
-
@session.find(:css,
|
|
291
|
+
@session.find(:css, '.does-not-exist', match: :one)
|
|
271
292
|
end.to raise_error(Capybara::ElementNotFound)
|
|
272
293
|
end
|
|
273
294
|
end
|
|
274
295
|
|
|
275
|
-
context
|
|
276
|
-
it
|
|
277
|
-
expect(@session.find(:css,
|
|
296
|
+
context 'when set to `first`' do
|
|
297
|
+
it 'returns the first matched element' do
|
|
298
|
+
expect(@session.find(:css, '.multiple', match: :first).text).to eq('multiple one')
|
|
278
299
|
end
|
|
279
|
-
|
|
300
|
+
|
|
301
|
+
it 'raises an error if there is no match' do
|
|
280
302
|
expect do
|
|
281
|
-
@session.find(:css,
|
|
303
|
+
@session.find(:css, '.does-not-exist', match: :first)
|
|
282
304
|
end.to raise_error(Capybara::ElementNotFound)
|
|
283
305
|
end
|
|
284
306
|
end
|
|
285
307
|
|
|
286
|
-
context
|
|
287
|
-
context
|
|
288
|
-
it
|
|
308
|
+
context 'when set to `smart`' do
|
|
309
|
+
context 'and `exact` set to `false`' do
|
|
310
|
+
it 'raises an error when there are multiple exact matches' do
|
|
289
311
|
expect do
|
|
290
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
312
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: false)
|
|
291
313
|
end.to raise_error(Capybara::Ambiguous)
|
|
292
314
|
end
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
315
|
+
|
|
316
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
317
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: false)
|
|
318
|
+
expect(result.text).to eq('almost singular')
|
|
296
319
|
end
|
|
297
|
-
|
|
320
|
+
|
|
321
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
298
322
|
expect do
|
|
299
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
323
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: false)
|
|
300
324
|
end.to raise_error(Capybara::Ambiguous)
|
|
301
325
|
end
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
326
|
+
|
|
327
|
+
it 'finds a single inexact match' do
|
|
328
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: false)
|
|
329
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
305
330
|
end
|
|
306
|
-
|
|
331
|
+
|
|
332
|
+
it 'raises an error if there is no match' do
|
|
307
333
|
expect do
|
|
308
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
334
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: false)
|
|
309
335
|
end.to raise_error(Capybara::ElementNotFound)
|
|
310
336
|
end
|
|
311
337
|
end
|
|
312
338
|
|
|
313
|
-
context
|
|
314
|
-
it
|
|
339
|
+
context 'with `exact` set to `true`' do
|
|
340
|
+
it 'raises an error when there are multiple exact matches' do
|
|
315
341
|
expect do
|
|
316
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
342
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: true)
|
|
317
343
|
end.to raise_error(Capybara::Ambiguous)
|
|
318
344
|
end
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
345
|
+
|
|
346
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
347
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: true)
|
|
348
|
+
expect(result.text).to eq('almost singular')
|
|
322
349
|
end
|
|
323
|
-
|
|
350
|
+
|
|
351
|
+
it 'raises an error when there are multiple inexact matches' do
|
|
324
352
|
expect do
|
|
325
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
353
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: true)
|
|
326
354
|
end.to raise_error(Capybara::ElementNotFound)
|
|
327
355
|
end
|
|
328
|
-
|
|
356
|
+
|
|
357
|
+
it 'raises an error when there is a single inexact matches' do
|
|
329
358
|
expect do
|
|
330
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
359
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: true)
|
|
331
360
|
end.to raise_error(Capybara::ElementNotFound)
|
|
332
361
|
end
|
|
333
|
-
|
|
362
|
+
|
|
363
|
+
it 'raises an error if there is no match' do
|
|
334
364
|
expect do
|
|
335
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
365
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: true)
|
|
336
366
|
end.to raise_error(Capybara::ElementNotFound)
|
|
337
367
|
end
|
|
338
368
|
end
|
|
339
369
|
end
|
|
340
370
|
|
|
341
|
-
context
|
|
342
|
-
context
|
|
343
|
-
it
|
|
344
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
345
|
-
expect(result.text).to eq(
|
|
371
|
+
context 'when set to `prefer_exact`' do
|
|
372
|
+
context 'and `exact` set to `false`' do
|
|
373
|
+
it 'picks the first one when there are multiple exact matches' do
|
|
374
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: false)
|
|
375
|
+
expect(result.text).to eq('multiple one')
|
|
346
376
|
end
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
377
|
+
|
|
378
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
379
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: false)
|
|
380
|
+
expect(result.text).to eq('almost singular')
|
|
350
381
|
end
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
382
|
+
|
|
383
|
+
it 'picks the first one when there are multiple inexact matches' do
|
|
384
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: false)
|
|
385
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
354
386
|
end
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
387
|
+
|
|
388
|
+
it 'finds a single inexact match' do
|
|
389
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: false)
|
|
390
|
+
expect(result.text).to eq('almost singular but not quite')
|
|
358
391
|
end
|
|
359
|
-
|
|
392
|
+
|
|
393
|
+
it 'raises an error if there is no match' do
|
|
360
394
|
expect do
|
|
361
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
395
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: false)
|
|
362
396
|
end.to raise_error(Capybara::ElementNotFound)
|
|
363
397
|
end
|
|
364
398
|
end
|
|
365
399
|
|
|
366
|
-
context
|
|
367
|
-
it
|
|
368
|
-
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
369
|
-
expect(result.text).to eq(
|
|
400
|
+
context 'with `exact` set to `true`' do
|
|
401
|
+
it 'picks the first one when there are multiple exact matches' do
|
|
402
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: true)
|
|
403
|
+
expect(result.text).to eq('multiple one')
|
|
370
404
|
end
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
405
|
+
|
|
406
|
+
it 'finds a single exact match when there also are inexact matches' do
|
|
407
|
+
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: true)
|
|
408
|
+
expect(result.text).to eq('almost singular')
|
|
374
409
|
end
|
|
375
|
-
|
|
410
|
+
|
|
411
|
+
it 'raises an error if there are multiple inexact matches' do
|
|
376
412
|
expect do
|
|
377
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
413
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: true)
|
|
378
414
|
end.to raise_error(Capybara::ElementNotFound)
|
|
379
415
|
end
|
|
380
|
-
|
|
416
|
+
|
|
417
|
+
it 'raises an error if there is a single inexact match' do
|
|
381
418
|
expect do
|
|
382
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
419
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: true)
|
|
383
420
|
end.to raise_error(Capybara::ElementNotFound)
|
|
384
421
|
end
|
|
385
|
-
|
|
422
|
+
|
|
423
|
+
it 'raises an error if there is no match' do
|
|
386
424
|
expect do
|
|
387
|
-
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is(
|
|
425
|
+
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: true)
|
|
388
426
|
end.to raise_error(Capybara::ElementNotFound)
|
|
389
427
|
end
|
|
390
428
|
end
|
|
391
429
|
end
|
|
392
430
|
|
|
393
|
-
it
|
|
431
|
+
it 'defaults to `Capybara.match`' do
|
|
394
432
|
Capybara.match = :one
|
|
395
433
|
expect do
|
|
396
|
-
@session.find(:css,
|
|
434
|
+
@session.find(:css, '.multiple')
|
|
397
435
|
end.to raise_error(Capybara::Ambiguous)
|
|
398
436
|
Capybara.match = :first
|
|
399
|
-
expect(@session.find(:css,
|
|
437
|
+
expect(@session.find(:css, '.multiple').text).to eq('multiple one')
|
|
400
438
|
end
|
|
401
439
|
|
|
402
|
-
it
|
|
440
|
+
it 'raises an error when unknown option given' do
|
|
403
441
|
expect do
|
|
404
|
-
@session.find(:css,
|
|
442
|
+
@session.find(:css, '.singular', match: :schmoo)
|
|
405
443
|
end.to raise_error(ArgumentError)
|
|
406
444
|
end
|
|
407
445
|
end
|
|
408
446
|
|
|
409
|
-
it
|
|
447
|
+
it 'supports a custom filter block' do
|
|
410
448
|
expect(@session.find(:css, 'input', &:disabled?)[:name]).to eq('disabled_text')
|
|
411
449
|
end
|
|
412
450
|
|
|
413
|
-
context
|
|
451
|
+
context 'with spatial filters', requires: [:spatial] do
|
|
452
|
+
before do
|
|
453
|
+
@session.visit('/spatial')
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
let :center do
|
|
457
|
+
@session.find(:css, 'div.center')
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
it 'should find an element above another element' do
|
|
461
|
+
expect(@session.find(:css, 'div:not(.corner)', above: center).text).to eq('2')
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'should find an element below another element' do
|
|
465
|
+
expect(@session.find(:css, 'div:not(.corner):not(.footer)', below: center).text).to eq('8')
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it 'should find an element left of another element' do
|
|
469
|
+
expect(@session.find(:css, 'div:not(.corner)', left_of: center).text).to eq('4')
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it 'should find an element right of another element' do
|
|
473
|
+
expect(@session.find(:css, 'div:not(.corner)', right_of: center).text).to eq('6')
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it 'should combine spatial filters' do
|
|
477
|
+
expect(@session.find(:css, 'div', left_of: center, above: center).text).to eq('1')
|
|
478
|
+
expect(@session.find(:css, 'div', right_of: center, below: center).text).to eq('9')
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
it 'should find an element "near" another element' do
|
|
482
|
+
expect(@session.find(:css, 'div.distance', near: center).text).to eq('2')
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
context 'within a scope' do
|
|
414
487
|
before do
|
|
415
488
|
@session.visit('/with_scope')
|
|
416
489
|
end
|
|
417
490
|
|
|
418
|
-
it
|
|
491
|
+
it 'should find the an element using the given locator' do
|
|
419
492
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
420
493
|
expect(@session.find('.//li[1]').text).to match(/With Simple HTML/)
|
|
421
494
|
end
|
|
422
495
|
end
|
|
423
496
|
|
|
424
|
-
it
|
|
497
|
+
it 'should support pseudo selectors' do
|
|
425
498
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
|
426
499
|
expect(@session.find(:css, 'input:disabled').value).to eq('James')
|
|
427
500
|
end
|
|
428
501
|
end
|
|
429
502
|
end
|
|
430
503
|
|
|
431
|
-
it
|
|
504
|
+
it 'should raise if selector type is unknown' do
|
|
432
505
|
expect do
|
|
433
506
|
@session.find(:unknown, '//h1')
|
|
434
507
|
end.to raise_error(ArgumentError)
|
|
435
508
|
end
|
|
509
|
+
|
|
510
|
+
context 'with Capybara.test_id' do
|
|
511
|
+
it 'should not match on it when nil' do
|
|
512
|
+
Capybara.test_id = nil
|
|
513
|
+
expect(@session).not_to have_field('test_id')
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it 'should work with the attribute set to `data-test-id` attribute' do
|
|
517
|
+
Capybara.test_id = 'data-test-id'
|
|
518
|
+
expect(@session.find(:field, 'test_id')[:id]).to eq 'test_field'
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
it 'should use a different attribute if set' do
|
|
522
|
+
Capybara.test_id = 'data-other-test-id'
|
|
523
|
+
expect(@session.find(:field, 'test_id')[:id]).to eq 'normal'
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
it 'should find a link with the test_id' do
|
|
527
|
+
Capybara.test_id = 'data-test-id'
|
|
528
|
+
expect(@session.find(:link, 'test-foo')[:id]).to eq 'foo'
|
|
529
|
+
end
|
|
530
|
+
end
|
|
436
531
|
end
|