capybara 3.0.0 → 3.36.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -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
@@ -19,41 +19,58 @@ module Capybara
|
|
19
19
|
# This will check if the expression occurs exactly 4 times.
|
20
20
|
#
|
21
21
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
22
|
-
# such as
|
22
|
+
# such as `:text` and `:visible`.
|
23
23
|
#
|
24
24
|
# page.has_selector?('li', text: 'Horse', visible: true)
|
25
25
|
#
|
26
|
-
# has_selector? can also accept XPath expressions generated by the
|
26
|
+
# {#has_selector?} can also accept XPath expressions generated by the
|
27
27
|
# XPath gem:
|
28
28
|
#
|
29
29
|
# page.has_selector?(:xpath, XPath.descendant(:p))
|
30
30
|
#
|
31
31
|
# @param (see Capybara::Node::Finders#all)
|
32
|
-
# @
|
33
|
-
# @option
|
34
|
-
# @option
|
35
|
-
# @option
|
36
|
-
# @option args [Range] :between (nil) Range of times that should contain number of times text occurs
|
32
|
+
# @option options [Integer] :count (nil) Number of matching elements that should exist
|
33
|
+
# @option options [Integer] :minimum (nil) Minimum number of matching elements that should exist
|
34
|
+
# @option options [Integer] :maximum (nil) Maximum number of matching elements that should exist
|
35
|
+
# @option options [Range] :between (nil) Range of number of matching elements that should exist
|
37
36
|
# @return [Boolean] If the expression exists
|
38
37
|
#
|
39
|
-
def has_selector?(*args, &optional_filter_block)
|
40
|
-
assert_selector(*args, &optional_filter_block)
|
41
|
-
rescue Capybara::ExpectationNotMet
|
42
|
-
false
|
38
|
+
def has_selector?(*args, **options, &optional_filter_block)
|
39
|
+
make_predicate(options) { assert_selector(*args, options, &optional_filter_block) }
|
43
40
|
end
|
44
41
|
|
45
42
|
##
|
46
43
|
#
|
47
44
|
# Checks if a given selector is not on the page or a descendant of the current node.
|
48
|
-
# Usage is identical to
|
45
|
+
# Usage is identical to {#has_selector?}.
|
49
46
|
#
|
50
|
-
# @param (see
|
47
|
+
# @param (see #has_selector?)
|
51
48
|
# @return [Boolean]
|
52
49
|
#
|
53
|
-
def has_no_selector?(*args, &optional_filter_block)
|
54
|
-
assert_no_selector(*args, &optional_filter_block)
|
55
|
-
|
56
|
-
|
50
|
+
def has_no_selector?(*args, **options, &optional_filter_block)
|
51
|
+
make_predicate(options) { assert_no_selector(*args, options, &optional_filter_block) }
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
#
|
56
|
+
# Checks if a an element has the specified CSS styles.
|
57
|
+
#
|
58
|
+
# element.matches_style?( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
59
|
+
#
|
60
|
+
# @param styles [Hash]
|
61
|
+
# @return [Boolean] If the styles match
|
62
|
+
#
|
63
|
+
def matches_style?(styles = nil, **options)
|
64
|
+
styles, options = options, {} if styles.nil?
|
65
|
+
make_predicate(options) { assert_matches_style(styles, **options) }
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# @deprecated Use {#matches_style?} instead.
|
70
|
+
#
|
71
|
+
def has_style?(styles = nil, **options)
|
72
|
+
Capybara::Helpers.warn "DEPRECATED: has_style? is deprecated, please use matches_style? : #{Capybara::Helpers.filter_backtrace(caller)}"
|
73
|
+
matches_style?(styles, **options)
|
57
74
|
end
|
58
75
|
|
59
76
|
##
|
@@ -72,15 +89,15 @@ module Capybara
|
|
72
89
|
# This will check if the expression occurs exactly 4 times. See
|
73
90
|
# {Capybara::Node::Finders#all} for other available result size options.
|
74
91
|
#
|
75
|
-
# If a
|
92
|
+
# If a `:count` of 0 is specified, it will behave like {#assert_no_selector};
|
76
93
|
# however, use of that method is preferred over this one.
|
77
94
|
#
|
78
95
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
79
|
-
# such as
|
96
|
+
# such as `:text` and `:visible`.
|
80
97
|
#
|
81
98
|
# page.assert_selector('li', text: 'Horse', visible: true)
|
82
99
|
#
|
83
|
-
#
|
100
|
+
# {#assert_selector} can also accept XPath expressions generated by the
|
84
101
|
# XPath gem:
|
85
102
|
#
|
86
103
|
# page.assert_selector(:xpath, XPath.descendant(:p))
|
@@ -91,76 +108,126 @@ module Capybara
|
|
91
108
|
#
|
92
109
|
def assert_selector(*args, &optional_filter_block)
|
93
110
|
_verify_selector_result(args, optional_filter_block) do |result, query|
|
94
|
-
unless result.matches_count? && (
|
111
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
95
112
|
raise Capybara::ExpectationNotMet, result.failure_message
|
96
113
|
end
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
117
|
+
##
|
118
|
+
#
|
119
|
+
# Asserts that an element has the specified CSS styles.
|
120
|
+
#
|
121
|
+
# element.assert_matches_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
122
|
+
#
|
123
|
+
# @param styles [Hash]
|
124
|
+
# @raise [Capybara::ExpectationNotMet] If the element doesn't have the specified styles
|
125
|
+
#
|
126
|
+
def assert_matches_style(styles = nil, **options)
|
127
|
+
styles, options = options, {} if styles.nil?
|
128
|
+
query_args, query_opts = _set_query_session_options(styles, options)
|
129
|
+
query = Capybara::Queries::StyleQuery.new(*query_args, **query_opts)
|
130
|
+
synchronize(query.wait) do
|
131
|
+
raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
|
132
|
+
end
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# @deprecated Use {#assert_matches_style} instead.
|
138
|
+
#
|
139
|
+
def assert_style(styles = nil, **options)
|
140
|
+
warn 'assert_style is deprecated, please use assert_matches_style instead'
|
141
|
+
assert_matches_style(styles, **options)
|
142
|
+
end
|
143
|
+
|
100
144
|
# Asserts that all of the provided selectors are present on the given page
|
101
145
|
# or descendants of the current node. If options are provided, the assertion
|
102
|
-
# will check that each locator is present with those options as well (other than
|
146
|
+
# will check that each locator is present with those options as well (other than `:wait`).
|
103
147
|
#
|
104
|
-
#
|
105
|
-
#
|
148
|
+
# page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
149
|
+
# page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
|
106
150
|
#
|
107
151
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
108
|
-
# such as
|
152
|
+
# such as `:text` and `:visible`.
|
109
153
|
#
|
110
|
-
# The
|
111
|
-
# within
|
154
|
+
# The `:wait` option applies to all of the selectors as a group, so all of the locators must be present
|
155
|
+
# within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
|
112
156
|
#
|
113
|
-
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, options
|
157
|
+
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
114
158
|
#
|
115
|
-
def assert_all_of_selectors(*args,
|
116
|
-
|
117
|
-
|
118
|
-
synchronize(wait) do
|
119
|
-
args.each do |locator|
|
120
|
-
assert_selector(selector, locator, options, &optional_filter_block)
|
121
|
-
end
|
159
|
+
def assert_all_of_selectors(*args, **options, &optional_filter_block)
|
160
|
+
_verify_multiple(*args, **options) do |selector, locator, opts|
|
161
|
+
assert_selector(selector, locator, opts, &optional_filter_block)
|
122
162
|
end
|
123
163
|
end
|
124
164
|
|
125
165
|
# Asserts that none of the provided selectors are present on the given page
|
126
166
|
# or descendants of the current node. If options are provided, the assertion
|
127
|
-
# will check that each locator is present with those options as well (other than
|
167
|
+
# will check that each locator is not present with those options as well (other than `:wait`).
|
168
|
+
#
|
169
|
+
# page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
170
|
+
# page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
|
171
|
+
#
|
172
|
+
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
173
|
+
# such as `:text` and `:visible`.
|
174
|
+
#
|
175
|
+
# The `:wait` option applies to all of the selectors as a group, so none of the locators must be present
|
176
|
+
# within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
|
177
|
+
#
|
178
|
+
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
179
|
+
#
|
180
|
+
def assert_none_of_selectors(*args, **options, &optional_filter_block)
|
181
|
+
_verify_multiple(*args, **options) do |selector, locator, opts|
|
182
|
+
assert_no_selector(selector, locator, opts, &optional_filter_block)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Asserts that any of the provided selectors are present on the given page
|
187
|
+
# or descendants of the current node. If options are provided, the assertion
|
188
|
+
# will check that each locator is present with those options as well (other than `:wait`).
|
128
189
|
#
|
129
|
-
#
|
130
|
-
#
|
190
|
+
# page.assert_any_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
191
|
+
# page.assert_any_of_selectors(:css, '#my_div', 'a.not_clicked')
|
131
192
|
#
|
132
193
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
133
|
-
# such as
|
194
|
+
# such as `:text` and `:visible`.
|
134
195
|
#
|
135
|
-
# The
|
136
|
-
# within
|
196
|
+
# The `:wait` option applies to all of the selectors as a group, so any of the locators must be present
|
197
|
+
# within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
|
137
198
|
#
|
138
|
-
# @overload
|
199
|
+
# @overload assert_any_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
139
200
|
#
|
140
|
-
def
|
201
|
+
def assert_any_of_selectors(*args, wait: nil, **options, &optional_filter_block)
|
141
202
|
wait = session_options.default_max_wait_time if wait.nil?
|
142
|
-
selector = args
|
203
|
+
selector = extract_selector(args)
|
143
204
|
synchronize(wait) do
|
144
|
-
args.
|
145
|
-
|
205
|
+
res = args.map do |locator|
|
206
|
+
assert_selector(selector, locator, options, &optional_filter_block)
|
207
|
+
break nil
|
208
|
+
rescue Capybara::ExpectationNotMet => e
|
209
|
+
e.message
|
146
210
|
end
|
211
|
+
raise Capybara::ExpectationNotMet, res.join(' or ') if res
|
212
|
+
|
213
|
+
true
|
147
214
|
end
|
148
215
|
end
|
149
216
|
|
150
217
|
##
|
151
218
|
#
|
152
219
|
# Asserts that a given selector is not on the page or a descendant of the current node.
|
153
|
-
# Usage is identical to
|
220
|
+
# Usage is identical to {#assert_selector}.
|
154
221
|
#
|
155
|
-
# Query options such as
|
222
|
+
# Query options such as `:count`, `:minimum`, `:maximum`, and `:between` are
|
156
223
|
# considered to be an integral part of the selector. This will return
|
157
|
-
# true
|
224
|
+
# `true`, for example, if a page contains 4 anchors but the query expects 5:
|
158
225
|
#
|
159
226
|
# page.assert_no_selector('a', minimum: 1) # Found, raises Capybara::ExpectationNotMet
|
160
227
|
# page.assert_no_selector('a', count: 4) # Found, raises Capybara::ExpectationNotMet
|
161
228
|
# page.assert_no_selector('a', count: 5) # Not Found, returns true
|
162
229
|
#
|
163
|
-
# @param (see
|
230
|
+
# @param (see #assert_selector)
|
164
231
|
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
165
232
|
#
|
166
233
|
def assert_no_selector(*args, &optional_filter_block)
|
@@ -170,7 +237,6 @@ module Capybara
|
|
170
237
|
end
|
171
238
|
end
|
172
239
|
end
|
173
|
-
alias_method :refute_selector, :assert_no_selector
|
174
240
|
|
175
241
|
##
|
176
242
|
#
|
@@ -186,11 +252,11 @@ module Capybara
|
|
186
252
|
# This will check if the expression occurs exactly 4 times.
|
187
253
|
#
|
188
254
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
189
|
-
# such as
|
255
|
+
# such as `:text` and `:visible`.
|
190
256
|
#
|
191
257
|
# page.has_xpath?('.//li', text: 'Horse', visible: true)
|
192
258
|
#
|
193
|
-
# has_xpath? can also accept XPath expressions
|
259
|
+
# {#has_xpath?} can also accept XPath expressions generated by the
|
194
260
|
# XPath gem:
|
195
261
|
#
|
196
262
|
# xpath = XPath.generate { |x| x.descendant(:p) }
|
@@ -202,19 +268,19 @@ module Capybara
|
|
202
268
|
# @return [Boolean] If the expression exists
|
203
269
|
#
|
204
270
|
def has_xpath?(path, **options, &optional_filter_block)
|
205
|
-
has_selector?(:xpath, path, options, &optional_filter_block)
|
271
|
+
has_selector?(:xpath, path, **options, &optional_filter_block)
|
206
272
|
end
|
207
273
|
|
208
274
|
##
|
209
275
|
#
|
210
276
|
# Checks if a given XPath expression is not on the page or a descendant of the current node.
|
211
|
-
# Usage is identical to
|
277
|
+
# Usage is identical to {#has_xpath?}.
|
212
278
|
#
|
213
|
-
# @param (see
|
279
|
+
# @param (see #has_xpath?)
|
214
280
|
# @return [Boolean]
|
215
281
|
#
|
216
282
|
def has_no_xpath?(path, **options, &optional_filter_block)
|
217
|
-
has_no_selector?(:xpath, path, options, &optional_filter_block)
|
283
|
+
has_no_selector?(:xpath, path, **options, &optional_filter_block)
|
218
284
|
end
|
219
285
|
|
220
286
|
##
|
@@ -231,7 +297,7 @@ module Capybara
|
|
231
297
|
# This will check if the selector occurs exactly 4 times.
|
232
298
|
#
|
233
299
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
234
|
-
# such as
|
300
|
+
# such as `:text` and `:visible`.
|
235
301
|
#
|
236
302
|
# page.has_css?('li', text: 'Horse', visible: true)
|
237
303
|
#
|
@@ -241,19 +307,19 @@ module Capybara
|
|
241
307
|
# @return [Boolean] If the selector exists
|
242
308
|
#
|
243
309
|
def has_css?(path, **options, &optional_filter_block)
|
244
|
-
has_selector?(:css, path, options, &optional_filter_block)
|
310
|
+
has_selector?(:css, path, **options, &optional_filter_block)
|
245
311
|
end
|
246
312
|
|
247
313
|
##
|
248
314
|
#
|
249
315
|
# Checks if a given CSS selector is not on the page or a descendant of the current node.
|
250
|
-
# Usage is identical to
|
316
|
+
# Usage is identical to {#has_css?}.
|
251
317
|
#
|
252
|
-
# @param (see
|
318
|
+
# @param (see #has_css?)
|
253
319
|
# @return [Boolean]
|
254
320
|
#
|
255
321
|
def has_no_css?(path, **options, &optional_filter_block)
|
256
|
-
has_no_selector?(:css, path, options, &optional_filter_block)
|
322
|
+
has_no_selector?(:css, path, **options, &optional_filter_block)
|
257
323
|
end
|
258
324
|
|
259
325
|
##
|
@@ -262,12 +328,11 @@ module Capybara
|
|
262
328
|
# text or id.
|
263
329
|
#
|
264
330
|
# @param [String] locator The text or id of a link to check for
|
265
|
-
# @param options
|
266
331
|
# @option options [String, Regexp] :href The value the href attribute must be
|
267
332
|
# @return [Boolean] Whether it exists
|
268
333
|
#
|
269
334
|
def has_link?(locator = nil, **options, &optional_filter_block)
|
270
|
-
has_selector?(:link, locator, options, &optional_filter_block)
|
335
|
+
has_selector?(:link, locator, **options, &optional_filter_block)
|
271
336
|
end
|
272
337
|
|
273
338
|
##
|
@@ -275,11 +340,11 @@ module Capybara
|
|
275
340
|
# Checks if the page or current node has no link with the given
|
276
341
|
# text or id.
|
277
342
|
#
|
278
|
-
# @param (see
|
343
|
+
# @param (see #has_link?)
|
279
344
|
# @return [Boolean] Whether it doesn't exist
|
280
345
|
#
|
281
346
|
def has_no_link?(locator = nil, **options, &optional_filter_block)
|
282
|
-
has_no_selector?(:link, locator, options, &optional_filter_block)
|
347
|
+
has_no_selector?(:link, locator, **options, &optional_filter_block)
|
283
348
|
end
|
284
349
|
|
285
350
|
##
|
@@ -291,7 +356,7 @@ module Capybara
|
|
291
356
|
# @return [Boolean] Whether it exists
|
292
357
|
#
|
293
358
|
def has_button?(locator = nil, **options, &optional_filter_block)
|
294
|
-
has_selector?(:button, locator, options, &optional_filter_block)
|
359
|
+
has_selector?(:button, locator, **options, &optional_filter_block)
|
295
360
|
end
|
296
361
|
|
297
362
|
##
|
@@ -303,7 +368,7 @@ module Capybara
|
|
303
368
|
# @return [Boolean] Whether it doesn't exist
|
304
369
|
#
|
305
370
|
def has_no_button?(locator = nil, **options, &optional_filter_block)
|
306
|
-
has_no_selector?(:button, locator, options, &optional_filter_block)
|
371
|
+
has_no_selector?(:button, locator, **options, &optional_filter_block)
|
307
372
|
end
|
308
373
|
|
309
374
|
##
|
@@ -312,7 +377,7 @@ module Capybara
|
|
312
377
|
# label, name or id.
|
313
378
|
#
|
314
379
|
# For text fields and other textual fields, such as textareas and
|
315
|
-
# HTML5 email/url/etc. fields, it's possible to specify a
|
380
|
+
# HTML5 email/url/etc. fields, it's possible to specify a `:with`
|
316
381
|
# option to specify the text the field should contain:
|
317
382
|
#
|
318
383
|
# page.has_field?('Name', with: 'Jonas')
|
@@ -321,7 +386,7 @@ module Capybara
|
|
321
386
|
#
|
322
387
|
# page.has_field?('Email', type: 'email')
|
323
388
|
#
|
324
|
-
#
|
389
|
+
# NOTE: 'textarea' and 'select' are valid type values, matching the associated tag names.
|
325
390
|
#
|
326
391
|
# @param [String] locator The label, name or id of a field to check for
|
327
392
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -329,13 +394,13 @@ module Capybara
|
|
329
394
|
# @return [Boolean] Whether it exists
|
330
395
|
#
|
331
396
|
def has_field?(locator = nil, **options, &optional_filter_block)
|
332
|
-
has_selector?(:field, locator, options, &optional_filter_block)
|
397
|
+
has_selector?(:field, locator, **options, &optional_filter_block)
|
333
398
|
end
|
334
399
|
|
335
400
|
##
|
336
401
|
#
|
337
402
|
# Checks if the page or current node has no form field with the given
|
338
|
-
# label, name or id. See {
|
403
|
+
# label, name or id. See {#has_field?}.
|
339
404
|
#
|
340
405
|
# @param [String] locator The label, name or id of a field to check for
|
341
406
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -343,59 +408,59 @@ module Capybara
|
|
343
408
|
# @return [Boolean] Whether it doesn't exist
|
344
409
|
#
|
345
410
|
def has_no_field?(locator = nil, **options, &optional_filter_block)
|
346
|
-
has_no_selector?(:field, locator, options, &optional_filter_block)
|
411
|
+
has_no_selector?(:field, locator, **options, &optional_filter_block)
|
347
412
|
end
|
348
413
|
|
349
414
|
##
|
350
415
|
#
|
351
416
|
# Checks if the page or current node has a radio button or
|
352
|
-
# checkbox with the given label, value
|
417
|
+
# checkbox with the given label, value, id, or {Capybara.configure test_id} attribute that is currently
|
353
418
|
# checked.
|
354
419
|
#
|
355
420
|
# @param [String] locator The label, name or id of a checked field
|
356
421
|
# @return [Boolean] Whether it exists
|
357
422
|
#
|
358
423
|
def has_checked_field?(locator = nil, **options, &optional_filter_block)
|
359
|
-
has_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
424
|
+
has_selector?(:field, locator, **options.merge(checked: true), &optional_filter_block)
|
360
425
|
end
|
361
426
|
|
362
427
|
##
|
363
428
|
#
|
364
429
|
# Checks if the page or current node has no radio button or
|
365
|
-
# checkbox with the given label, value or id, that is currently
|
430
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
366
431
|
# checked.
|
367
432
|
#
|
368
433
|
# @param [String] locator The label, name or id of a checked field
|
369
434
|
# @return [Boolean] Whether it doesn't exist
|
370
435
|
#
|
371
436
|
def has_no_checked_field?(locator = nil, **options, &optional_filter_block)
|
372
|
-
has_no_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
437
|
+
has_no_selector?(:field, locator, **options.merge(checked: true), &optional_filter_block)
|
373
438
|
end
|
374
439
|
|
375
440
|
##
|
376
441
|
#
|
377
442
|
# Checks if the page or current node has a radio button or
|
378
|
-
# checkbox with the given label, value or id, that is currently
|
443
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
379
444
|
# unchecked.
|
380
445
|
#
|
381
446
|
# @param [String] locator The label, name or id of an unchecked field
|
382
447
|
# @return [Boolean] Whether it exists
|
383
448
|
#
|
384
449
|
def has_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
385
|
-
has_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
450
|
+
has_selector?(:field, locator, **options.merge(unchecked: true), &optional_filter_block)
|
386
451
|
end
|
387
452
|
|
388
453
|
##
|
389
454
|
#
|
390
455
|
# Checks if the page or current node has no radio button or
|
391
|
-
# checkbox with the given label, value or id, that is currently
|
456
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
392
457
|
# unchecked.
|
393
458
|
#
|
394
459
|
# @param [String] locator The label, name or id of an unchecked field
|
395
460
|
# @return [Boolean] Whether it doesn't exist
|
396
461
|
#
|
397
462
|
def has_no_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
398
|
-
has_no_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
463
|
+
has_no_selector?(:field, locator, **options.merge(unchecked: true), &optional_filter_block)
|
399
464
|
end
|
400
465
|
|
401
466
|
##
|
@@ -428,19 +493,19 @@ module Capybara
|
|
428
493
|
# @return [Boolean] Whether it exists
|
429
494
|
#
|
430
495
|
def has_select?(locator = nil, **options, &optional_filter_block)
|
431
|
-
has_selector?(:select, locator, options, &optional_filter_block)
|
496
|
+
has_selector?(:select, locator, **options, &optional_filter_block)
|
432
497
|
end
|
433
498
|
|
434
499
|
##
|
435
500
|
#
|
436
501
|
# Checks if the page or current node has no select field with the
|
437
|
-
# given label, name or id. See {
|
502
|
+
# given label, name or id. See {#has_select?}.
|
438
503
|
#
|
439
|
-
# @param (see
|
504
|
+
# @param (see #has_select?)
|
440
505
|
# @return [Boolean] Whether it doesn't exist
|
441
506
|
#
|
442
507
|
def has_no_select?(locator = nil, **options, &optional_filter_block)
|
443
|
-
has_no_selector?(:select, locator, options, &optional_filter_block)
|
508
|
+
has_no_selector?(:select, locator, **options, &optional_filter_block)
|
444
509
|
end
|
445
510
|
|
446
511
|
##
|
@@ -450,35 +515,43 @@ module Capybara
|
|
450
515
|
#
|
451
516
|
# page.has_table?('People')
|
452
517
|
#
|
453
|
-
# @param [String] locator
|
454
|
-
# @
|
518
|
+
# @param [String] locator The id or caption of a table
|
519
|
+
# @option options [Array<Array<String>>] :rows
|
520
|
+
# Text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
|
521
|
+
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_rows
|
522
|
+
# Partial set of text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
|
523
|
+
# @option options [Array<Array<String>>] :cols
|
524
|
+
# Text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
|
525
|
+
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_cols
|
526
|
+
# Partial set of text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
|
527
|
+
# @return [Boolean] Whether it exists
|
455
528
|
#
|
456
529
|
def has_table?(locator = nil, **options, &optional_filter_block)
|
457
|
-
has_selector?(:table, locator, options, &optional_filter_block)
|
530
|
+
has_selector?(:table, locator, **options, &optional_filter_block)
|
458
531
|
end
|
459
532
|
|
460
533
|
##
|
461
534
|
#
|
462
535
|
# Checks if the page or current node has no table with the given id
|
463
|
-
# or caption. See {
|
536
|
+
# or caption. See {#has_table?}.
|
464
537
|
#
|
465
|
-
# @param (see
|
538
|
+
# @param (see #has_table?)
|
466
539
|
# @return [Boolean] Whether it doesn't exist
|
467
540
|
#
|
468
541
|
def has_no_table?(locator = nil, **options, &optional_filter_block)
|
469
|
-
has_no_selector?(:table, locator, options, &optional_filter_block)
|
542
|
+
has_no_selector?(:table, locator, **options, &optional_filter_block)
|
470
543
|
end
|
471
544
|
|
472
545
|
##
|
473
546
|
#
|
474
|
-
# Asserts that the
|
547
|
+
# Asserts that the current node matches a given selector.
|
475
548
|
#
|
476
549
|
# node.assert_matches_selector('p#foo')
|
477
550
|
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
|
478
551
|
# node.assert_matches_selector(:foo)
|
479
552
|
#
|
480
553
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
481
|
-
# such as
|
554
|
+
# such as `:text` and `:visible`.
|
482
555
|
#
|
483
556
|
# node.assert_matches_selector('li', text: 'Horse', visible: true)
|
484
557
|
#
|
@@ -487,86 +560,89 @@ module Capybara
|
|
487
560
|
#
|
488
561
|
def assert_matches_selector(*args, &optional_filter_block)
|
489
562
|
_verify_match_result(args, optional_filter_block) do |result|
|
490
|
-
raise Capybara::ExpectationNotMet,
|
563
|
+
raise Capybara::ExpectationNotMet, 'Item does not match the provided selector' unless result.include? self
|
491
564
|
end
|
492
565
|
end
|
493
566
|
|
567
|
+
##
|
568
|
+
#
|
569
|
+
# Asserts that the current node does not match a given selector.
|
570
|
+
# Usage is identical to {#assert_matches_selector}.
|
571
|
+
#
|
572
|
+
# @param (see #assert_matches_selector)
|
573
|
+
# @raise [Capybara::ExpectationNotMet] If the selector matches
|
574
|
+
#
|
494
575
|
def assert_not_matches_selector(*args, &optional_filter_block)
|
495
576
|
_verify_match_result(args, optional_filter_block) do |result|
|
496
577
|
raise Capybara::ExpectationNotMet, 'Item matched the provided selector' if result.include? self
|
497
578
|
end
|
498
579
|
end
|
499
|
-
alias_method :refute_matches_selector, :assert_not_matches_selector
|
500
580
|
|
501
581
|
##
|
502
582
|
#
|
503
|
-
# Checks if the current node matches given selector
|
583
|
+
# Checks if the current node matches given selector.
|
504
584
|
#
|
505
|
-
# @param (see
|
585
|
+
# @param (see #has_selector?)
|
506
586
|
# @return [Boolean]
|
507
587
|
#
|
508
|
-
def matches_selector?(*args, &optional_filter_block)
|
509
|
-
assert_matches_selector(*args, &optional_filter_block)
|
510
|
-
rescue Capybara::ExpectationNotMet
|
511
|
-
return false
|
588
|
+
def matches_selector?(*args, **options, &optional_filter_block)
|
589
|
+
make_predicate(options) { assert_matches_selector(*args, options, &optional_filter_block) }
|
512
590
|
end
|
513
591
|
|
514
592
|
##
|
515
593
|
#
|
516
|
-
# Checks if the current node matches given XPath expression
|
594
|
+
# Checks if the current node matches given XPath expression.
|
517
595
|
#
|
518
596
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
519
597
|
# @return [Boolean]
|
520
598
|
#
|
521
599
|
def matches_xpath?(xpath, **options, &optional_filter_block)
|
522
|
-
matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
600
|
+
matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
523
601
|
end
|
524
602
|
|
525
603
|
##
|
526
604
|
#
|
527
|
-
# Checks if the current node matches given CSS selector
|
605
|
+
# Checks if the current node matches given CSS selector.
|
528
606
|
#
|
529
607
|
# @param [String] css The CSS selector to match against the current code
|
530
608
|
# @return [Boolean]
|
531
609
|
#
|
532
610
|
def matches_css?(css, **options, &optional_filter_block)
|
533
|
-
matches_selector?(:css, css, options, &optional_filter_block)
|
611
|
+
matches_selector?(:css, css, **options, &optional_filter_block)
|
534
612
|
end
|
535
613
|
|
536
614
|
##
|
537
615
|
#
|
538
|
-
# Checks if the current node does not match given selector
|
539
|
-
# Usage is identical to
|
616
|
+
# Checks if the current node does not match given selector.
|
617
|
+
# Usage is identical to {#has_selector?}.
|
540
618
|
#
|
541
|
-
# @param (see
|
619
|
+
# @param (see #has_selector?)
|
542
620
|
# @return [Boolean]
|
543
621
|
#
|
544
|
-
def not_matches_selector?(*args, &optional_filter_block)
|
545
|
-
assert_not_matches_selector(*args, &optional_filter_block)
|
546
|
-
rescue Capybara::ExpectationNotMet
|
547
|
-
return false
|
622
|
+
def not_matches_selector?(*args, **options, &optional_filter_block)
|
623
|
+
make_predicate(options) { assert_not_matches_selector(*args, options, &optional_filter_block) }
|
548
624
|
end
|
549
625
|
|
550
626
|
##
|
551
627
|
#
|
552
|
-
# Checks if the current node does not match given XPath expression
|
628
|
+
# Checks if the current node does not match given XPath expression.
|
553
629
|
#
|
554
630
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
555
631
|
# @return [Boolean]
|
556
632
|
#
|
557
633
|
def not_matches_xpath?(xpath, **options, &optional_filter_block)
|
558
|
-
not_matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
634
|
+
not_matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
559
635
|
end
|
560
636
|
|
561
637
|
##
|
562
638
|
#
|
563
|
-
# Checks if the current node does not match given CSS selector
|
639
|
+
# Checks if the current node does not match given CSS selector.
|
564
640
|
#
|
565
641
|
# @param [String] css The CSS selector to match against the current code
|
566
642
|
# @return [Boolean]
|
567
643
|
#
|
568
644
|
def not_matches_css?(css, **options, &optional_filter_block)
|
569
|
-
not_matches_selector?(:css, css, options, &optional_filter_block)
|
645
|
+
not_matches_selector?(:css, css, **options, &optional_filter_block)
|
570
646
|
end
|
571
647
|
|
572
648
|
##
|
@@ -574,29 +650,31 @@ module Capybara
|
|
574
650
|
# ignoring any HTML tags.
|
575
651
|
#
|
576
652
|
# @!macro text_query_params
|
577
|
-
# @overload $0(type, text, options
|
578
|
-
# @param [:all, :visible] type Whether to check for only visible or all text. If this parameter is missing or nil then we use the value of
|
653
|
+
# @overload $0(type, text, **options)
|
654
|
+
# @param [:all, :visible] type Whether to check for only visible or all text. If this parameter is missing or nil then we use the value of {Capybara.configure ignore_hidden_elements}, which defaults to `true`, corresponding to `:visible`.
|
579
655
|
# @param [String, Regexp] text The string/regexp to check for. If it's a string, text is expected to include it. If it's a regexp, text is expected to match it.
|
580
656
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
581
657
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
582
658
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
583
659
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
584
|
-
# @option options [Numeric] :wait
|
585
|
-
# @option options [Boolean] :exact
|
586
|
-
#
|
660
|
+
# @option options [Numeric] :wait Maximum time that Capybara will wait for text to eq/match given string/regexp argument. Defaults to {Capybara.configure default_max_wait_time}.
|
661
|
+
# @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
|
662
|
+
# @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
|
663
|
+
# @overload $0(text, **options)
|
587
664
|
# @param [String, Regexp] text The string/regexp to check for. If it's a string, text is expected to include it. If it's a regexp, text is expected to match it.
|
588
665
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
589
666
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
590
667
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
591
668
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
592
|
-
# @option options [Numeric] :wait
|
593
|
-
# @option options [Boolean] :exact
|
669
|
+
# @option options [Numeric] :wait Maximum time that Capybara will wait for text to eq/match given string/regexp argument. Defaults to {Capybara.configure default_max_wait_time}.
|
670
|
+
# @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
|
671
|
+
# @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
|
594
672
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
595
673
|
# @return [true]
|
596
674
|
#
|
597
|
-
def assert_text(*args)
|
598
|
-
_verify_text(args) do |count, query|
|
599
|
-
unless query.matches_count?(count) && (
|
675
|
+
def assert_text(type_or_text, *args, **opts)
|
676
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
677
|
+
unless query.matches_count?(count) && (count.positive? || query.expects_none?)
|
600
678
|
raise Capybara::ExpectationNotMet, query.failure_message
|
601
679
|
end
|
602
680
|
end
|
@@ -610,9 +688,9 @@ module Capybara
|
|
610
688
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
611
689
|
# @return [true]
|
612
690
|
#
|
613
|
-
def assert_no_text(*args)
|
614
|
-
_verify_text(args) do |count, query|
|
615
|
-
if query.matches_count?(count) && (
|
691
|
+
def assert_no_text(type_or_text, *args, **opts)
|
692
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
693
|
+
if query.matches_count?(count) && (count.positive? || query.expects_none?)
|
616
694
|
raise Capybara::ExpectationNotMet, query.negative_failure_message
|
617
695
|
end
|
618
696
|
end
|
@@ -622,10 +700,6 @@ module Capybara
|
|
622
700
|
# Checks if the page or current node has the given text content,
|
623
701
|
# ignoring any HTML tags.
|
624
702
|
#
|
625
|
-
# Whitespaces are normalized in both node's text and passed text parameter.
|
626
|
-
# Note that whitespace isn't normalized in passed regexp as normalizing whitespace
|
627
|
-
# in regexp isn't easy and doesn't seem to be worth it.
|
628
|
-
#
|
629
703
|
# By default it will check if the text occurs at least once,
|
630
704
|
# but a different number can be specified.
|
631
705
|
#
|
@@ -636,10 +710,8 @@ module Capybara
|
|
636
710
|
# @macro text_query_params
|
637
711
|
# @return [Boolean] Whether it exists
|
638
712
|
#
|
639
|
-
def has_text?(*args)
|
640
|
-
assert_text(*args)
|
641
|
-
rescue Capybara::ExpectationNotMet
|
642
|
-
false
|
713
|
+
def has_text?(*args, **options)
|
714
|
+
make_predicate(options) { assert_text(*args, **options) }
|
643
715
|
end
|
644
716
|
alias_method :has_content?, :has_text?
|
645
717
|
|
@@ -650,52 +722,161 @@ module Capybara
|
|
650
722
|
# @macro text_query_params
|
651
723
|
# @return [Boolean] Whether it doesn't exist
|
652
724
|
#
|
653
|
-
def has_no_text?(*args)
|
654
|
-
assert_no_text(*args)
|
655
|
-
rescue Capybara::ExpectationNotMet
|
656
|
-
false
|
725
|
+
def has_no_text?(*args, **options)
|
726
|
+
make_predicate(options) { assert_no_text(*args, **options) }
|
657
727
|
end
|
658
728
|
alias_method :has_no_content?, :has_no_text?
|
659
729
|
|
730
|
+
##
|
731
|
+
#
|
732
|
+
# Asserts that a given selector matches an ancestor of the current node.
|
733
|
+
#
|
734
|
+
# element.assert_ancestor('p#foo')
|
735
|
+
#
|
736
|
+
# Accepts the same options as {#assert_selector}
|
737
|
+
#
|
738
|
+
# @param (see Capybara::Node::Finders#find)
|
739
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
740
|
+
#
|
741
|
+
def assert_ancestor(*args, &optional_filter_block)
|
742
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::AncestorQuery) do |result, query|
|
743
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
744
|
+
raise Capybara::ExpectationNotMet, result.failure_message
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
def assert_no_ancestor(*args, &optional_filter_block)
|
750
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::AncestorQuery) do |result, query|
|
751
|
+
if result.matches_count? && (!result.empty? || query.expects_none?)
|
752
|
+
raise Capybara::ExpectationNotMet, result.negative_failure_message
|
753
|
+
end
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
##
|
758
|
+
#
|
759
|
+
# Predicate version of {#assert_ancestor}
|
760
|
+
#
|
761
|
+
def has_ancestor?(*args, **options, &optional_filter_block)
|
762
|
+
make_predicate(options) { assert_ancestor(*args, options, &optional_filter_block) }
|
763
|
+
end
|
764
|
+
|
765
|
+
##
|
766
|
+
#
|
767
|
+
# Predicate version of {#assert_no_ancestor}
|
768
|
+
#
|
769
|
+
def has_no_ancestor?(*args, **options, &optional_filter_block)
|
770
|
+
make_predicate(options) { assert_no_ancestor(*args, options, &optional_filter_block) }
|
771
|
+
end
|
772
|
+
|
773
|
+
##
|
774
|
+
#
|
775
|
+
# Asserts that a given selector matches a sibling of the current node.
|
776
|
+
#
|
777
|
+
# element.assert_sibling('p#foo')
|
778
|
+
#
|
779
|
+
# Accepts the same options as {#assert_selector}
|
780
|
+
#
|
781
|
+
# @param (see Capybara::Node::Finders#find)
|
782
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
783
|
+
#
|
784
|
+
def assert_sibling(*args, &optional_filter_block)
|
785
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
|
786
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
787
|
+
raise Capybara::ExpectationNotMet, result.failure_message
|
788
|
+
end
|
789
|
+
end
|
790
|
+
end
|
791
|
+
|
792
|
+
def assert_no_sibling(*args, &optional_filter_block)
|
793
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
|
794
|
+
if result.matches_count? && (!result.empty? || query.expects_none?)
|
795
|
+
raise Capybara::ExpectationNotMet, result.negative_failure_message
|
796
|
+
end
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
##
|
801
|
+
#
|
802
|
+
# Predicate version of {#assert_sibling}
|
803
|
+
#
|
804
|
+
def has_sibling?(*args, **options, &optional_filter_block)
|
805
|
+
make_predicate(options) { assert_sibling(*args, options, &optional_filter_block) }
|
806
|
+
end
|
807
|
+
|
808
|
+
##
|
809
|
+
#
|
810
|
+
# Predicate version of {#assert_no_sibling}
|
811
|
+
#
|
812
|
+
def has_no_sibling?(*args, **options, &optional_filter_block)
|
813
|
+
make_predicate(options) { assert_no_sibling(*args, options, &optional_filter_block) }
|
814
|
+
end
|
815
|
+
|
660
816
|
def ==(other)
|
661
817
|
eql?(other) || (other.respond_to?(:base) && base == other.base)
|
662
818
|
end
|
663
819
|
|
664
820
|
private
|
665
821
|
|
666
|
-
def
|
667
|
-
|
668
|
-
|
822
|
+
def extract_selector(args)
|
823
|
+
args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
824
|
+
end
|
825
|
+
|
826
|
+
def _verify_multiple(*args, wait: nil, **options)
|
827
|
+
wait = session_options.default_max_wait_time if wait.nil?
|
828
|
+
selector = extract_selector(args)
|
829
|
+
synchronize(wait) do
|
830
|
+
args.each { |locator| yield(selector, locator, options) }
|
831
|
+
end
|
832
|
+
end
|
833
|
+
|
834
|
+
def _verify_selector_result(query_args, optional_filter_block, query_type = Capybara::Queries::SelectorQuery)
|
835
|
+
# query_args, query_opts = if query_args[0].is_a? Symbol
|
836
|
+
# a,o = _set_query_session_options(*query_args.slice(2..))
|
837
|
+
# [query_args.slice(0..1).concat(a), o]
|
838
|
+
# else
|
839
|
+
# _set_query_session_options(*query_args)
|
840
|
+
# end
|
841
|
+
query_args, query_opts = _set_query_session_options(*query_args)
|
842
|
+
query = query_type.new(*query_args, **query_opts, &optional_filter_block)
|
669
843
|
synchronize(query.wait) do
|
670
|
-
|
671
|
-
yield result, query
|
844
|
+
yield query.resolve_for(self), query
|
672
845
|
end
|
673
846
|
true
|
674
847
|
end
|
675
848
|
|
676
849
|
def _verify_match_result(query_args, optional_filter_block)
|
677
|
-
query_args = _set_query_session_options(*query_args)
|
678
|
-
query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
|
850
|
+
query_args, query_opts = _set_query_session_options(*query_args)
|
851
|
+
query = Capybara::Queries::MatchQuery.new(*query_args, **query_opts, &optional_filter_block)
|
679
852
|
synchronize(query.wait) do
|
680
|
-
|
681
|
-
yield result
|
853
|
+
yield query.resolve_for(parent || session&.document || query_scope)
|
682
854
|
end
|
683
855
|
true
|
684
856
|
end
|
685
857
|
|
686
|
-
def _verify_text(
|
687
|
-
|
688
|
-
query = Capybara::Queries::TextQuery.new(
|
858
|
+
def _verify_text(type = nil, expected_text, **query_options) # rubocop:disable Style/OptionalArguments
|
859
|
+
query_options[:session_options] = session_options
|
860
|
+
query = Capybara::Queries::TextQuery.new(type, expected_text, **query_options)
|
689
861
|
synchronize(query.wait) do
|
690
|
-
|
691
|
-
yield(count, query)
|
862
|
+
yield query.resolve_for(self), query
|
692
863
|
end
|
693
864
|
true
|
694
865
|
end
|
695
866
|
|
696
|
-
def _set_query_session_options(*query_args
|
867
|
+
def _set_query_session_options(*query_args)
|
868
|
+
query_args, query_options = query_args.dup, {}
|
869
|
+
# query_options = query_args.pop if query_options.empty? && query_args.last.is_a?(Hash)
|
870
|
+
query_options = query_args.pop if query_args.last.is_a?(Hash)
|
697
871
|
query_options[:session_options] = session_options
|
698
|
-
query_args
|
872
|
+
[query_args, query_options]
|
873
|
+
end
|
874
|
+
|
875
|
+
def make_predicate(options)
|
876
|
+
options[:wait] = 0 unless options.key?(:wait) || session_options.predicates_wait
|
877
|
+
yield
|
878
|
+
rescue Capybara::ExpectationNotMet
|
879
|
+
false
|
699
880
|
end
|
700
881
|
end
|
701
882
|
end
|