capybara 3.3.0 → 3.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/History.md +803 -13
- data/License.txt +1 -1
- data/README.md +257 -84
- data/lib/capybara/config.rb +25 -9
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +17 -3
- data/lib/capybara/driver/node.rb +31 -6
- data/lib/capybara/dsl.rb +9 -7
- data/lib/capybara/helpers.rb +31 -7
- data/lib/capybara/minitest/spec.rb +180 -88
- data/lib/capybara/minitest.rb +262 -149
- data/lib/capybara/node/actions.rb +202 -116
- data/lib/capybara/node/base.rb +34 -19
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +10 -12
- data/lib/capybara/node/element.rb +269 -115
- data/lib/capybara/node/finders.rb +99 -77
- data/lib/capybara/node/matchers.rb +327 -151
- data/lib/capybara/node/simple.rb +48 -13
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +8 -9
- data/lib/capybara/queries/base_query.rb +23 -16
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +1 -0
- data/lib/capybara/queries/selector_query.rb +587 -130
- data/lib/capybara/queries/sibling_query.rb +8 -6
- data/lib/capybara/queries/style_query.rb +6 -2
- data/lib/capybara/queries/text_query.rb +28 -14
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +92 -25
- data/lib/capybara/rack_test/driver.rb +16 -7
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +68 -41
- data/lib/capybara/rack_test/node.rb +106 -39
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +75 -52
- data/lib/capybara/rspec/features.rb +7 -7
- data/lib/capybara/rspec/matcher_proxies.rb +39 -18
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +141 -339
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +27 -25
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +1 -0
- data/lib/capybara/selector/filter_set.rb +73 -25
- data/lib/capybara/selector/filters/base.rb +24 -5
- data/lib/capybara/selector/filters/expression_filter.rb +3 -3
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -2
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +85 -348
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +474 -447
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +255 -143
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +436 -134
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +56 -19
- data/lib/capybara/server/checker.rb +9 -3
- data/lib/capybara/server/middleware.rb +28 -12
- data/lib/capybara/server.rb +33 -10
- data/lib/capybara/session/config.rb +34 -10
- data/lib/capybara/session/matchers.rb +23 -16
- data/lib/capybara/session.rb +230 -170
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +121 -8
- data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +127 -40
- data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
- data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
- data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
- data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
- data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
- data/lib/capybara/spec/session/body_spec.rb +6 -6
- data/lib/capybara/spec/session/check_spec.rb +102 -47
- data/lib/capybara/spec/session/choose_spec.rb +58 -32
- data/lib/capybara/spec/session/click_button_spec.rb +219 -163
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
- data/lib/capybara/spec/session/click_link_spec.rb +77 -54
- data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
- data/lib/capybara/spec/session/current_url_spec.rb +38 -29
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
- data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
- data/lib/capybara/spec/session/find_field_spec.rb +32 -30
- data/lib/capybara/spec/session/find_link_spec.rb +31 -21
- data/lib/capybara/spec/session/find_spec.rb +244 -141
- data/lib/capybara/spec/session/first_spec.rb +43 -43
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +94 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -132
- data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +137 -58
- data/lib/capybara/spec/session/has_link_spec.rb +44 -4
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
- data/lib/capybara/spec/session/has_select_spec.rb +84 -50
- data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +181 -4
- data/lib/capybara/spec/session/has_text_spec.rb +101 -53
- data/lib/capybara/spec/session/has_title_spec.rb +19 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
- data/lib/capybara/spec/session/headers_spec.rb +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +894 -142
- data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
- data/lib/capybara/spec/session/response_code_spec.rb +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +37 -37
- data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +85 -85
- data/lib/capybara/spec/session/selectors_spec.rb +49 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +25 -24
- data/lib/capybara/spec/session/title_spec.rb +7 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +68 -49
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
- data/lib/capybara/spec/session/window/window_spec.rb +62 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
- data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
- data/lib/capybara/spec/session/within_spec.rb +79 -42
- data/lib/capybara/spec/spec_helper.rb +41 -53
- data/lib/capybara/spec/test_app.rb +132 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +139 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +67 -0
- data/lib/capybara/spec/views/with_animation.erb +39 -4
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +37 -9
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +26 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +19 -25
- data/lib/capybara.rb +126 -111
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +56 -44
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +8 -8
- data/spec/dsl_spec.rb +79 -52
- data/spec/filter_set_spec.rb +9 -9
- data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
- data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
- data/spec/minitest_spec.rb +45 -7
- data/spec/minitest_spec_spec.rb +87 -64
- data/spec/per_session_config_spec.rb +6 -6
- data/spec/rack_test_spec.rb +172 -116
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +80 -72
- data/spec/rspec/features_spec.rb +21 -16
- data/spec/rspec/scenarios_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +407 -365
- data/spec/rspec/views_spec.rb +3 -3
- data/spec/rspec_matchers_spec.rb +35 -10
- data/spec/rspec_spec.rb +63 -41
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +334 -89
- data/spec/selenium_spec_chrome.rb +176 -62
- data/spec/selenium_spec_chrome_remote.rb +54 -14
- data/spec/selenium_spec_edge.rb +41 -8
- data/spec/selenium_spec_firefox.rb +228 -0
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +129 -11
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +171 -97
- data/spec/session_spec.rb +34 -18
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +344 -80
- data/spec/spec_helper.rb +124 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +326 -28
- data/lib/capybara/rspec/compound.rb +0 -94
- data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
- data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
- data/lib/capybara/spec/session/has_style_spec.rb +0 -25
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -167
|
@@ -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
|