capybara 3.3.0 → 3.40.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/History.md +803 -13
- data/License.txt +1 -1
- data/README.md +257 -84
- data/lib/capybara/config.rb +25 -9
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +17 -3
- data/lib/capybara/driver/node.rb +31 -6
- data/lib/capybara/dsl.rb +9 -7
- data/lib/capybara/helpers.rb +31 -7
- data/lib/capybara/minitest/spec.rb +180 -88
- data/lib/capybara/minitest.rb +262 -149
- data/lib/capybara/node/actions.rb +202 -116
- data/lib/capybara/node/base.rb +34 -19
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +10 -12
- data/lib/capybara/node/element.rb +269 -115
- data/lib/capybara/node/finders.rb +99 -77
- data/lib/capybara/node/matchers.rb +327 -151
- data/lib/capybara/node/simple.rb +48 -13
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +8 -9
- data/lib/capybara/queries/base_query.rb +23 -16
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +1 -0
- data/lib/capybara/queries/selector_query.rb +587 -130
- data/lib/capybara/queries/sibling_query.rb +8 -6
- data/lib/capybara/queries/style_query.rb +6 -2
- data/lib/capybara/queries/text_query.rb +28 -14
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +92 -25
- data/lib/capybara/rack_test/driver.rb +16 -7
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +68 -41
- data/lib/capybara/rack_test/node.rb +106 -39
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +75 -52
- data/lib/capybara/rspec/features.rb +7 -7
- data/lib/capybara/rspec/matcher_proxies.rb +39 -18
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +141 -339
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +27 -25
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +1 -0
- data/lib/capybara/selector/filter_set.rb +73 -25
- data/lib/capybara/selector/filters/base.rb +24 -5
- data/lib/capybara/selector/filters/expression_filter.rb +3 -3
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -2
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +85 -348
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +474 -447
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +255 -143
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +436 -134
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +56 -19
- data/lib/capybara/server/checker.rb +9 -3
- data/lib/capybara/server/middleware.rb +28 -12
- data/lib/capybara/server.rb +33 -10
- data/lib/capybara/session/config.rb +34 -10
- data/lib/capybara/session/matchers.rb +23 -16
- data/lib/capybara/session.rb +230 -170
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +121 -8
- data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +127 -40
- data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
- data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
- data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
- data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
- data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
- data/lib/capybara/spec/session/body_spec.rb +6 -6
- data/lib/capybara/spec/session/check_spec.rb +102 -47
- data/lib/capybara/spec/session/choose_spec.rb +58 -32
- data/lib/capybara/spec/session/click_button_spec.rb +219 -163
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
- data/lib/capybara/spec/session/click_link_spec.rb +77 -54
- data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
- data/lib/capybara/spec/session/current_url_spec.rb +38 -29
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
- data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
- data/lib/capybara/spec/session/find_field_spec.rb +32 -30
- data/lib/capybara/spec/session/find_link_spec.rb +31 -21
- data/lib/capybara/spec/session/find_spec.rb +244 -141
- data/lib/capybara/spec/session/first_spec.rb +43 -43
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +94 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -132
- data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +137 -58
- data/lib/capybara/spec/session/has_link_spec.rb +44 -4
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
- data/lib/capybara/spec/session/has_select_spec.rb +84 -50
- data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +181 -4
- data/lib/capybara/spec/session/has_text_spec.rb +101 -53
- data/lib/capybara/spec/session/has_title_spec.rb +19 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
- data/lib/capybara/spec/session/headers_spec.rb +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +894 -142
- data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
- data/lib/capybara/spec/session/response_code_spec.rb +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +37 -37
- data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +85 -85
- data/lib/capybara/spec/session/selectors_spec.rb +49 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +25 -24
- data/lib/capybara/spec/session/title_spec.rb +7 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +68 -49
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
- data/lib/capybara/spec/session/window/window_spec.rb +62 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
- data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
- data/lib/capybara/spec/session/within_spec.rb +79 -42
- data/lib/capybara/spec/spec_helper.rb +41 -53
- data/lib/capybara/spec/test_app.rb +132 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +139 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +67 -0
- data/lib/capybara/spec/views/with_animation.erb +39 -4
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +37 -9
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +26 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +19 -25
- data/lib/capybara.rb +126 -111
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +56 -44
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +8 -8
- data/spec/dsl_spec.rb +79 -52
- data/spec/filter_set_spec.rb +9 -9
- data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
- data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
- data/spec/minitest_spec.rb +45 -7
- data/spec/minitest_spec_spec.rb +87 -64
- data/spec/per_session_config_spec.rb +6 -6
- data/spec/rack_test_spec.rb +172 -116
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +80 -72
- data/spec/rspec/features_spec.rb +21 -16
- data/spec/rspec/scenarios_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +407 -365
- data/spec/rspec/views_spec.rb +3 -3
- data/spec/rspec_matchers_spec.rb +35 -10
- data/spec/rspec_spec.rb +63 -41
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +334 -89
- data/spec/selenium_spec_chrome.rb +176 -62
- data/spec/selenium_spec_chrome_remote.rb +54 -14
- data/spec/selenium_spec_edge.rb +41 -8
- data/spec/selenium_spec_firefox.rb +228 -0
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +129 -11
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +171 -97
- data/spec/session_spec.rb +34 -18
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +344 -80
- data/spec/spec_helper.rb +124 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +326 -28
- data/lib/capybara/rspec/compound.rb +0 -94
- data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
- data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
- data/lib/capybara/spec/session/has_style_spec.rb +0 -25
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -167
@@ -19,56 +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
|
-
rescue Capybara::ExpectationNotMet
|
56
|
-
false
|
50
|
+
def has_no_selector?(*args, **options, &optional_filter_block)
|
51
|
+
make_predicate(options) { assert_no_selector(*args, options, &optional_filter_block) }
|
57
52
|
end
|
58
53
|
|
59
54
|
##
|
60
55
|
#
|
61
|
-
# Checks if a an element has the specified CSS styles
|
56
|
+
# Checks if a an element has the specified CSS styles.
|
62
57
|
#
|
63
|
-
# element.
|
58
|
+
# element.matches_style?( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
64
59
|
#
|
65
60
|
# @param styles [Hash]
|
66
61
|
# @return [Boolean] If the styles match
|
67
62
|
#
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
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)
|
72
74
|
end
|
73
75
|
|
74
76
|
##
|
@@ -87,15 +89,15 @@ module Capybara
|
|
87
89
|
# This will check if the expression occurs exactly 4 times. See
|
88
90
|
# {Capybara::Node::Finders#all} for other available result size options.
|
89
91
|
#
|
90
|
-
# If a
|
92
|
+
# If a `:count` of 0 is specified, it will behave like {#assert_no_selector};
|
91
93
|
# however, use of that method is preferred over this one.
|
92
94
|
#
|
93
95
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
94
|
-
# such as
|
96
|
+
# such as `:text` and `:visible`.
|
95
97
|
#
|
96
98
|
# page.assert_selector('li', text: 'Horse', visible: true)
|
97
99
|
#
|
98
|
-
#
|
100
|
+
# {#assert_selector} can also accept XPath expressions generated by the
|
99
101
|
# XPath gem:
|
100
102
|
#
|
101
103
|
# page.assert_selector(:xpath, XPath.descendant(:p))
|
@@ -114,86 +116,118 @@ module Capybara
|
|
114
116
|
|
115
117
|
##
|
116
118
|
#
|
117
|
-
# Asserts that an element has the specified CSS styles
|
119
|
+
# Asserts that an element has the specified CSS styles.
|
118
120
|
#
|
119
|
-
# element.
|
121
|
+
# element.assert_matches_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
120
122
|
#
|
121
123
|
# @param styles [Hash]
|
122
124
|
# @raise [Capybara::ExpectationNotMet] If the element doesn't have the specified styles
|
123
125
|
#
|
124
|
-
def
|
125
|
-
|
126
|
-
|
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)
|
127
130
|
synchronize(query.wait) do
|
128
131
|
raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
|
129
132
|
end
|
130
133
|
true
|
131
134
|
end
|
132
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
|
+
|
133
144
|
# Asserts that all of the provided selectors are present on the given page
|
134
145
|
# or descendants of the current node. If options are provided, the assertion
|
135
|
-
# 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`).
|
136
147
|
#
|
137
|
-
#
|
138
|
-
#
|
148
|
+
# page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
149
|
+
# page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
|
139
150
|
#
|
140
151
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
141
|
-
# such as
|
152
|
+
# such as `:text` and `:visible`.
|
142
153
|
#
|
143
|
-
# The
|
144
|
-
# 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.
|
145
156
|
#
|
146
157
|
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
147
158
|
#
|
148
|
-
def assert_all_of_selectors(*args,
|
149
|
-
|
150
|
-
|
151
|
-
synchronize(wait) do
|
152
|
-
args.each do |locator|
|
153
|
-
assert_selector(selector, locator, options, &optional_filter_block)
|
154
|
-
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)
|
155
162
|
end
|
156
163
|
end
|
157
164
|
|
158
165
|
# Asserts that none of the provided selectors are present on the given page
|
159
166
|
# or descendants of the current node. If options are provided, the assertion
|
160
|
-
# 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`).
|
161
168
|
#
|
162
|
-
#
|
163
|
-
#
|
169
|
+
# page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
170
|
+
# page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
|
164
171
|
#
|
165
172
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
166
|
-
# such as
|
173
|
+
# such as `:text` and `:visible`.
|
167
174
|
#
|
168
|
-
# The
|
169
|
-
# within
|
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.
|
170
177
|
#
|
171
178
|
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
172
179
|
#
|
173
|
-
def assert_none_of_selectors(*args,
|
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`).
|
189
|
+
#
|
190
|
+
# page.assert_any_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
191
|
+
# page.assert_any_of_selectors(:css, '#my_div', 'a.not_clicked')
|
192
|
+
#
|
193
|
+
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
194
|
+
# such as `:text` and `:visible`.
|
195
|
+
#
|
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.
|
198
|
+
#
|
199
|
+
# @overload assert_any_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
200
|
+
#
|
201
|
+
def assert_any_of_selectors(*args, wait: nil, **options, &optional_filter_block)
|
174
202
|
wait = session_options.default_max_wait_time if wait.nil?
|
175
203
|
selector = extract_selector(args)
|
176
204
|
synchronize(wait) do
|
177
|
-
args.
|
178
|
-
|
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
|
179
210
|
end
|
211
|
+
raise Capybara::ExpectationNotMet, res.join(' or ') if res
|
212
|
+
|
213
|
+
true
|
180
214
|
end
|
181
215
|
end
|
182
216
|
|
183
217
|
##
|
184
218
|
#
|
185
219
|
# Asserts that a given selector is not on the page or a descendant of the current node.
|
186
|
-
# Usage is identical to
|
220
|
+
# Usage is identical to {#assert_selector}.
|
187
221
|
#
|
188
|
-
# Query options such as
|
222
|
+
# Query options such as `:count`, `:minimum`, `:maximum`, and `:between` are
|
189
223
|
# considered to be an integral part of the selector. This will return
|
190
|
-
# true
|
224
|
+
# `true`, for example, if a page contains 4 anchors but the query expects 5:
|
191
225
|
#
|
192
226
|
# page.assert_no_selector('a', minimum: 1) # Found, raises Capybara::ExpectationNotMet
|
193
227
|
# page.assert_no_selector('a', count: 4) # Found, raises Capybara::ExpectationNotMet
|
194
228
|
# page.assert_no_selector('a', count: 5) # Not Found, returns true
|
195
229
|
#
|
196
|
-
# @param (see
|
230
|
+
# @param (see #assert_selector)
|
197
231
|
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
198
232
|
#
|
199
233
|
def assert_no_selector(*args, &optional_filter_block)
|
@@ -203,7 +237,6 @@ module Capybara
|
|
203
237
|
end
|
204
238
|
end
|
205
239
|
end
|
206
|
-
alias_method :refute_selector, :assert_no_selector
|
207
240
|
|
208
241
|
##
|
209
242
|
#
|
@@ -219,11 +252,11 @@ module Capybara
|
|
219
252
|
# This will check if the expression occurs exactly 4 times.
|
220
253
|
#
|
221
254
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
222
|
-
# such as
|
255
|
+
# such as `:text` and `:visible`.
|
223
256
|
#
|
224
257
|
# page.has_xpath?('.//li', text: 'Horse', visible: true)
|
225
258
|
#
|
226
|
-
# has_xpath? can also accept XPath expressions
|
259
|
+
# {#has_xpath?} can also accept XPath expressions generated by the
|
227
260
|
# XPath gem:
|
228
261
|
#
|
229
262
|
# xpath = XPath.generate { |x| x.descendant(:p) }
|
@@ -235,19 +268,19 @@ module Capybara
|
|
235
268
|
# @return [Boolean] If the expression exists
|
236
269
|
#
|
237
270
|
def has_xpath?(path, **options, &optional_filter_block)
|
238
|
-
has_selector?(:xpath, path, options, &optional_filter_block)
|
271
|
+
has_selector?(:xpath, path, **options, &optional_filter_block)
|
239
272
|
end
|
240
273
|
|
241
274
|
##
|
242
275
|
#
|
243
276
|
# Checks if a given XPath expression is not on the page or a descendant of the current node.
|
244
|
-
# Usage is identical to
|
277
|
+
# Usage is identical to {#has_xpath?}.
|
245
278
|
#
|
246
|
-
# @param (see
|
279
|
+
# @param (see #has_xpath?)
|
247
280
|
# @return [Boolean]
|
248
281
|
#
|
249
282
|
def has_no_xpath?(path, **options, &optional_filter_block)
|
250
|
-
has_no_selector?(:xpath, path, options, &optional_filter_block)
|
283
|
+
has_no_selector?(:xpath, path, **options, &optional_filter_block)
|
251
284
|
end
|
252
285
|
|
253
286
|
##
|
@@ -264,7 +297,7 @@ module Capybara
|
|
264
297
|
# This will check if the selector occurs exactly 4 times.
|
265
298
|
#
|
266
299
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
267
|
-
# such as
|
300
|
+
# such as `:text` and `:visible`.
|
268
301
|
#
|
269
302
|
# page.has_css?('li', text: 'Horse', visible: true)
|
270
303
|
#
|
@@ -274,19 +307,44 @@ module Capybara
|
|
274
307
|
# @return [Boolean] If the selector exists
|
275
308
|
#
|
276
309
|
def has_css?(path, **options, &optional_filter_block)
|
277
|
-
has_selector?(:css, path, options, &optional_filter_block)
|
310
|
+
has_selector?(:css, path, **options, &optional_filter_block)
|
278
311
|
end
|
279
312
|
|
280
313
|
##
|
281
314
|
#
|
282
315
|
# Checks if a given CSS selector is not on the page or a descendant of the current node.
|
283
|
-
# Usage is identical to
|
316
|
+
# Usage is identical to {#has_css?}.
|
284
317
|
#
|
285
|
-
# @param (see
|
318
|
+
# @param (see #has_css?)
|
286
319
|
# @return [Boolean]
|
287
320
|
#
|
288
321
|
def has_no_css?(path, **options, &optional_filter_block)
|
289
|
-
has_no_selector?(:css, path, options, &optional_filter_block)
|
322
|
+
has_no_selector?(:css, path, **options, &optional_filter_block)
|
323
|
+
end
|
324
|
+
|
325
|
+
##
|
326
|
+
#
|
327
|
+
# Checks if the page or current node has a element with the given
|
328
|
+
# local name.
|
329
|
+
#
|
330
|
+
# @param [String] locator The local name of a element to check for
|
331
|
+
# @option options [String, Regexp] The attributes values of matching elements
|
332
|
+
# @return [Boolean] Whether it exists
|
333
|
+
#
|
334
|
+
def has_element?(locator = nil, **options, &optional_filter_block)
|
335
|
+
has_selector?(:element, locator, **options, &optional_filter_block)
|
336
|
+
end
|
337
|
+
|
338
|
+
##
|
339
|
+
#
|
340
|
+
# Checks if the page or current node has no element with the given
|
341
|
+
# local name.
|
342
|
+
#
|
343
|
+
# @param (see #has_element?)
|
344
|
+
# @return [Boolean] Whether it doesn't exist
|
345
|
+
#
|
346
|
+
def has_no_element?(locator = nil, **options, &optional_filter_block)
|
347
|
+
has_no_selector?(:element, locator, **options, &optional_filter_block)
|
290
348
|
end
|
291
349
|
|
292
350
|
##
|
@@ -295,12 +353,11 @@ module Capybara
|
|
295
353
|
# text or id.
|
296
354
|
#
|
297
355
|
# @param [String] locator The text or id of a link to check for
|
298
|
-
# @param options
|
299
356
|
# @option options [String, Regexp] :href The value the href attribute must be
|
300
357
|
# @return [Boolean] Whether it exists
|
301
358
|
#
|
302
359
|
def has_link?(locator = nil, **options, &optional_filter_block)
|
303
|
-
has_selector?(:link, locator, options, &optional_filter_block)
|
360
|
+
has_selector?(:link, locator, **options, &optional_filter_block)
|
304
361
|
end
|
305
362
|
|
306
363
|
##
|
@@ -308,11 +365,11 @@ module Capybara
|
|
308
365
|
# Checks if the page or current node has no link with the given
|
309
366
|
# text or id.
|
310
367
|
#
|
311
|
-
# @param (see
|
368
|
+
# @param (see #has_link?)
|
312
369
|
# @return [Boolean] Whether it doesn't exist
|
313
370
|
#
|
314
371
|
def has_no_link?(locator = nil, **options, &optional_filter_block)
|
315
|
-
has_no_selector?(:link, locator, options, &optional_filter_block)
|
372
|
+
has_no_selector?(:link, locator, **options, &optional_filter_block)
|
316
373
|
end
|
317
374
|
|
318
375
|
##
|
@@ -324,7 +381,7 @@ module Capybara
|
|
324
381
|
# @return [Boolean] Whether it exists
|
325
382
|
#
|
326
383
|
def has_button?(locator = nil, **options, &optional_filter_block)
|
327
|
-
has_selector?(:button, locator, options, &optional_filter_block)
|
384
|
+
has_selector?(:button, locator, **options, &optional_filter_block)
|
328
385
|
end
|
329
386
|
|
330
387
|
##
|
@@ -336,7 +393,7 @@ module Capybara
|
|
336
393
|
# @return [Boolean] Whether it doesn't exist
|
337
394
|
#
|
338
395
|
def has_no_button?(locator = nil, **options, &optional_filter_block)
|
339
|
-
has_no_selector?(:button, locator, options, &optional_filter_block)
|
396
|
+
has_no_selector?(:button, locator, **options, &optional_filter_block)
|
340
397
|
end
|
341
398
|
|
342
399
|
##
|
@@ -345,7 +402,7 @@ module Capybara
|
|
345
402
|
# label, name or id.
|
346
403
|
#
|
347
404
|
# For text fields and other textual fields, such as textareas and
|
348
|
-
# HTML5 email/url/etc. fields, it's possible to specify a
|
405
|
+
# HTML5 email/url/etc. fields, it's possible to specify a `:with`
|
349
406
|
# option to specify the text the field should contain:
|
350
407
|
#
|
351
408
|
# page.has_field?('Name', with: 'Jonas')
|
@@ -354,7 +411,7 @@ module Capybara
|
|
354
411
|
#
|
355
412
|
# page.has_field?('Email', type: 'email')
|
356
413
|
#
|
357
|
-
#
|
414
|
+
# NOTE: 'textarea' and 'select' are valid type values, matching the associated tag names.
|
358
415
|
#
|
359
416
|
# @param [String] locator The label, name or id of a field to check for
|
360
417
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -362,13 +419,13 @@ module Capybara
|
|
362
419
|
# @return [Boolean] Whether it exists
|
363
420
|
#
|
364
421
|
def has_field?(locator = nil, **options, &optional_filter_block)
|
365
|
-
has_selector?(:field, locator, options, &optional_filter_block)
|
422
|
+
has_selector?(:field, locator, **options, &optional_filter_block)
|
366
423
|
end
|
367
424
|
|
368
425
|
##
|
369
426
|
#
|
370
427
|
# Checks if the page or current node has no form field with the given
|
371
|
-
# label, name or id. See {
|
428
|
+
# label, name or id. See {#has_field?}.
|
372
429
|
#
|
373
430
|
# @param [String] locator The label, name or id of a field to check for
|
374
431
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -376,59 +433,59 @@ module Capybara
|
|
376
433
|
# @return [Boolean] Whether it doesn't exist
|
377
434
|
#
|
378
435
|
def has_no_field?(locator = nil, **options, &optional_filter_block)
|
379
|
-
has_no_selector?(:field, locator, options, &optional_filter_block)
|
436
|
+
has_no_selector?(:field, locator, **options, &optional_filter_block)
|
380
437
|
end
|
381
438
|
|
382
439
|
##
|
383
440
|
#
|
384
441
|
# Checks if the page or current node has a radio button or
|
385
|
-
# checkbox with the given label, value
|
442
|
+
# checkbox with the given label, value, id, or {Capybara.configure test_id} attribute that is currently
|
386
443
|
# checked.
|
387
444
|
#
|
388
445
|
# @param [String] locator The label, name or id of a checked field
|
389
446
|
# @return [Boolean] Whether it exists
|
390
447
|
#
|
391
448
|
def has_checked_field?(locator = nil, **options, &optional_filter_block)
|
392
|
-
has_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
449
|
+
has_selector?(:field, locator, **options.merge(checked: true), &optional_filter_block)
|
393
450
|
end
|
394
451
|
|
395
452
|
##
|
396
453
|
#
|
397
454
|
# Checks if the page or current node has no radio button or
|
398
|
-
# checkbox with the given label, value or id, that is currently
|
455
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
399
456
|
# checked.
|
400
457
|
#
|
401
458
|
# @param [String] locator The label, name or id of a checked field
|
402
459
|
# @return [Boolean] Whether it doesn't exist
|
403
460
|
#
|
404
461
|
def has_no_checked_field?(locator = nil, **options, &optional_filter_block)
|
405
|
-
has_no_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
462
|
+
has_no_selector?(:field, locator, **options.merge(checked: true), &optional_filter_block)
|
406
463
|
end
|
407
464
|
|
408
465
|
##
|
409
466
|
#
|
410
467
|
# Checks if the page or current node has a radio button or
|
411
|
-
# checkbox with the given label, value or id, that is currently
|
468
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
412
469
|
# unchecked.
|
413
470
|
#
|
414
471
|
# @param [String] locator The label, name or id of an unchecked field
|
415
472
|
# @return [Boolean] Whether it exists
|
416
473
|
#
|
417
474
|
def has_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
418
|
-
has_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
475
|
+
has_selector?(:field, locator, **options.merge(unchecked: true), &optional_filter_block)
|
419
476
|
end
|
420
477
|
|
421
478
|
##
|
422
479
|
#
|
423
480
|
# Checks if the page or current node has no radio button or
|
424
|
-
# checkbox with the given label, value or id, that is currently
|
481
|
+
# checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
|
425
482
|
# unchecked.
|
426
483
|
#
|
427
484
|
# @param [String] locator The label, name or id of an unchecked field
|
428
485
|
# @return [Boolean] Whether it doesn't exist
|
429
486
|
#
|
430
487
|
def has_no_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
431
|
-
has_no_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
488
|
+
has_no_selector?(:field, locator, **options.merge(unchecked: true), &optional_filter_block)
|
432
489
|
end
|
433
490
|
|
434
491
|
##
|
@@ -461,19 +518,19 @@ module Capybara
|
|
461
518
|
# @return [Boolean] Whether it exists
|
462
519
|
#
|
463
520
|
def has_select?(locator = nil, **options, &optional_filter_block)
|
464
|
-
has_selector?(:select, locator, options, &optional_filter_block)
|
521
|
+
has_selector?(:select, locator, **options, &optional_filter_block)
|
465
522
|
end
|
466
523
|
|
467
524
|
##
|
468
525
|
#
|
469
526
|
# Checks if the page or current node has no select field with the
|
470
|
-
# given label, name or id. See {
|
527
|
+
# given label, name or id. See {#has_select?}.
|
471
528
|
#
|
472
|
-
# @param (see
|
529
|
+
# @param (see #has_select?)
|
473
530
|
# @return [Boolean] Whether it doesn't exist
|
474
531
|
#
|
475
532
|
def has_no_select?(locator = nil, **options, &optional_filter_block)
|
476
|
-
has_no_selector?(:select, locator, options, &optional_filter_block)
|
533
|
+
has_no_selector?(:select, locator, **options, &optional_filter_block)
|
477
534
|
end
|
478
535
|
|
479
536
|
##
|
@@ -483,35 +540,43 @@ module Capybara
|
|
483
540
|
#
|
484
541
|
# page.has_table?('People')
|
485
542
|
#
|
486
|
-
# @param [String] locator
|
487
|
-
# @
|
543
|
+
# @param [String] locator The id or caption of a table
|
544
|
+
# @option options [Array<Array<String>>] :rows
|
545
|
+
# Text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
|
546
|
+
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_rows
|
547
|
+
# Partial set of text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
|
548
|
+
# @option options [Array<Array<String>>] :cols
|
549
|
+
# Text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
|
550
|
+
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_cols
|
551
|
+
# Partial set of text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
|
552
|
+
# @return [Boolean] Whether it exists
|
488
553
|
#
|
489
554
|
def has_table?(locator = nil, **options, &optional_filter_block)
|
490
|
-
has_selector?(:table, locator, options, &optional_filter_block)
|
555
|
+
has_selector?(:table, locator, **options, &optional_filter_block)
|
491
556
|
end
|
492
557
|
|
493
558
|
##
|
494
559
|
#
|
495
560
|
# Checks if the page or current node has no table with the given id
|
496
|
-
# or caption. See {
|
561
|
+
# or caption. See {#has_table?}.
|
497
562
|
#
|
498
|
-
# @param (see
|
563
|
+
# @param (see #has_table?)
|
499
564
|
# @return [Boolean] Whether it doesn't exist
|
500
565
|
#
|
501
566
|
def has_no_table?(locator = nil, **options, &optional_filter_block)
|
502
|
-
has_no_selector?(:table, locator, options, &optional_filter_block)
|
567
|
+
has_no_selector?(:table, locator, **options, &optional_filter_block)
|
503
568
|
end
|
504
569
|
|
505
570
|
##
|
506
571
|
#
|
507
|
-
# Asserts that the
|
572
|
+
# Asserts that the current node matches a given selector.
|
508
573
|
#
|
509
574
|
# node.assert_matches_selector('p#foo')
|
510
575
|
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
|
511
576
|
# node.assert_matches_selector(:foo)
|
512
577
|
#
|
513
578
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
514
|
-
# such as
|
579
|
+
# such as `:text` and `:visible`.
|
515
580
|
#
|
516
581
|
# node.assert_matches_selector('li', text: 'Horse', visible: true)
|
517
582
|
#
|
@@ -520,86 +585,89 @@ module Capybara
|
|
520
585
|
#
|
521
586
|
def assert_matches_selector(*args, &optional_filter_block)
|
522
587
|
_verify_match_result(args, optional_filter_block) do |result|
|
523
|
-
raise Capybara::ExpectationNotMet,
|
588
|
+
raise Capybara::ExpectationNotMet, 'Item does not match the provided selector' unless result.include? self
|
524
589
|
end
|
525
590
|
end
|
526
591
|
|
592
|
+
##
|
593
|
+
#
|
594
|
+
# Asserts that the current node does not match a given selector.
|
595
|
+
# Usage is identical to {#assert_matches_selector}.
|
596
|
+
#
|
597
|
+
# @param (see #assert_matches_selector)
|
598
|
+
# @raise [Capybara::ExpectationNotMet] If the selector matches
|
599
|
+
#
|
527
600
|
def assert_not_matches_selector(*args, &optional_filter_block)
|
528
601
|
_verify_match_result(args, optional_filter_block) do |result|
|
529
602
|
raise Capybara::ExpectationNotMet, 'Item matched the provided selector' if result.include? self
|
530
603
|
end
|
531
604
|
end
|
532
|
-
alias_method :refute_matches_selector, :assert_not_matches_selector
|
533
605
|
|
534
606
|
##
|
535
607
|
#
|
536
|
-
# Checks if the current node matches given selector
|
608
|
+
# Checks if the current node matches given selector.
|
537
609
|
#
|
538
|
-
# @param (see
|
610
|
+
# @param (see #has_selector?)
|
539
611
|
# @return [Boolean]
|
540
612
|
#
|
541
|
-
def matches_selector?(*args, &optional_filter_block)
|
542
|
-
assert_matches_selector(*args, &optional_filter_block)
|
543
|
-
rescue Capybara::ExpectationNotMet
|
544
|
-
false
|
613
|
+
def matches_selector?(*args, **options, &optional_filter_block)
|
614
|
+
make_predicate(options) { assert_matches_selector(*args, options, &optional_filter_block) }
|
545
615
|
end
|
546
616
|
|
547
617
|
##
|
548
618
|
#
|
549
|
-
# Checks if the current node matches given XPath expression
|
619
|
+
# Checks if the current node matches given XPath expression.
|
550
620
|
#
|
551
621
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
552
622
|
# @return [Boolean]
|
553
623
|
#
|
554
624
|
def matches_xpath?(xpath, **options, &optional_filter_block)
|
555
|
-
matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
625
|
+
matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
556
626
|
end
|
557
627
|
|
558
628
|
##
|
559
629
|
#
|
560
|
-
# Checks if the current node matches given CSS selector
|
630
|
+
# Checks if the current node matches given CSS selector.
|
561
631
|
#
|
562
632
|
# @param [String] css The CSS selector to match against the current code
|
563
633
|
# @return [Boolean]
|
564
634
|
#
|
565
635
|
def matches_css?(css, **options, &optional_filter_block)
|
566
|
-
matches_selector?(:css, css, options, &optional_filter_block)
|
636
|
+
matches_selector?(:css, css, **options, &optional_filter_block)
|
567
637
|
end
|
568
638
|
|
569
639
|
##
|
570
640
|
#
|
571
|
-
# Checks if the current node does not match given selector
|
572
|
-
# Usage is identical to
|
641
|
+
# Checks if the current node does not match given selector.
|
642
|
+
# Usage is identical to {#has_selector?}.
|
573
643
|
#
|
574
|
-
# @param (see
|
644
|
+
# @param (see #has_selector?)
|
575
645
|
# @return [Boolean]
|
576
646
|
#
|
577
|
-
def not_matches_selector?(*args, &optional_filter_block)
|
578
|
-
assert_not_matches_selector(*args, &optional_filter_block)
|
579
|
-
rescue Capybara::ExpectationNotMet
|
580
|
-
false
|
647
|
+
def not_matches_selector?(*args, **options, &optional_filter_block)
|
648
|
+
make_predicate(options) { assert_not_matches_selector(*args, options, &optional_filter_block) }
|
581
649
|
end
|
582
650
|
|
583
651
|
##
|
584
652
|
#
|
585
|
-
# Checks if the current node does not match given XPath expression
|
653
|
+
# Checks if the current node does not match given XPath expression.
|
586
654
|
#
|
587
655
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
588
656
|
# @return [Boolean]
|
589
657
|
#
|
590
658
|
def not_matches_xpath?(xpath, **options, &optional_filter_block)
|
591
|
-
not_matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
659
|
+
not_matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
592
660
|
end
|
593
661
|
|
594
662
|
##
|
595
663
|
#
|
596
|
-
# Checks if the current node does not match given CSS selector
|
664
|
+
# Checks if the current node does not match given CSS selector.
|
597
665
|
#
|
598
666
|
# @param [String] css The CSS selector to match against the current code
|
599
667
|
# @return [Boolean]
|
600
668
|
#
|
601
669
|
def not_matches_css?(css, **options, &optional_filter_block)
|
602
|
-
not_matches_selector?(:css, css, options, &optional_filter_block)
|
670
|
+
not_matches_selector?(:css, css, **options, &optional_filter_block)
|
603
671
|
end
|
604
672
|
|
605
673
|
##
|
@@ -608,27 +676,29 @@ module Capybara
|
|
608
676
|
#
|
609
677
|
# @!macro text_query_params
|
610
678
|
# @overload $0(type, text, **options)
|
611
|
-
# @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
|
679
|
+
# @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`.
|
612
680
|
# @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.
|
613
681
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
614
682
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
615
683
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
616
684
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
617
|
-
# @option options [Numeric] :wait
|
618
|
-
# @option options [Boolean] :exact
|
685
|
+
# @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}.
|
686
|
+
# @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
|
687
|
+
# @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
|
619
688
|
# @overload $0(text, **options)
|
620
689
|
# @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.
|
621
690
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
622
691
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
623
692
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
624
693
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
625
|
-
# @option options [Numeric] :wait
|
626
|
-
# @option options [Boolean] :exact
|
694
|
+
# @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}.
|
695
|
+
# @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
|
696
|
+
# @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
|
627
697
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
628
698
|
# @return [true]
|
629
699
|
#
|
630
|
-
def assert_text(*args)
|
631
|
-
_verify_text(args) do |count, query|
|
700
|
+
def assert_text(type_or_text, *args, **opts)
|
701
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
632
702
|
unless query.matches_count?(count) && (count.positive? || query.expects_none?)
|
633
703
|
raise Capybara::ExpectationNotMet, query.failure_message
|
634
704
|
end
|
@@ -643,8 +713,8 @@ module Capybara
|
|
643
713
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
644
714
|
# @return [true]
|
645
715
|
#
|
646
|
-
def assert_no_text(*args)
|
647
|
-
_verify_text(args) do |count, query|
|
716
|
+
def assert_no_text(type_or_text, *args, **opts)
|
717
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
648
718
|
if query.matches_count?(count) && (count.positive? || query.expects_none?)
|
649
719
|
raise Capybara::ExpectationNotMet, query.negative_failure_message
|
650
720
|
end
|
@@ -665,10 +735,8 @@ module Capybara
|
|
665
735
|
# @macro text_query_params
|
666
736
|
# @return [Boolean] Whether it exists
|
667
737
|
#
|
668
|
-
def has_text?(*args)
|
669
|
-
assert_text(*args)
|
670
|
-
rescue Capybara::ExpectationNotMet
|
671
|
-
false
|
738
|
+
def has_text?(*args, **options)
|
739
|
+
make_predicate(options) { assert_text(*args, **options) }
|
672
740
|
end
|
673
741
|
alias_method :has_content?, :has_text?
|
674
742
|
|
@@ -679,13 +747,97 @@ module Capybara
|
|
679
747
|
# @macro text_query_params
|
680
748
|
# @return [Boolean] Whether it doesn't exist
|
681
749
|
#
|
682
|
-
def has_no_text?(*args)
|
683
|
-
assert_no_text(*args)
|
684
|
-
rescue Capybara::ExpectationNotMet
|
685
|
-
false
|
750
|
+
def has_no_text?(*args, **options)
|
751
|
+
make_predicate(options) { assert_no_text(*args, **options) }
|
686
752
|
end
|
687
753
|
alias_method :has_no_content?, :has_no_text?
|
688
754
|
|
755
|
+
##
|
756
|
+
#
|
757
|
+
# Asserts that a given selector matches an ancestor of the current node.
|
758
|
+
#
|
759
|
+
# element.assert_ancestor('p#foo')
|
760
|
+
#
|
761
|
+
# Accepts the same options as {#assert_selector}
|
762
|
+
#
|
763
|
+
# @param (see Capybara::Node::Finders#find)
|
764
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
765
|
+
#
|
766
|
+
def assert_ancestor(*args, &optional_filter_block)
|
767
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::AncestorQuery) do |result, query|
|
768
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
769
|
+
raise Capybara::ExpectationNotMet, result.failure_message
|
770
|
+
end
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
def assert_no_ancestor(*args, &optional_filter_block)
|
775
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::AncestorQuery) do |result, query|
|
776
|
+
if result.matches_count? && (!result.empty? || query.expects_none?)
|
777
|
+
raise Capybara::ExpectationNotMet, result.negative_failure_message
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
##
|
783
|
+
#
|
784
|
+
# Predicate version of {#assert_ancestor}
|
785
|
+
#
|
786
|
+
def has_ancestor?(*args, **options, &optional_filter_block)
|
787
|
+
make_predicate(options) { assert_ancestor(*args, options, &optional_filter_block) }
|
788
|
+
end
|
789
|
+
|
790
|
+
##
|
791
|
+
#
|
792
|
+
# Predicate version of {#assert_no_ancestor}
|
793
|
+
#
|
794
|
+
def has_no_ancestor?(*args, **options, &optional_filter_block)
|
795
|
+
make_predicate(options) { assert_no_ancestor(*args, options, &optional_filter_block) }
|
796
|
+
end
|
797
|
+
|
798
|
+
##
|
799
|
+
#
|
800
|
+
# Asserts that a given selector matches a sibling of the current node.
|
801
|
+
#
|
802
|
+
# element.assert_sibling('p#foo')
|
803
|
+
#
|
804
|
+
# Accepts the same options as {#assert_selector}
|
805
|
+
#
|
806
|
+
# @param (see Capybara::Node::Finders#find)
|
807
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
808
|
+
#
|
809
|
+
def assert_sibling(*args, &optional_filter_block)
|
810
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
|
811
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
812
|
+
raise Capybara::ExpectationNotMet, result.failure_message
|
813
|
+
end
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
def assert_no_sibling(*args, &optional_filter_block)
|
818
|
+
_verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
|
819
|
+
if result.matches_count? && (!result.empty? || query.expects_none?)
|
820
|
+
raise Capybara::ExpectationNotMet, result.negative_failure_message
|
821
|
+
end
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
##
|
826
|
+
#
|
827
|
+
# Predicate version of {#assert_sibling}
|
828
|
+
#
|
829
|
+
def has_sibling?(*args, **options, &optional_filter_block)
|
830
|
+
make_predicate(options) { assert_sibling(*args, options, &optional_filter_block) }
|
831
|
+
end
|
832
|
+
|
833
|
+
##
|
834
|
+
#
|
835
|
+
# Predicate version of {#assert_no_sibling}
|
836
|
+
#
|
837
|
+
def has_no_sibling?(*args, **options, &optional_filter_block)
|
838
|
+
make_predicate(options) { assert_no_sibling(*args, options, &optional_filter_block) }
|
839
|
+
end
|
840
|
+
|
689
841
|
def ==(other)
|
690
842
|
eql?(other) || (other.respond_to?(:base) && base == other.base)
|
691
843
|
end
|
@@ -696,9 +848,23 @@ module Capybara
|
|
696
848
|
args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
697
849
|
end
|
698
850
|
|
699
|
-
def
|
700
|
-
|
701
|
-
|
851
|
+
def _verify_multiple(*args, wait: nil, **options)
|
852
|
+
wait = session_options.default_max_wait_time if wait.nil?
|
853
|
+
selector = extract_selector(args)
|
854
|
+
synchronize(wait) do
|
855
|
+
args.each { |locator| yield(selector, locator, options) }
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
def _verify_selector_result(query_args, optional_filter_block, query_type = Capybara::Queries::SelectorQuery)
|
860
|
+
# query_args, query_opts = if query_args[0].is_a? Symbol
|
861
|
+
# a,o = _set_query_session_options(*query_args.slice(2..))
|
862
|
+
# [query_args.slice(0..1).concat(a), o]
|
863
|
+
# else
|
864
|
+
# _set_query_session_options(*query_args)
|
865
|
+
# end
|
866
|
+
query_args, query_opts = _set_query_session_options(*query_args)
|
867
|
+
query = query_type.new(*query_args, **query_opts, &optional_filter_block)
|
702
868
|
synchronize(query.wait) do
|
703
869
|
yield query.resolve_for(self), query
|
704
870
|
end
|
@@ -706,26 +872,36 @@ module Capybara
|
|
706
872
|
end
|
707
873
|
|
708
874
|
def _verify_match_result(query_args, optional_filter_block)
|
709
|
-
query_args = _set_query_session_options(*query_args)
|
710
|
-
query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
|
875
|
+
query_args, query_opts = _set_query_session_options(*query_args)
|
876
|
+
query = Capybara::Queries::MatchQuery.new(*query_args, **query_opts, &optional_filter_block)
|
711
877
|
synchronize(query.wait) do
|
712
|
-
yield query.resolve_for(query_scope)
|
878
|
+
yield query.resolve_for(parent || session&.document || query_scope)
|
713
879
|
end
|
714
880
|
true
|
715
881
|
end
|
716
882
|
|
717
|
-
def _verify_text(
|
718
|
-
|
719
|
-
query = Capybara::Queries::TextQuery.new(
|
883
|
+
def _verify_text(type = nil, expected_text, **query_options) # rubocop:disable Style/OptionalArguments
|
884
|
+
query_options[:session_options] = session_options
|
885
|
+
query = Capybara::Queries::TextQuery.new(type, expected_text, **query_options)
|
720
886
|
synchronize(query.wait) do
|
721
887
|
yield query.resolve_for(self), query
|
722
888
|
end
|
723
889
|
true
|
724
890
|
end
|
725
891
|
|
726
|
-
def _set_query_session_options(*query_args
|
892
|
+
def _set_query_session_options(*query_args)
|
893
|
+
query_args, query_options = query_args.dup, {}
|
894
|
+
# query_options = query_args.pop if query_options.empty? && query_args.last.is_a?(Hash)
|
895
|
+
query_options = query_args.pop if query_args.last.is_a?(Hash)
|
727
896
|
query_options[:session_options] = session_options
|
728
|
-
query_args
|
897
|
+
[query_args, query_options]
|
898
|
+
end
|
899
|
+
|
900
|
+
def make_predicate(options)
|
901
|
+
options[:wait] = 0 unless options.key?(:wait) || session_options.predicates_wait
|
902
|
+
yield
|
903
|
+
rescue Capybara::ExpectationNotMet
|
904
|
+
false
|
729
905
|
end
|
730
906
|
end
|
731
907
|
end
|