capybara 3.0.0 → 3.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/History.md +891 -12
- data/License.txt +1 -1
- data/README.md +257 -84
- data/lib/capybara/config.rb +29 -10
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +22 -4
- data/lib/capybara/driver/node.rb +38 -9
- data/lib/capybara/dsl.rb +9 -7
- data/lib/capybara/helpers.rb +57 -8
- data/lib/capybara/minitest/spec.rb +185 -84
- data/lib/capybara/minitest.rb +264 -145
- data/lib/capybara/node/actions.rb +248 -124
- data/lib/capybara/node/base.rb +35 -20
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +13 -15
- data/lib/capybara/node/element.rb +350 -113
- data/lib/capybara/node/finders.rb +104 -82
- data/lib/capybara/node/matchers.rb +363 -157
- data/lib/capybara/node/simple.rb +54 -15
- 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 +9 -10
- data/lib/capybara/queries/base_query.rb +25 -18
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +11 -0
- data/lib/capybara/queries/selector_query.rb +617 -104
- data/lib/capybara/queries/sibling_query.rb +9 -7
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +40 -22
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +106 -31
- 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 +74 -49
- data/lib/capybara/rack_test/node.rb +120 -47
- 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 +87 -53
- data/lib/capybara/rspec/features.rb +8 -10
- 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 +142 -315
- data/lib/capybara/rspec.rb +3 -2
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +85 -8
- 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 +72 -28
- data/lib/capybara/selector/filters/base.rb +45 -2
- data/lib/capybara/selector/filters/expression_filter.rb +5 -6
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +18 -4
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +89 -200
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +474 -534
- 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 +270 -245
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +460 -170
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +80 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +58 -67
- data/lib/capybara/session/config.rb +40 -6
- data/lib/capybara/session/matchers.rb +26 -19
- data/lib/capybara/session.rb +252 -194
- 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 +126 -8
- data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +135 -44
- data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
- data/lib/capybara/spec/session/{assert_current_path.rb → assert_current_path_spec.rb} +20 -18
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/{assert_text.rb → assert_text_spec.rb} +76 -52
- data/lib/capybara/spec/session/{assert_title.rb → 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 +11 -13
- data/lib/capybara/spec/session/check_spec.rb +112 -51
- data/lib/capybara/spec/session/choose_spec.rb +62 -30
- data/lib/capybara/spec/session/click_button_spec.rb +227 -161
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -30
- data/lib/capybara/spec/session/click_link_spec.rb +89 -55
- data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
- data/lib/capybara/spec/session/current_url_spec.rb +44 -37
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
- data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +8 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +70 -56
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +110 -44
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +8 -8
- data/lib/capybara/spec/session/find_field_spec.rb +33 -31
- data/lib/capybara/spec/session/find_link_spec.rb +42 -14
- data/lib/capybara/spec/session/find_spec.rb +251 -142
- data/lib/capybara/spec/session/first_spec.rb +45 -44
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +32 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +46 -19
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +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 +98 -12
- data/lib/capybara/spec/session/has_css_spec.rb +271 -137
- 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 +46 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +33 -31
- data/lib/capybara/spec/session/has_select_spec.rb +84 -50
- data/lib/capybara/spec/session/has_selector_spec.rb +117 -69
- 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.rb → headers_spec.rb} +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +958 -122
- data/lib/capybara/spec/session/node_wrapper_spec.rb +15 -12
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +65 -37
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +5 -4
- data/lib/capybara/spec/session/save_page_spec.rb +41 -38
- data/lib/capybara/spec/session/save_screenshot_spec.rb +13 -11
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +102 -76
- data/lib/capybara/spec/session/selectors_spec.rb +51 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +26 -24
- data/lib/capybara/spec/session/title_spec.rb +8 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +41 -22
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +79 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +22 -19
- data/lib/capybara/spec/session/window/current_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +25 -21
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +10 -5
- data/lib/capybara/spec/session/window/window_spec.rb +88 -54
- data/lib/capybara/spec/session/window/windows_spec.rb +11 -8
- data/lib/capybara/spec/session/window/within_window_spec.rb +17 -16
- data/lib/capybara/spec/session/within_spec.rb +82 -44
- data/lib/capybara/spec/spec_helper.rb +46 -52
- data/lib/capybara/spec/test_app.rb +148 -41
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +156 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +68 -1
- data/lib/capybara/spec/views/with_animation.erb +81 -0
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +46 -11
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +30 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +21 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +32 -26
- data/lib/capybara.rb +128 -104
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +65 -51
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +84 -55
- data/spec/filter_set_spec.rb +24 -7
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +5 -5
- data/spec/minitest_spec.rb +49 -5
- data/spec/minitest_spec_spec.rb +92 -62
- data/spec/per_session_config_spec.rb +6 -6
- data/spec/rack_test_spec.rb +183 -115
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +99 -39
- data/spec/rspec/features_spec.rb +28 -25
- data/spec/rspec/scenarios_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +418 -364
- data/spec/rspec/views_spec.rb +4 -3
- data/spec/rspec_matchers_spec.rb +35 -10
- data/spec/rspec_spec.rb +109 -85
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +392 -62
- data/spec/selenium_spec_chrome.rb +183 -41
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- 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 +192 -81
- data/spec/session_spec.rb +52 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +460 -123
- data/spec/spec_helper.rb +124 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +344 -45
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/lib/capybara/rspec/compound.rb +0 -90
- data/lib/capybara/spec/session/assert_selector.rb +0 -149
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -143
@@ -19,41 +19,58 @@ module Capybara
|
|
19
19
|
# This will check if the expression occurs exactly 4 times.
|
20
20
|
#
|
21
21
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
22
|
-
# such as
|
22
|
+
# such as `:text` and `:visible`.
|
23
23
|
#
|
24
24
|
# page.has_selector?('li', text: 'Horse', visible: true)
|
25
25
|
#
|
26
|
-
# has_selector? can also accept XPath expressions generated by the
|
26
|
+
# {#has_selector?} can also accept XPath expressions generated by the
|
27
27
|
# XPath gem:
|
28
28
|
#
|
29
29
|
# page.has_selector?(:xpath, XPath.descendant(:p))
|
30
30
|
#
|
31
31
|
# @param (see Capybara::Node::Finders#all)
|
32
|
-
# @
|
33
|
-
# @option
|
34
|
-
# @option
|
35
|
-
# @option
|
36
|
-
# @option args [Range] :between (nil) Range of times that should contain number of times text occurs
|
32
|
+
# @option options [Integer] :count (nil) Number of matching elements that should exist
|
33
|
+
# @option options [Integer] :minimum (nil) Minimum number of matching elements that should exist
|
34
|
+
# @option options [Integer] :maximum (nil) Maximum number of matching elements that should exist
|
35
|
+
# @option options [Range] :between (nil) Range of number of matching elements that should exist
|
37
36
|
# @return [Boolean] If the expression exists
|
38
37
|
#
|
39
|
-
def has_selector?(*args, &optional_filter_block)
|
40
|
-
assert_selector(*args, &optional_filter_block)
|
41
|
-
rescue Capybara::ExpectationNotMet
|
42
|
-
false
|
38
|
+
def has_selector?(*args, **options, &optional_filter_block)
|
39
|
+
make_predicate(options) { assert_selector(*args, options, &optional_filter_block) }
|
43
40
|
end
|
44
41
|
|
45
42
|
##
|
46
43
|
#
|
47
44
|
# Checks if a given selector is not on the page or a descendant of the current node.
|
48
|
-
# Usage is identical to
|
45
|
+
# Usage is identical to {#has_selector?}.
|
49
46
|
#
|
50
|
-
# @param (see
|
47
|
+
# @param (see #has_selector?)
|
51
48
|
# @return [Boolean]
|
52
49
|
#
|
53
|
-
def has_no_selector?(*args, &optional_filter_block)
|
54
|
-
assert_no_selector(*args, &optional_filter_block)
|
55
|
-
|
56
|
-
|
50
|
+
def has_no_selector?(*args, **options, &optional_filter_block)
|
51
|
+
make_predicate(options) { assert_no_selector(*args, options, &optional_filter_block) }
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
#
|
56
|
+
# Checks if a an element has the specified CSS styles.
|
57
|
+
#
|
58
|
+
# element.matches_style?( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
59
|
+
#
|
60
|
+
# @param styles [Hash]
|
61
|
+
# @return [Boolean] If the styles match
|
62
|
+
#
|
63
|
+
def matches_style?(styles = nil, **options)
|
64
|
+
styles, options = options, {} if styles.nil?
|
65
|
+
make_predicate(options) { assert_matches_style(styles, **options) }
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# @deprecated Use {#matches_style?} instead.
|
70
|
+
#
|
71
|
+
def has_style?(styles = nil, **options)
|
72
|
+
Capybara::Helpers.warn "DEPRECATED: has_style? is deprecated, please use matches_style? : #{Capybara::Helpers.filter_backtrace(caller)}"
|
73
|
+
matches_style?(styles, **options)
|
57
74
|
end
|
58
75
|
|
59
76
|
##
|
@@ -72,15 +89,15 @@ module Capybara
|
|
72
89
|
# This will check if the expression occurs exactly 4 times. See
|
73
90
|
# {Capybara::Node::Finders#all} for other available result size options.
|
74
91
|
#
|
75
|
-
# If a
|
92
|
+
# If a `:count` of 0 is specified, it will behave like {#assert_no_selector};
|
76
93
|
# however, use of that method is preferred over this one.
|
77
94
|
#
|
78
95
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
79
|
-
# such as
|
96
|
+
# such as `:text` and `:visible`.
|
80
97
|
#
|
81
98
|
# page.assert_selector('li', text: 'Horse', visible: true)
|
82
99
|
#
|
83
|
-
#
|
100
|
+
# {#assert_selector} can also accept XPath expressions generated by the
|
84
101
|
# XPath gem:
|
85
102
|
#
|
86
103
|
# page.assert_selector(:xpath, XPath.descendant(:p))
|
@@ -91,76 +108,126 @@ module Capybara
|
|
91
108
|
#
|
92
109
|
def assert_selector(*args, &optional_filter_block)
|
93
110
|
_verify_selector_result(args, optional_filter_block) do |result, query|
|
94
|
-
unless result.matches_count? && (
|
111
|
+
unless result.matches_count? && (result.any? || query.expects_none?)
|
95
112
|
raise Capybara::ExpectationNotMet, result.failure_message
|
96
113
|
end
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
117
|
+
##
|
118
|
+
#
|
119
|
+
# Asserts that an element has the specified CSS styles.
|
120
|
+
#
|
121
|
+
# element.assert_matches_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
|
122
|
+
#
|
123
|
+
# @param styles [Hash]
|
124
|
+
# @raise [Capybara::ExpectationNotMet] If the element doesn't have the specified styles
|
125
|
+
#
|
126
|
+
def assert_matches_style(styles = nil, **options)
|
127
|
+
styles, options = options, {} if styles.nil?
|
128
|
+
query_args, query_opts = _set_query_session_options(styles, options)
|
129
|
+
query = Capybara::Queries::StyleQuery.new(*query_args, **query_opts)
|
130
|
+
synchronize(query.wait) do
|
131
|
+
raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
|
132
|
+
end
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# @deprecated Use {#assert_matches_style} instead.
|
138
|
+
#
|
139
|
+
def assert_style(styles = nil, **options)
|
140
|
+
warn 'assert_style is deprecated, please use assert_matches_style instead'
|
141
|
+
assert_matches_style(styles, **options)
|
142
|
+
end
|
143
|
+
|
100
144
|
# Asserts that all of the provided selectors are present on the given page
|
101
145
|
# or descendants of the current node. If options are provided, the assertion
|
102
|
-
# will check that each locator is present with those options as well (other than
|
146
|
+
# will check that each locator is present with those options as well (other than `:wait`).
|
103
147
|
#
|
104
|
-
#
|
105
|
-
#
|
148
|
+
# page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
149
|
+
# page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
|
106
150
|
#
|
107
151
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
108
|
-
# such as
|
152
|
+
# such as `:text` and `:visible`.
|
109
153
|
#
|
110
|
-
# The
|
111
|
-
# within
|
154
|
+
# The `:wait` option applies to all of the selectors as a group, so all of the locators must be present
|
155
|
+
# within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
|
112
156
|
#
|
113
|
-
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, options
|
157
|
+
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
114
158
|
#
|
115
|
-
def assert_all_of_selectors(*args,
|
116
|
-
|
117
|
-
|
118
|
-
synchronize(wait) do
|
119
|
-
args.each do |locator|
|
120
|
-
assert_selector(selector, locator, options, &optional_filter_block)
|
121
|
-
end
|
159
|
+
def assert_all_of_selectors(*args, **options, &optional_filter_block)
|
160
|
+
_verify_multiple(*args, **options) do |selector, locator, opts|
|
161
|
+
assert_selector(selector, locator, opts, &optional_filter_block)
|
122
162
|
end
|
123
163
|
end
|
124
164
|
|
125
165
|
# Asserts that none of the provided selectors are present on the given page
|
126
166
|
# or descendants of the current node. If options are provided, the assertion
|
127
|
-
# will check that each locator is present with those options as well (other than
|
167
|
+
# will check that each locator is not present with those options as well (other than `:wait`).
|
128
168
|
#
|
129
|
-
#
|
130
|
-
#
|
169
|
+
# page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
|
170
|
+
# page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
|
131
171
|
#
|
132
172
|
# It accepts all options that {Capybara::Node::Finders#all} accepts,
|
133
|
-
# such as
|
173
|
+
# such as `:text` and `:visible`.
|
134
174
|
#
|
135
|
-
# The
|
136
|
-
# 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.
|
137
177
|
#
|
138
|
-
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, options
|
178
|
+
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, **options)
|
139
179
|
#
|
140
|
-
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)
|
141
202
|
wait = session_options.default_max_wait_time if wait.nil?
|
142
|
-
selector = args
|
203
|
+
selector = extract_selector(args)
|
143
204
|
synchronize(wait) do
|
144
|
-
args.
|
145
|
-
|
205
|
+
res = args.map do |locator|
|
206
|
+
assert_selector(selector, locator, options, &optional_filter_block)
|
207
|
+
break nil
|
208
|
+
rescue Capybara::ExpectationNotMet => e
|
209
|
+
e.message
|
146
210
|
end
|
211
|
+
raise Capybara::ExpectationNotMet, res.join(' or ') if res
|
212
|
+
|
213
|
+
true
|
147
214
|
end
|
148
215
|
end
|
149
216
|
|
150
217
|
##
|
151
218
|
#
|
152
219
|
# Asserts that a given selector is not on the page or a descendant of the current node.
|
153
|
-
# Usage is identical to
|
220
|
+
# Usage is identical to {#assert_selector}.
|
154
221
|
#
|
155
|
-
# Query options such as
|
222
|
+
# Query options such as `:count`, `:minimum`, `:maximum`, and `:between` are
|
156
223
|
# considered to be an integral part of the selector. This will return
|
157
|
-
# true
|
224
|
+
# `true`, for example, if a page contains 4 anchors but the query expects 5:
|
158
225
|
#
|
159
226
|
# page.assert_no_selector('a', minimum: 1) # Found, raises Capybara::ExpectationNotMet
|
160
227
|
# page.assert_no_selector('a', count: 4) # Found, raises Capybara::ExpectationNotMet
|
161
228
|
# page.assert_no_selector('a', count: 5) # Not Found, returns true
|
162
229
|
#
|
163
|
-
# @param (see
|
230
|
+
# @param (see #assert_selector)
|
164
231
|
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
165
232
|
#
|
166
233
|
def assert_no_selector(*args, &optional_filter_block)
|
@@ -170,7 +237,6 @@ module Capybara
|
|
170
237
|
end
|
171
238
|
end
|
172
239
|
end
|
173
|
-
alias_method :refute_selector, :assert_no_selector
|
174
240
|
|
175
241
|
##
|
176
242
|
#
|
@@ -186,11 +252,11 @@ module Capybara
|
|
186
252
|
# This will check if the expression occurs exactly 4 times.
|
187
253
|
#
|
188
254
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
189
|
-
# such as
|
255
|
+
# such as `:text` and `:visible`.
|
190
256
|
#
|
191
257
|
# page.has_xpath?('.//li', text: 'Horse', visible: true)
|
192
258
|
#
|
193
|
-
# has_xpath? can also accept XPath expressions
|
259
|
+
# {#has_xpath?} can also accept XPath expressions generated by the
|
194
260
|
# XPath gem:
|
195
261
|
#
|
196
262
|
# xpath = XPath.generate { |x| x.descendant(:p) }
|
@@ -202,19 +268,19 @@ module Capybara
|
|
202
268
|
# @return [Boolean] If the expression exists
|
203
269
|
#
|
204
270
|
def has_xpath?(path, **options, &optional_filter_block)
|
205
|
-
has_selector?(:xpath, path, options, &optional_filter_block)
|
271
|
+
has_selector?(:xpath, path, **options, &optional_filter_block)
|
206
272
|
end
|
207
273
|
|
208
274
|
##
|
209
275
|
#
|
210
276
|
# Checks if a given XPath expression is not on the page or a descendant of the current node.
|
211
|
-
# Usage is identical to
|
277
|
+
# Usage is identical to {#has_xpath?}.
|
212
278
|
#
|
213
|
-
# @param (see
|
279
|
+
# @param (see #has_xpath?)
|
214
280
|
# @return [Boolean]
|
215
281
|
#
|
216
282
|
def has_no_xpath?(path, **options, &optional_filter_block)
|
217
|
-
has_no_selector?(:xpath, path, options, &optional_filter_block)
|
283
|
+
has_no_selector?(:xpath, path, **options, &optional_filter_block)
|
218
284
|
end
|
219
285
|
|
220
286
|
##
|
@@ -231,7 +297,7 @@ module Capybara
|
|
231
297
|
# This will check if the selector occurs exactly 4 times.
|
232
298
|
#
|
233
299
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
234
|
-
# such as
|
300
|
+
# such as `:text` and `:visible`.
|
235
301
|
#
|
236
302
|
# page.has_css?('li', text: 'Horse', visible: true)
|
237
303
|
#
|
@@ -241,19 +307,44 @@ module Capybara
|
|
241
307
|
# @return [Boolean] If the selector exists
|
242
308
|
#
|
243
309
|
def has_css?(path, **options, &optional_filter_block)
|
244
|
-
has_selector?(:css, path, options, &optional_filter_block)
|
310
|
+
has_selector?(:css, path, **options, &optional_filter_block)
|
245
311
|
end
|
246
312
|
|
247
313
|
##
|
248
314
|
#
|
249
315
|
# Checks if a given CSS selector is not on the page or a descendant of the current node.
|
250
|
-
# Usage is identical to
|
316
|
+
# Usage is identical to {#has_css?}.
|
251
317
|
#
|
252
|
-
# @param (see
|
318
|
+
# @param (see #has_css?)
|
253
319
|
# @return [Boolean]
|
254
320
|
#
|
255
321
|
def has_no_css?(path, **options, &optional_filter_block)
|
256
|
-
has_no_selector?(:css, path, options, &optional_filter_block)
|
322
|
+
has_no_selector?(:css, path, **options, &optional_filter_block)
|
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)
|
257
348
|
end
|
258
349
|
|
259
350
|
##
|
@@ -262,12 +353,11 @@ module Capybara
|
|
262
353
|
# text or id.
|
263
354
|
#
|
264
355
|
# @param [String] locator The text or id of a link to check for
|
265
|
-
# @param options
|
266
356
|
# @option options [String, Regexp] :href The value the href attribute must be
|
267
357
|
# @return [Boolean] Whether it exists
|
268
358
|
#
|
269
359
|
def has_link?(locator = nil, **options, &optional_filter_block)
|
270
|
-
has_selector?(:link, locator, options, &optional_filter_block)
|
360
|
+
has_selector?(:link, locator, **options, &optional_filter_block)
|
271
361
|
end
|
272
362
|
|
273
363
|
##
|
@@ -275,11 +365,11 @@ module Capybara
|
|
275
365
|
# Checks if the page or current node has no link with the given
|
276
366
|
# text or id.
|
277
367
|
#
|
278
|
-
# @param (see
|
368
|
+
# @param (see #has_link?)
|
279
369
|
# @return [Boolean] Whether it doesn't exist
|
280
370
|
#
|
281
371
|
def has_no_link?(locator = nil, **options, &optional_filter_block)
|
282
|
-
has_no_selector?(:link, locator, options, &optional_filter_block)
|
372
|
+
has_no_selector?(:link, locator, **options, &optional_filter_block)
|
283
373
|
end
|
284
374
|
|
285
375
|
##
|
@@ -291,7 +381,7 @@ module Capybara
|
|
291
381
|
# @return [Boolean] Whether it exists
|
292
382
|
#
|
293
383
|
def has_button?(locator = nil, **options, &optional_filter_block)
|
294
|
-
has_selector?(:button, locator, options, &optional_filter_block)
|
384
|
+
has_selector?(:button, locator, **options, &optional_filter_block)
|
295
385
|
end
|
296
386
|
|
297
387
|
##
|
@@ -303,7 +393,7 @@ module Capybara
|
|
303
393
|
# @return [Boolean] Whether it doesn't exist
|
304
394
|
#
|
305
395
|
def has_no_button?(locator = nil, **options, &optional_filter_block)
|
306
|
-
has_no_selector?(:button, locator, options, &optional_filter_block)
|
396
|
+
has_no_selector?(:button, locator, **options, &optional_filter_block)
|
307
397
|
end
|
308
398
|
|
309
399
|
##
|
@@ -312,7 +402,7 @@ module Capybara
|
|
312
402
|
# label, name or id.
|
313
403
|
#
|
314
404
|
# For text fields and other textual fields, such as textareas and
|
315
|
-
# HTML5 email/url/etc. fields, it's possible to specify a
|
405
|
+
# HTML5 email/url/etc. fields, it's possible to specify a `:with`
|
316
406
|
# option to specify the text the field should contain:
|
317
407
|
#
|
318
408
|
# page.has_field?('Name', with: 'Jonas')
|
@@ -321,7 +411,7 @@ module Capybara
|
|
321
411
|
#
|
322
412
|
# page.has_field?('Email', type: 'email')
|
323
413
|
#
|
324
|
-
#
|
414
|
+
# NOTE: 'textarea' and 'select' are valid type values, matching the associated tag names.
|
325
415
|
#
|
326
416
|
# @param [String] locator The label, name or id of a field to check for
|
327
417
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -329,13 +419,13 @@ module Capybara
|
|
329
419
|
# @return [Boolean] Whether it exists
|
330
420
|
#
|
331
421
|
def has_field?(locator = nil, **options, &optional_filter_block)
|
332
|
-
has_selector?(:field, locator, options, &optional_filter_block)
|
422
|
+
has_selector?(:field, locator, **options, &optional_filter_block)
|
333
423
|
end
|
334
424
|
|
335
425
|
##
|
336
426
|
#
|
337
427
|
# Checks if the page or current node has no form field with the given
|
338
|
-
# label, name or id. See {
|
428
|
+
# label, name or id. See {#has_field?}.
|
339
429
|
#
|
340
430
|
# @param [String] locator The label, name or id of a field to check for
|
341
431
|
# @option options [String, Regexp] :with The text content of the field or a Regexp to match
|
@@ -343,59 +433,59 @@ module Capybara
|
|
343
433
|
# @return [Boolean] Whether it doesn't exist
|
344
434
|
#
|
345
435
|
def has_no_field?(locator = nil, **options, &optional_filter_block)
|
346
|
-
has_no_selector?(:field, locator, options, &optional_filter_block)
|
436
|
+
has_no_selector?(:field, locator, **options, &optional_filter_block)
|
347
437
|
end
|
348
438
|
|
349
439
|
##
|
350
440
|
#
|
351
441
|
# Checks if the page or current node has a radio button or
|
352
|
-
# checkbox with the given label, value
|
442
|
+
# checkbox with the given label, value, id, or {Capybara.configure test_id} attribute that is currently
|
353
443
|
# checked.
|
354
444
|
#
|
355
445
|
# @param [String] locator The label, name or id of a checked field
|
356
446
|
# @return [Boolean] Whether it exists
|
357
447
|
#
|
358
448
|
def has_checked_field?(locator = nil, **options, &optional_filter_block)
|
359
|
-
has_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
|
449
|
+
has_selector?(:field, locator, **options.merge(checked: true), &optional_filter_block)
|
360
450
|
end
|
361
451
|
|
362
452
|
##
|
363
453
|
#
|
364
454
|
# Checks if the page or current node has no radio button or
|
365
|
-
# 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
|
366
456
|
# checked.
|
367
457
|
#
|
368
458
|
# @param [String] locator The label, name or id of a checked field
|
369
459
|
# @return [Boolean] Whether it doesn't exist
|
370
460
|
#
|
371
461
|
def has_no_checked_field?(locator = nil, **options, &optional_filter_block)
|
372
|
-
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)
|
373
463
|
end
|
374
464
|
|
375
465
|
##
|
376
466
|
#
|
377
467
|
# Checks if the page or current node has a radio button or
|
378
|
-
# 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
|
379
469
|
# unchecked.
|
380
470
|
#
|
381
471
|
# @param [String] locator The label, name or id of an unchecked field
|
382
472
|
# @return [Boolean] Whether it exists
|
383
473
|
#
|
384
474
|
def has_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
385
|
-
has_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
|
475
|
+
has_selector?(:field, locator, **options.merge(unchecked: true), &optional_filter_block)
|
386
476
|
end
|
387
477
|
|
388
478
|
##
|
389
479
|
#
|
390
480
|
# Checks if the page or current node has no radio button or
|
391
|
-
# 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
|
392
482
|
# unchecked.
|
393
483
|
#
|
394
484
|
# @param [String] locator The label, name or id of an unchecked field
|
395
485
|
# @return [Boolean] Whether it doesn't exist
|
396
486
|
#
|
397
487
|
def has_no_unchecked_field?(locator = nil, **options, &optional_filter_block)
|
398
|
-
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)
|
399
489
|
end
|
400
490
|
|
401
491
|
##
|
@@ -428,19 +518,19 @@ module Capybara
|
|
428
518
|
# @return [Boolean] Whether it exists
|
429
519
|
#
|
430
520
|
def has_select?(locator = nil, **options, &optional_filter_block)
|
431
|
-
has_selector?(:select, locator, options, &optional_filter_block)
|
521
|
+
has_selector?(:select, locator, **options, &optional_filter_block)
|
432
522
|
end
|
433
523
|
|
434
524
|
##
|
435
525
|
#
|
436
526
|
# Checks if the page or current node has no select field with the
|
437
|
-
# given label, name or id. See {
|
527
|
+
# given label, name or id. See {#has_select?}.
|
438
528
|
#
|
439
|
-
# @param (see
|
529
|
+
# @param (see #has_select?)
|
440
530
|
# @return [Boolean] Whether it doesn't exist
|
441
531
|
#
|
442
532
|
def has_no_select?(locator = nil, **options, &optional_filter_block)
|
443
|
-
has_no_selector?(:select, locator, options, &optional_filter_block)
|
533
|
+
has_no_selector?(:select, locator, **options, &optional_filter_block)
|
444
534
|
end
|
445
535
|
|
446
536
|
##
|
@@ -450,35 +540,43 @@ module Capybara
|
|
450
540
|
#
|
451
541
|
# page.has_table?('People')
|
452
542
|
#
|
453
|
-
# @param [String] locator
|
454
|
-
# @
|
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
|
455
553
|
#
|
456
554
|
def has_table?(locator = nil, **options, &optional_filter_block)
|
457
|
-
has_selector?(:table, locator, options, &optional_filter_block)
|
555
|
+
has_selector?(:table, locator, **options, &optional_filter_block)
|
458
556
|
end
|
459
557
|
|
460
558
|
##
|
461
559
|
#
|
462
560
|
# Checks if the page or current node has no table with the given id
|
463
|
-
# or caption. See {
|
561
|
+
# or caption. See {#has_table?}.
|
464
562
|
#
|
465
|
-
# @param (see
|
563
|
+
# @param (see #has_table?)
|
466
564
|
# @return [Boolean] Whether it doesn't exist
|
467
565
|
#
|
468
566
|
def has_no_table?(locator = nil, **options, &optional_filter_block)
|
469
|
-
has_no_selector?(:table, locator, options, &optional_filter_block)
|
567
|
+
has_no_selector?(:table, locator, **options, &optional_filter_block)
|
470
568
|
end
|
471
569
|
|
472
570
|
##
|
473
571
|
#
|
474
|
-
# Asserts that the
|
572
|
+
# Asserts that the current node matches a given selector.
|
475
573
|
#
|
476
574
|
# node.assert_matches_selector('p#foo')
|
477
575
|
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
|
478
576
|
# node.assert_matches_selector(:foo)
|
479
577
|
#
|
480
578
|
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
481
|
-
# such as
|
579
|
+
# such as `:text` and `:visible`.
|
482
580
|
#
|
483
581
|
# node.assert_matches_selector('li', text: 'Horse', visible: true)
|
484
582
|
#
|
@@ -487,86 +585,89 @@ module Capybara
|
|
487
585
|
#
|
488
586
|
def assert_matches_selector(*args, &optional_filter_block)
|
489
587
|
_verify_match_result(args, optional_filter_block) do |result|
|
490
|
-
raise Capybara::ExpectationNotMet,
|
588
|
+
raise Capybara::ExpectationNotMet, 'Item does not match the provided selector' unless result.include? self
|
491
589
|
end
|
492
590
|
end
|
493
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
|
+
#
|
494
600
|
def assert_not_matches_selector(*args, &optional_filter_block)
|
495
601
|
_verify_match_result(args, optional_filter_block) do |result|
|
496
602
|
raise Capybara::ExpectationNotMet, 'Item matched the provided selector' if result.include? self
|
497
603
|
end
|
498
604
|
end
|
499
|
-
alias_method :refute_matches_selector, :assert_not_matches_selector
|
500
605
|
|
501
606
|
##
|
502
607
|
#
|
503
|
-
# Checks if the current node matches given selector
|
608
|
+
# Checks if the current node matches given selector.
|
504
609
|
#
|
505
|
-
# @param (see
|
610
|
+
# @param (see #has_selector?)
|
506
611
|
# @return [Boolean]
|
507
612
|
#
|
508
|
-
def matches_selector?(*args, &optional_filter_block)
|
509
|
-
assert_matches_selector(*args, &optional_filter_block)
|
510
|
-
rescue Capybara::ExpectationNotMet
|
511
|
-
return false
|
613
|
+
def matches_selector?(*args, **options, &optional_filter_block)
|
614
|
+
make_predicate(options) { assert_matches_selector(*args, options, &optional_filter_block) }
|
512
615
|
end
|
513
616
|
|
514
617
|
##
|
515
618
|
#
|
516
|
-
# Checks if the current node matches given XPath expression
|
619
|
+
# Checks if the current node matches given XPath expression.
|
517
620
|
#
|
518
621
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
519
622
|
# @return [Boolean]
|
520
623
|
#
|
521
624
|
def matches_xpath?(xpath, **options, &optional_filter_block)
|
522
|
-
matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
625
|
+
matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
523
626
|
end
|
524
627
|
|
525
628
|
##
|
526
629
|
#
|
527
|
-
# Checks if the current node matches given CSS selector
|
630
|
+
# Checks if the current node matches given CSS selector.
|
528
631
|
#
|
529
632
|
# @param [String] css The CSS selector to match against the current code
|
530
633
|
# @return [Boolean]
|
531
634
|
#
|
532
635
|
def matches_css?(css, **options, &optional_filter_block)
|
533
|
-
matches_selector?(:css, css, options, &optional_filter_block)
|
636
|
+
matches_selector?(:css, css, **options, &optional_filter_block)
|
534
637
|
end
|
535
638
|
|
536
639
|
##
|
537
640
|
#
|
538
|
-
# Checks if the current node does not match given selector
|
539
|
-
# Usage is identical to
|
641
|
+
# Checks if the current node does not match given selector.
|
642
|
+
# Usage is identical to {#has_selector?}.
|
540
643
|
#
|
541
|
-
# @param (see
|
644
|
+
# @param (see #has_selector?)
|
542
645
|
# @return [Boolean]
|
543
646
|
#
|
544
|
-
def not_matches_selector?(*args, &optional_filter_block)
|
545
|
-
assert_not_matches_selector(*args, &optional_filter_block)
|
546
|
-
rescue Capybara::ExpectationNotMet
|
547
|
-
return false
|
647
|
+
def not_matches_selector?(*args, **options, &optional_filter_block)
|
648
|
+
make_predicate(options) { assert_not_matches_selector(*args, options, &optional_filter_block) }
|
548
649
|
end
|
549
650
|
|
550
651
|
##
|
551
652
|
#
|
552
|
-
# Checks if the current node does not match given XPath expression
|
653
|
+
# Checks if the current node does not match given XPath expression.
|
553
654
|
#
|
554
655
|
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
|
555
656
|
# @return [Boolean]
|
556
657
|
#
|
557
658
|
def not_matches_xpath?(xpath, **options, &optional_filter_block)
|
558
|
-
not_matches_selector?(:xpath, xpath, options, &optional_filter_block)
|
659
|
+
not_matches_selector?(:xpath, xpath, **options, &optional_filter_block)
|
559
660
|
end
|
560
661
|
|
561
662
|
##
|
562
663
|
#
|
563
|
-
# Checks if the current node does not match given CSS selector
|
664
|
+
# Checks if the current node does not match given CSS selector.
|
564
665
|
#
|
565
666
|
# @param [String] css The CSS selector to match against the current code
|
566
667
|
# @return [Boolean]
|
567
668
|
#
|
568
669
|
def not_matches_css?(css, **options, &optional_filter_block)
|
569
|
-
not_matches_selector?(:css, css, options, &optional_filter_block)
|
670
|
+
not_matches_selector?(:css, css, **options, &optional_filter_block)
|
570
671
|
end
|
571
672
|
|
572
673
|
##
|
@@ -574,29 +675,31 @@ module Capybara
|
|
574
675
|
# ignoring any HTML tags.
|
575
676
|
#
|
576
677
|
# @!macro text_query_params
|
577
|
-
# @overload $0(type, text, options
|
578
|
-
# @param [:all, :visible] type Whether to check for only visible or all text. If this parameter is missing or nil then we use the value of
|
678
|
+
# @overload $0(type, text, **options)
|
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`.
|
579
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.
|
580
681
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
581
682
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
582
683
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
583
684
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
584
|
-
# @option options [Numeric] :wait
|
585
|
-
# @option options [Boolean] :exact
|
586
|
-
#
|
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
|
688
|
+
# @overload $0(text, **options)
|
587
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.
|
588
690
|
# @option options [Integer] :count (nil) Number of times the text is expected to occur
|
589
691
|
# @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
|
590
692
|
# @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
|
591
693
|
# @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
|
592
|
-
# @option options [Numeric] :wait
|
593
|
-
# @option options [Boolean] :exact
|
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
|
594
697
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
595
698
|
# @return [true]
|
596
699
|
#
|
597
|
-
def assert_text(*args)
|
598
|
-
_verify_text(args) do |count, query|
|
599
|
-
unless query.matches_count?(count) && (
|
700
|
+
def assert_text(type_or_text, *args, **opts)
|
701
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
702
|
+
unless query.matches_count?(count) && (count.positive? || query.expects_none?)
|
600
703
|
raise Capybara::ExpectationNotMet, query.failure_message
|
601
704
|
end
|
602
705
|
end
|
@@ -610,9 +713,9 @@ module Capybara
|
|
610
713
|
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
611
714
|
# @return [true]
|
612
715
|
#
|
613
|
-
def assert_no_text(*args)
|
614
|
-
_verify_text(args) do |count, query|
|
615
|
-
if query.matches_count?(count) && (
|
716
|
+
def assert_no_text(type_or_text, *args, **opts)
|
717
|
+
_verify_text(type_or_text, *args, **opts) do |count, query|
|
718
|
+
if query.matches_count?(count) && (count.positive? || query.expects_none?)
|
616
719
|
raise Capybara::ExpectationNotMet, query.negative_failure_message
|
617
720
|
end
|
618
721
|
end
|
@@ -622,10 +725,6 @@ module Capybara
|
|
622
725
|
# Checks if the page or current node has the given text content,
|
623
726
|
# ignoring any HTML tags.
|
624
727
|
#
|
625
|
-
# Whitespaces are normalized in both node's text and passed text parameter.
|
626
|
-
# Note that whitespace isn't normalized in passed regexp as normalizing whitespace
|
627
|
-
# in regexp isn't easy and doesn't seem to be worth it.
|
628
|
-
#
|
629
728
|
# By default it will check if the text occurs at least once,
|
630
729
|
# but a different number can be specified.
|
631
730
|
#
|
@@ -636,10 +735,8 @@ module Capybara
|
|
636
735
|
# @macro text_query_params
|
637
736
|
# @return [Boolean] Whether it exists
|
638
737
|
#
|
639
|
-
def has_text?(*args)
|
640
|
-
assert_text(*args)
|
641
|
-
rescue Capybara::ExpectationNotMet
|
642
|
-
false
|
738
|
+
def has_text?(*args, **options)
|
739
|
+
make_predicate(options) { assert_text(*args, **options) }
|
643
740
|
end
|
644
741
|
alias_method :has_content?, :has_text?
|
645
742
|
|
@@ -650,52 +747,161 @@ module Capybara
|
|
650
747
|
# @macro text_query_params
|
651
748
|
# @return [Boolean] Whether it doesn't exist
|
652
749
|
#
|
653
|
-
def has_no_text?(*args)
|
654
|
-
assert_no_text(*args)
|
655
|
-
rescue Capybara::ExpectationNotMet
|
656
|
-
false
|
750
|
+
def has_no_text?(*args, **options)
|
751
|
+
make_predicate(options) { assert_no_text(*args, **options) }
|
657
752
|
end
|
658
753
|
alias_method :has_no_content?, :has_no_text?
|
659
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
|
+
|
660
841
|
def ==(other)
|
661
842
|
eql?(other) || (other.respond_to?(:base) && base == other.base)
|
662
843
|
end
|
663
844
|
|
664
845
|
private
|
665
846
|
|
666
|
-
def
|
667
|
-
|
668
|
-
|
847
|
+
def extract_selector(args)
|
848
|
+
args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
849
|
+
end
|
850
|
+
|
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)
|
669
868
|
synchronize(query.wait) do
|
670
|
-
|
671
|
-
yield result, query
|
869
|
+
yield query.resolve_for(self), query
|
672
870
|
end
|
673
871
|
true
|
674
872
|
end
|
675
873
|
|
676
874
|
def _verify_match_result(query_args, optional_filter_block)
|
677
|
-
query_args = _set_query_session_options(*query_args)
|
678
|
-
query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
|
875
|
+
query_args, query_opts = _set_query_session_options(*query_args)
|
876
|
+
query = Capybara::Queries::MatchQuery.new(*query_args, **query_opts, &optional_filter_block)
|
679
877
|
synchronize(query.wait) do
|
680
|
-
|
681
|
-
yield result
|
878
|
+
yield query.resolve_for(parent || session&.document || query_scope)
|
682
879
|
end
|
683
880
|
true
|
684
881
|
end
|
685
882
|
|
686
|
-
def _verify_text(
|
687
|
-
|
688
|
-
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)
|
689
886
|
synchronize(query.wait) do
|
690
|
-
|
691
|
-
yield(count, query)
|
887
|
+
yield query.resolve_for(self), query
|
692
888
|
end
|
693
889
|
true
|
694
890
|
end
|
695
891
|
|
696
|
-
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)
|
697
896
|
query_options[:session_options] = session_options
|
698
|
-
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
|
699
905
|
end
|
700
906
|
end
|
701
907
|
end
|