capybara 3.13.2 → 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 +587 -16
- data/README.md +240 -90
- data/lib/capybara/config.rb +24 -11
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +8 -0
- data/lib/capybara/driver/node.rb +20 -4
- data/lib/capybara/dsl.rb +5 -3
- data/lib/capybara/helpers.rb +25 -4
- data/lib/capybara/minitest/spec.rb +174 -90
- data/lib/capybara/minitest.rb +256 -142
- data/lib/capybara/node/actions.rb +123 -77
- data/lib/capybara/node/base.rb +20 -12
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +223 -117
- data/lib/capybara/node/finders.rb +81 -71
- data/lib/capybara/node/matchers.rb +271 -134
- data/lib/capybara/node/simple.rb +18 -5
- 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 +3 -2
- data/lib/capybara/queries/current_path_query.rb +15 -5
- data/lib/capybara/queries/selector_query.rb +364 -54
- data/lib/capybara/queries/sibling_query.rb +8 -6
- data/lib/capybara/queries/style_query.rb +2 -2
- data/lib/capybara/queries/text_query.rb +13 -1
- data/lib/capybara/queries/title_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +76 -11
- data/lib/capybara/rack_test/driver.rb +10 -5
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +31 -9
- data/lib/capybara/rack_test/node.rb +74 -23
- 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 +44 -20
- data/lib/capybara/rspec/matcher_proxies.rb +13 -11
- data/lib/capybara/rspec/matchers/base.rb +31 -16
- data/lib/capybara/rspec/matchers/compound.rb +1 -1
- 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 +2 -2
- data/lib/capybara/rspec/matchers/have_selector.rb +21 -21
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +4 -4
- data/lib/capybara/rspec/matchers/have_title.rb +2 -2
- data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
- data/lib/capybara/rspec/matchers/match_style.rb +7 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +111 -68
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/selector/builders/css_builder.rb +11 -7
- data/lib/capybara/selector/builders/xpath_builder.rb +5 -3
- data/lib/capybara/selector/css.rb +11 -9
- 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_set.rb +19 -18
- data/lib/capybara/selector/filters/base.rb +11 -2
- data/lib/capybara/selector/filters/locator_filter.rb +13 -3
- data/lib/capybara/selector/regexp_disassembler.rb +11 -7
- data/lib/capybara/selector/selector.rb +50 -440
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +473 -482
- 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 +174 -62
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +74 -18
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +37 -3
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +14 -1
- 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 +68 -45
- data/lib/capybara/selenium/extensions/html5_drag.rb +192 -22
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +8 -10
- data/lib/capybara/selenium/node.rb +268 -72
- data/lib/capybara/selenium/nodes/chrome_node.rb +105 -9
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +51 -61
- 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 +1 -1
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +43 -21
- data/lib/capybara/server/checker.rb +6 -2
- data/lib/capybara/server/middleware.rb +25 -13
- data/lib/capybara/server.rb +20 -4
- data/lib/capybara/session/config.rb +15 -11
- data/lib/capybara/session/matchers.rb +11 -11
- data/lib/capybara/session.rb +162 -131
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +105 -6
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +89 -15
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
- data/lib/capybara/spec/session/assert_text_spec.rb +26 -22
- data/lib/capybara/spec/session/attach_file_spec.rb +64 -31
- data/lib/capybara/spec/session/check_spec.rb +26 -4
- data/lib/capybara/spec/session/choose_spec.rb +14 -2
- data/lib/capybara/spec/session/click_button_spec.rb +109 -61
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_spec.rb +23 -1
- data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
- data/lib/capybara/spec/session/current_url_spec.rb +11 -1
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
- data/lib/capybara/spec/session/evaluate_script_spec.rb +12 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +46 -5
- data/lib/capybara/spec/session/find_link_spec.rb +10 -0
- data/lib/capybara/spec/session/find_spec.rb +80 -7
- data/lib/capybara/spec/session/first_spec.rb +2 -2
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
- data/lib/capybara/spec/session/has_button_spec.rb +81 -0
- data/lib/capybara/spec/session/has_css_spec.rb +45 -8
- data/lib/capybara/spec/session/has_current_path_spec.rb +22 -7
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +59 -1
- data/lib/capybara/spec/session/has_link_spec.rb +40 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
- data/lib/capybara/spec/session/has_select_spec.rb +42 -8
- data/lib/capybara/spec/session/has_selector_spec.rb +19 -4
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +177 -0
- data/lib/capybara/spec/session/has_text_spec.rb +31 -3
- data/lib/capybara/spec/session/html_spec.rb +1 -1
- data/lib/capybara/spec/session/matches_style_spec.rb +6 -4
- data/lib/capybara/spec/session/node_spec.rb +697 -23
- data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
- data/lib/capybara/spec/session/refresh_spec.rb +2 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +21 -7
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +4 -4
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
- data/lib/capybara/spec/session/scroll_spec.rb +9 -7
- data/lib/capybara/spec/session/select_spec.rb +5 -10
- data/lib/capybara/spec/session/selectors_spec.rb +24 -3
- data/lib/capybara/spec/session/uncheck_spec.rb +3 -3
- data/lib/capybara/spec/session/unselect_spec.rb +1 -1
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +54 -57
- data/lib/capybara/spec/session/window/windows_spec.rb +2 -2
- data/lib/capybara/spec/session/within_spec.rb +36 -0
- data/lib/capybara/spec/spec_helper.rb +30 -19
- data/lib/capybara/spec/test_app.rb +122 -34
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +86 -8
- data/lib/capybara/spec/views/frame_child.erb +3 -2
- 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 +10 -10
- 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 +2 -1
- 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 +34 -6
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +7 -4
- 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 +14 -18
- data/lib/capybara.rb +91 -126
- data/spec/basic_node_spec.rb +30 -16
- data/spec/capybara_spec.rb +40 -28
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +3 -1
- data/spec/css_splitter_spec.rb +1 -1
- data/spec/dsl_spec.rb +33 -22
- data/spec/filter_set_spec.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_failure.rb +3 -3
- data/spec/fixtures/selenium_driver_rspec_success.rb +3 -3
- data/spec/minitest_spec.rb +24 -2
- data/spec/minitest_spec_spec.rb +60 -45
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +131 -98
- data/spec/regexp_dissassembler_spec.rb +53 -39
- data/spec/result_spec.rb +68 -66
- data/spec/rspec/features_spec.rb +9 -4
- data/spec/rspec/scenarios_spec.rb +6 -2
- data/spec/rspec/shared_spec_matchers.rb +137 -98
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +23 -21
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +77 -21
- data/spec/selenium_spec_chrome.rb +141 -39
- data/spec/selenium_spec_chrome_remote.rb +32 -17
- data/spec/selenium_spec_edge.rb +36 -8
- data/spec/selenium_spec_firefox.rb +110 -68
- data/spec/selenium_spec_firefox_remote.rb +22 -15
- data/spec/selenium_spec_ie.rb +29 -22
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +153 -81
- data/spec/session_spec.rb +11 -4
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +179 -74
- data/spec/spec_helper.rb +80 -5
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +3 -1
- metadata +218 -30
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
@@ -27,9 +27,11 @@ module Capybara
|
|
27
27
|
@query_scope = query_scope
|
28
28
|
@query = query
|
29
29
|
@allow_reload = false
|
30
|
+
@query_idx = nil
|
30
31
|
end
|
31
32
|
|
32
|
-
def allow_reload!
|
33
|
+
def allow_reload!(idx = nil)
|
34
|
+
@query_idx = idx
|
33
35
|
@allow_reload = true
|
34
36
|
end
|
35
37
|
|
@@ -43,7 +45,7 @@ module Capybara
|
|
43
45
|
|
44
46
|
##
|
45
47
|
#
|
46
|
-
# Retrieve the text of the element. If
|
48
|
+
# Retrieve the text of the element. If {Capybara.configure ignore_hidden_elements}
|
47
49
|
# is `true`, which it is by default, then this will return only text
|
48
50
|
# which is visible. The exact semantics of this may differ between
|
49
51
|
# drivers, but generally any text within elements with `display:none` is
|
@@ -61,7 +63,7 @@ module Capybara
|
|
61
63
|
|
62
64
|
##
|
63
65
|
#
|
64
|
-
# Retrieve the given attribute
|
66
|
+
# Retrieve the given attribute.
|
65
67
|
#
|
66
68
|
# element[:title] # => HTML title attribute
|
67
69
|
#
|
@@ -74,7 +76,7 @@ module Capybara
|
|
74
76
|
|
75
77
|
##
|
76
78
|
#
|
77
|
-
# Retrieve the given CSS styles
|
79
|
+
# Retrieve the given CSS styles.
|
78
80
|
#
|
79
81
|
# element.style('color', 'font-size') # => Computed values of CSS 'color' and 'font-size' styles
|
80
82
|
#
|
@@ -87,11 +89,11 @@ module Capybara
|
|
87
89
|
|
88
90
|
begin
|
89
91
|
synchronize { base.style(styles) }
|
90
|
-
rescue NotImplementedError =>
|
92
|
+
rescue NotImplementedError => e
|
91
93
|
begin
|
92
94
|
evaluate_script(STYLE_SCRIPT, *styles)
|
93
95
|
rescue Capybara::NotSupportedByDriverError
|
94
|
-
raise
|
96
|
+
raise e
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end
|
@@ -109,32 +111,41 @@ module Capybara
|
|
109
111
|
# Set the value of the form element to the given value.
|
110
112
|
#
|
111
113
|
# @param [String] value The new value
|
112
|
-
# @param [Hash
|
114
|
+
# @param [Hash] options Driver specific options for how to set the value. Take default values from {Capybara.configure default_set_options}.
|
113
115
|
#
|
114
116
|
# @return [Capybara::Node::Element] The element
|
115
117
|
def set(value, **options)
|
116
|
-
|
118
|
+
if ENV.fetch('CAPYBARA_THOROUGH', nil) && readonly?
|
119
|
+
raise Capybara::ReadOnlyElementError, "Attempt to set readonly element with value: #{value}"
|
120
|
+
end
|
117
121
|
|
118
122
|
options = session_options.default_set_options.to_h.merge(options)
|
119
|
-
synchronize { base.set(value, options) }
|
123
|
+
synchronize { base.set(value, **options) }
|
120
124
|
self
|
121
125
|
end
|
122
126
|
|
123
127
|
##
|
124
128
|
#
|
125
|
-
# Select this node if is an option element inside a select tag
|
129
|
+
# Select this node if it is an option element inside a select tag.
|
130
|
+
#
|
131
|
+
# @!macro action_waiting_behavior
|
132
|
+
# If the driver dynamic pages (JS) and the element is currently non-interactable, this method will
|
133
|
+
# continuously retry the action until either the element becomes interactable or the maximum
|
134
|
+
# wait time expires.
|
126
135
|
#
|
136
|
+
# @param [false, Numeric] wait
|
137
|
+
# Maximum time to wait for the action to succeed. Defaults to {Capybara.configure default_max_wait_time}.
|
127
138
|
# @return [Capybara::Node::Element] The element
|
128
139
|
def select_option(wait: nil)
|
129
|
-
warn "Attempt to select disabled option: #{value || text}" if disabled?
|
130
140
|
synchronize(wait) { base.select_option }
|
131
141
|
self
|
132
142
|
end
|
133
143
|
|
134
144
|
##
|
135
145
|
#
|
136
|
-
# Unselect this node if is an option element inside a multiple select tag
|
146
|
+
# Unselect this node if it is an option element inside a multiple select tag.
|
137
147
|
#
|
148
|
+
# @macro action_waiting_behavior
|
138
149
|
# @return [Capybara::Node::Element] The element
|
139
150
|
def unselect_option(wait: nil)
|
140
151
|
synchronize(wait) { base.unselect_option }
|
@@ -143,51 +154,55 @@ module Capybara
|
|
143
154
|
|
144
155
|
##
|
145
156
|
#
|
146
|
-
# Click the Element
|
157
|
+
# Click the Element.
|
147
158
|
#
|
159
|
+
# @macro action_waiting_behavior
|
148
160
|
# @!macro click_modifiers
|
149
|
-
# Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element
|
150
|
-
# @overload $0(*modifier_keys, **offset)
|
161
|
+
# Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element.
|
162
|
+
# @overload $0(*modifier_keys, wait: nil, **offset)
|
151
163
|
# @param *modifier_keys [:alt, :control, :meta, :shift] ([]) Keys to be held down when clicking
|
152
|
-
# @option
|
153
|
-
#
|
164
|
+
# @option options [Integer] x X coordinate to offset the click location. If {Capybara.configure w3c_click_offset} is `true` the
|
165
|
+
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
166
|
+
# @option options [Integer] y Y coordinate to offset the click location. If {Capybara.configure w3c_click_offset} is `true` the
|
167
|
+
# offset will be from the element center, otherwise it will be from the top left corner of the element
|
168
|
+
# @option options [Float] delay Delay between the mouse down and mouse up events in seconds (0)
|
154
169
|
# @return [Capybara::Node::Element] The element
|
155
|
-
def click(*keys,
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
self
|
170
|
+
def click(*keys, **options)
|
171
|
+
perform_click_action(keys, **options) do |k, opts|
|
172
|
+
base.click(k, **opts)
|
173
|
+
end
|
160
174
|
end
|
161
175
|
|
162
176
|
##
|
163
177
|
#
|
164
|
-
# Right Click the Element
|
178
|
+
# Right Click the Element.
|
165
179
|
#
|
180
|
+
# @macro action_waiting_behavior
|
166
181
|
# @macro click_modifiers
|
182
|
+
# @option options [Float] delay Delay between the mouse down and mouse up events in seconds (0)
|
167
183
|
# @return [Capybara::Node::Element] The element
|
168
|
-
def right_click(*keys,
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
self
|
184
|
+
def right_click(*keys, **options)
|
185
|
+
perform_click_action(keys, **options) do |k, opts|
|
186
|
+
base.right_click(k, **opts)
|
187
|
+
end
|
173
188
|
end
|
174
189
|
|
175
190
|
##
|
176
191
|
#
|
177
|
-
# Double Click the Element
|
192
|
+
# Double Click the Element.
|
178
193
|
#
|
194
|
+
# @macro action_waiting_behavior
|
179
195
|
# @macro click_modifiers
|
180
196
|
# @return [Capybara::Node::Element] The element
|
181
|
-
def double_click(*keys,
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
self
|
197
|
+
def double_click(*keys, **options)
|
198
|
+
perform_click_action(keys, **options) do |k, opts|
|
199
|
+
base.double_click(k, **opts)
|
200
|
+
end
|
186
201
|
end
|
187
202
|
|
188
203
|
##
|
189
204
|
#
|
190
|
-
# Send Keystrokes to the Element
|
205
|
+
# Send Keystrokes to the Element.
|
191
206
|
#
|
192
207
|
# @overload send_keys(keys, ...)
|
193
208
|
# @param keys [String, Symbol, Array<String,Symbol>]
|
@@ -195,65 +210,65 @@ module Capybara
|
|
195
210
|
# Examples:
|
196
211
|
#
|
197
212
|
# element.send_keys "foo" #=> value: 'foo'
|
198
|
-
# element.send_keys "tet", :left, "s"
|
213
|
+
# element.send_keys "tet", :left, "s" #=> value: 'test'
|
199
214
|
# element.send_keys [:control, 'a'], :space #=> value: ' ' - assuming ctrl-a selects all contents
|
200
215
|
#
|
201
|
-
# Symbols supported for keys
|
202
|
-
# :cancel
|
203
|
-
# :help
|
204
|
-
# :backspace
|
205
|
-
# :tab
|
206
|
-
# :clear
|
207
|
-
# :return
|
208
|
-
# :enter
|
209
|
-
# :shift
|
210
|
-
# :control
|
211
|
-
# :alt
|
212
|
-
# :pause
|
213
|
-
# :escape
|
214
|
-
# :space
|
215
|
-
# :page_up
|
216
|
-
# :page_down
|
217
|
-
# :end
|
218
|
-
# :home
|
219
|
-
# :left
|
220
|
-
# :up
|
221
|
-
# :right
|
222
|
-
# :down
|
223
|
-
# :insert
|
224
|
-
# :delete
|
225
|
-
# :semicolon
|
226
|
-
# :equals
|
227
|
-
# :numpad0
|
228
|
-
# :numpad1
|
229
|
-
# :numpad2
|
230
|
-
# :numpad3
|
231
|
-
# :numpad4
|
232
|
-
# :numpad5
|
233
|
-
# :numpad6
|
234
|
-
# :numpad7
|
235
|
-
# :numpad8
|
236
|
-
# :numpad9
|
237
|
-
# :multiply - numeric keypad *
|
238
|
-
# :add - numeric keypad +
|
239
|
-
# :separator - numeric keypad 'separator' key ??
|
240
|
-
# :subtract - numeric keypad -
|
241
|
-
# :decimal - numeric keypad .
|
242
|
-
# :divide - numeric keypad /
|
243
|
-
# :f1
|
244
|
-
# :f2
|
245
|
-
# :f3
|
246
|
-
# :f4
|
247
|
-
# :f5
|
248
|
-
# :f6
|
249
|
-
# :f7
|
250
|
-
# :f8
|
251
|
-
# :f9
|
252
|
-
# :f10
|
253
|
-
# :f11
|
254
|
-
# :f12
|
255
|
-
# :meta
|
256
|
-
# :command - alias of :meta
|
216
|
+
# Symbols supported for keys:
|
217
|
+
# * :cancel
|
218
|
+
# * :help
|
219
|
+
# * :backspace
|
220
|
+
# * :tab
|
221
|
+
# * :clear
|
222
|
+
# * :return
|
223
|
+
# * :enter
|
224
|
+
# * :shift
|
225
|
+
# * :control
|
226
|
+
# * :alt
|
227
|
+
# * :pause
|
228
|
+
# * :escape
|
229
|
+
# * :space
|
230
|
+
# * :page_up
|
231
|
+
# * :page_down
|
232
|
+
# * :end
|
233
|
+
# * :home
|
234
|
+
# * :left
|
235
|
+
# * :up
|
236
|
+
# * :right
|
237
|
+
# * :down
|
238
|
+
# * :insert
|
239
|
+
# * :delete
|
240
|
+
# * :semicolon
|
241
|
+
# * :equals
|
242
|
+
# * :numpad0
|
243
|
+
# * :numpad1
|
244
|
+
# * :numpad2
|
245
|
+
# * :numpad3
|
246
|
+
# * :numpad4
|
247
|
+
# * :numpad5
|
248
|
+
# * :numpad6
|
249
|
+
# * :numpad7
|
250
|
+
# * :numpad8
|
251
|
+
# * :numpad9
|
252
|
+
# * :multiply - numeric keypad *
|
253
|
+
# * :add - numeric keypad +
|
254
|
+
# * :separator - numeric keypad 'separator' key ??
|
255
|
+
# * :subtract - numeric keypad -
|
256
|
+
# * :decimal - numeric keypad .
|
257
|
+
# * :divide - numeric keypad /
|
258
|
+
# * :f1
|
259
|
+
# * :f2
|
260
|
+
# * :f3
|
261
|
+
# * :f4
|
262
|
+
# * :f5
|
263
|
+
# * :f6
|
264
|
+
# * :f7
|
265
|
+
# * :f8
|
266
|
+
# * :f9
|
267
|
+
# * :f10
|
268
|
+
# * :f11
|
269
|
+
# * :f12
|
270
|
+
# * :meta
|
271
|
+
# * :command - alias of :meta
|
257
272
|
#
|
258
273
|
# @return [Capybara::Node::Element] The element
|
259
274
|
def send_keys(*args)
|
@@ -263,7 +278,7 @@ module Capybara
|
|
263
278
|
|
264
279
|
##
|
265
280
|
#
|
266
|
-
# Hover on the Element
|
281
|
+
# Hover on the Element.
|
267
282
|
#
|
268
283
|
# @return [Capybara::Node::Element] The element
|
269
284
|
def hover
|
@@ -276,7 +291,8 @@ module Capybara
|
|
276
291
|
# @return [String] The tag name of the element
|
277
292
|
#
|
278
293
|
def tag_name
|
279
|
-
|
294
|
+
# Element type is immutable so cache it
|
295
|
+
@tag_name ||= initial_cache[:tag_name] || synchronize { base.tag_name }
|
280
296
|
end
|
281
297
|
|
282
298
|
##
|
@@ -290,6 +306,17 @@ module Capybara
|
|
290
306
|
synchronize { base.visible? }
|
291
307
|
end
|
292
308
|
|
309
|
+
##
|
310
|
+
#
|
311
|
+
# Whether or not the element is currently in the viewport and it (or descendants)
|
312
|
+
# would be considered clickable at the elements center point.
|
313
|
+
#
|
314
|
+
# @return [Boolean] Whether the elements center is obscured.
|
315
|
+
#
|
316
|
+
def obscured?
|
317
|
+
synchronize { base.obscured? }
|
318
|
+
end
|
319
|
+
|
293
320
|
##
|
294
321
|
#
|
295
322
|
# Whether or not the element is checked.
|
@@ -342,7 +369,7 @@ module Capybara
|
|
342
369
|
|
343
370
|
##
|
344
371
|
#
|
345
|
-
# An XPath expression describing where on the page the element can be found
|
372
|
+
# An XPath expression describing where on the page the element can be found.
|
346
373
|
#
|
347
374
|
# @return [String] An XPath expression
|
348
375
|
#
|
@@ -350,6 +377,10 @@ module Capybara
|
|
350
377
|
synchronize { base.path }
|
351
378
|
end
|
352
379
|
|
380
|
+
def rect
|
381
|
+
synchronize { base.rect }
|
382
|
+
end
|
383
|
+
|
353
384
|
##
|
354
385
|
#
|
355
386
|
# Trigger any event on the current element, for example mouseover or focus
|
@@ -374,26 +405,54 @@ module Capybara
|
|
374
405
|
# source.drag_to(target)
|
375
406
|
#
|
376
407
|
# @param [Capybara::Node::Element] node The element to drag to
|
408
|
+
# @param [Hash] options Driver specific options for dragging. May not be supported by all drivers.
|
409
|
+
# @option options [Numeric] :delay (0.05) When using Chrome/Firefox with Selenium and HTML5 dragging this is the number
|
410
|
+
# of seconds between each stage of the drag.
|
411
|
+
# @option options [Boolean] :html5 When using Chrome/Firefox with Selenium enables to force the use of HTML5
|
412
|
+
# (true) or legacy (false) dragging. If not specified the driver will attempt to
|
413
|
+
# detect the correct method to use.
|
414
|
+
# @option options [Array<Symbol>,Symbol] :drop_modifiers Modifier keys which should be held while the dragged element is dropped.
|
415
|
+
#
|
416
|
+
#
|
417
|
+
# @return [Capybara::Node::Element] The dragged element
|
418
|
+
def drag_to(node, **options)
|
419
|
+
synchronize { base.drag_to(node.base, **options) }
|
420
|
+
self
|
421
|
+
end
|
422
|
+
|
423
|
+
##
|
424
|
+
#
|
425
|
+
# Drop items on the current element.
|
426
|
+
#
|
427
|
+
# target = page.find('#foo')
|
428
|
+
# target.drop('/some/path/file.csv')
|
429
|
+
#
|
430
|
+
# @overload drop(path, ...)
|
431
|
+
# @param [String, #to_path] path Location of the file to drop on the element
|
432
|
+
#
|
433
|
+
# @overload drop(strings, ...)
|
434
|
+
# @param [Hash] strings A hash of type to data to be dropped - `{ "text/url" => "https://www.google.com" }`
|
377
435
|
#
|
378
436
|
# @return [Capybara::Node::Element] The element
|
379
|
-
def
|
380
|
-
|
437
|
+
def drop(*args)
|
438
|
+
options = args.map { |arg| arg.respond_to?(:to_path) ? arg.to_path : arg }
|
439
|
+
synchronize { base.drop(*options) }
|
381
440
|
self
|
382
441
|
end
|
383
442
|
|
384
443
|
##
|
385
444
|
#
|
386
|
-
# Scroll the page or element
|
445
|
+
# Scroll the page or element.
|
387
446
|
#
|
388
|
-
# Scroll the page or element to its top, bottom or middle
|
389
447
|
# @overload scroll_to(position, offset: [0,0])
|
448
|
+
# Scroll the page or element to its top, bottom or middle.
|
390
449
|
# @param [:top, :bottom, :center, :current] position
|
391
|
-
# @param
|
450
|
+
# @param [[Integer, Integer]] offset
|
392
451
|
#
|
393
|
-
# Scroll the page or current element until the given element is aligned at the top, bottom, or center of it
|
394
452
|
# @overload scroll_to(element, align: :top)
|
453
|
+
# Scroll the page or current element until the given element is aligned at the top, bottom, or center of it.
|
395
454
|
# @param [Capybara::Node::Element] element The element to be scrolled into view
|
396
|
-
# @param [:top, :bottom, :center]
|
455
|
+
# @param [:top, :bottom, :center] align Where to align the element being scrolled into view with relation to the current page/element if possible
|
397
456
|
#
|
398
457
|
# @overload scroll_to(x,y)
|
399
458
|
# @param [Integer] x Horizontal scroll offset
|
@@ -413,14 +472,25 @@ module Capybara
|
|
413
472
|
self
|
414
473
|
end
|
415
474
|
|
475
|
+
##
|
476
|
+
#
|
477
|
+
# Return the shadow_root for the current element
|
478
|
+
#
|
479
|
+
# @return [Capybara::Node::Element] The shadow root
|
480
|
+
|
481
|
+
def shadow_root
|
482
|
+
root = synchronize { base.shadow_root }
|
483
|
+
root && Capybara::Node::Element.new(session, root, nil, nil)
|
484
|
+
end
|
485
|
+
|
416
486
|
##
|
417
487
|
#
|
418
488
|
# Execute the given JS in the context of the element not returning a result. This is useful for scripts that return
|
419
|
-
# complex objects, such as jQuery statements.
|
420
|
-
#
|
489
|
+
# complex objects, such as jQuery statements. {#execute_script} should be used over
|
490
|
+
# {#evaluate_script} whenever a result is not expected or needed. `this` in the script will refer to the element this is called on.
|
421
491
|
#
|
422
492
|
# @param [String] script A string of JavaScript to execute
|
423
|
-
# @param args Optional arguments that will be passed to the script.
|
493
|
+
# @param args Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers
|
424
494
|
#
|
425
495
|
def execute_script(script, *args)
|
426
496
|
session.execute_script(<<~JS, self, *args)
|
@@ -433,7 +503,7 @@ module Capybara
|
|
433
503
|
##
|
434
504
|
#
|
435
505
|
# Evaluate the given JS in the context of the element and return the result. Be careful when using this with
|
436
|
-
# scripts that return complex objects, such as jQuery statements.
|
506
|
+
# scripts that return complex objects, such as jQuery statements. {#execute_script} might
|
437
507
|
# be a better alternative. `this` in the script will refer to the element this is called on.
|
438
508
|
#
|
439
509
|
# @param [String] script A string of JavaScript to evaluate
|
@@ -451,7 +521,7 @@ module Capybara
|
|
451
521
|
#
|
452
522
|
# Evaluate the given JavaScript in the context of the element and obtain the result from a
|
453
523
|
# callback function which will be passed as the last argument to the script. `this` in the
|
454
|
-
# script will refer to the element this is called on
|
524
|
+
# script will refer to the element this is called on.
|
455
525
|
#
|
456
526
|
# @param [String] script A string of JavaScript to evaluate
|
457
527
|
# @return [Object] The result of the evaluated JavaScript (may be driver specific)
|
@@ -464,25 +534,51 @@ module Capybara
|
|
464
534
|
JS
|
465
535
|
end
|
466
536
|
|
537
|
+
##
|
538
|
+
#
|
539
|
+
# Toggle the elements background color between white and black for a period of time.
|
540
|
+
#
|
541
|
+
# @return [Capybara::Node::Element] The element
|
542
|
+
def flash
|
543
|
+
execute_script(<<~JS, 100)
|
544
|
+
async function flash(el, delay){
|
545
|
+
var old_bg = el.style.backgroundColor;
|
546
|
+
var colors = ["black", "white"];
|
547
|
+
for(var i=0; i<20; i++){
|
548
|
+
el.style.backgroundColor = colors[i % colors.length];
|
549
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
550
|
+
}
|
551
|
+
el.style.backgroundColor = old_bg;
|
552
|
+
}
|
553
|
+
flash(this, arguments[0]);
|
554
|
+
JS
|
555
|
+
|
556
|
+
self
|
557
|
+
end
|
558
|
+
|
559
|
+
# @api private
|
467
560
|
def reload
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
561
|
+
return self unless @allow_reload
|
562
|
+
|
563
|
+
begin
|
564
|
+
reloaded = @query.resolve_for(query_scope ? query_scope.reload : session)[@query_idx.to_i]
|
565
|
+
@base = reloaded.base if reloaded
|
566
|
+
rescue StandardError => e
|
567
|
+
raise e unless catch_error?(e)
|
475
568
|
end
|
476
569
|
self
|
477
570
|
end
|
478
571
|
|
572
|
+
##
|
573
|
+
#
|
574
|
+
# A human-readable representation of the element.
|
575
|
+
#
|
576
|
+
# @return [String] A string representation
|
479
577
|
def inspect
|
480
578
|
%(#<Capybara::Node::Element tag="#{base.tag_name}" path="#{base.path}">)
|
481
579
|
rescue NotSupportedByDriverError
|
482
580
|
%(#<Capybara::Node::Element tag="#{base.tag_name}">)
|
483
|
-
rescue
|
484
|
-
raise unless session.driver.invalid_element_errors.any? { |et| err.is_a?(et) }
|
485
|
-
|
581
|
+
rescue *session.driver.invalid_element_errors
|
486
582
|
%(Obsolete #<Capybara::Node::Element>)
|
487
583
|
end
|
488
584
|
|
@@ -502,6 +598,16 @@ module Capybara
|
|
502
598
|
return result;
|
503
599
|
}).apply(this, arguments)
|
504
600
|
JS
|
601
|
+
|
602
|
+
private
|
603
|
+
|
604
|
+
def perform_click_action(keys, wait: nil, **options)
|
605
|
+
raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ options[:x] ^ options[:y]
|
606
|
+
|
607
|
+
options[:offset] ||= :center if session_options.w3c_click_offset
|
608
|
+
synchronize(wait) { yield keys, options }
|
609
|
+
self
|
610
|
+
end
|
505
611
|
end
|
506
612
|
end
|
507
613
|
end
|