capybara 2.18.0 → 3.0.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/History.md +55 -1
- data/README.md +18 -17
- data/lib/capybara/config.rb +11 -58
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +15 -16
- data/lib/capybara/driver/node.rb +5 -4
- data/lib/capybara/dsl.rb +1 -0
- data/lib/capybara/helpers.rb +19 -29
- data/lib/capybara/minitest/spec.rb +15 -14
- data/lib/capybara/minitest.rb +139 -138
- data/lib/capybara/node/actions.rb +60 -81
- data/lib/capybara/node/base.rb +11 -18
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +8 -8
- data/lib/capybara/node/element.rb +30 -40
- data/lib/capybara/node/finders.rb +62 -70
- data/lib/capybara/node/matchers.rb +50 -71
- data/lib/capybara/node/simple.rb +11 -17
- data/lib/capybara/queries/ancestor_query.rb +11 -7
- data/lib/capybara/queries/base_query.rb +22 -18
- data/lib/capybara/queries/current_path_query.rb +8 -24
- data/lib/capybara/queries/match_query.rb +3 -7
- data/lib/capybara/queries/selector_query.rb +92 -95
- data/lib/capybara/queries/sibling_query.rb +4 -4
- data/lib/capybara/queries/text_query.rb +35 -35
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +15 -18
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +6 -10
- data/lib/capybara/rack_test/form.rb +50 -40
- data/lib/capybara/rack_test/node.rb +93 -63
- data/lib/capybara/rails.rb +2 -6
- data/lib/capybara/result.rb +22 -22
- data/lib/capybara/rspec/compound.rb +5 -10
- data/lib/capybara/rspec/features.rb +17 -48
- data/lib/capybara/rspec/matcher_proxies.rb +31 -15
- data/lib/capybara/rspec/matchers.rb +70 -61
- data/lib/capybara/rspec.rb +5 -10
- data/lib/capybara/selector/css.rb +6 -11
- data/lib/capybara/selector/filter.rb +1 -17
- data/lib/capybara/selector/filter_set.rb +18 -15
- data/lib/capybara/selector/filters/base.rb +7 -6
- data/lib/capybara/selector/filters/expression_filter.rb +6 -23
- data/lib/capybara/selector/filters/node_filter.rb +2 -12
- data/lib/capybara/selector/selector.rb +28 -34
- data/lib/capybara/selector.rb +129 -117
- data/lib/capybara/selenium/driver.rb +131 -125
- data/lib/capybara/selenium/node.rb +197 -115
- data/lib/capybara/server.rb +3 -2
- data/lib/capybara/session/config.rb +47 -67
- data/lib/capybara/session/matchers.rb +8 -7
- data/lib/capybara/session.rb +138 -224
- data/lib/capybara/spec/public/test.js +25 -4
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
- data/lib/capybara/spec/session/accept_prompt_spec.rb +1 -0
- data/lib/capybara/spec/session/all_spec.rb +31 -18
- data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
- data/lib/capybara/spec/session/assert_current_path.rb +12 -11
- data/lib/capybara/spec/session/assert_selector.rb +1 -0
- data/lib/capybara/spec/session/assert_text.rb +23 -23
- data/lib/capybara/spec/session/assert_title.rb +13 -3
- data/lib/capybara/spec/session/attach_file_spec.rb +51 -30
- data/lib/capybara/spec/session/body_spec.rb +1 -0
- data/lib/capybara/spec/session/check_spec.rb +7 -6
- data/lib/capybara/spec/session/choose_spec.rb +5 -4
- data/lib/capybara/spec/session/click_button_spec.rb +24 -32
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
- data/lib/capybara/spec/session/click_link_spec.rb +8 -7
- data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
- data/lib/capybara/spec/session/current_url_spec.rb +17 -6
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
- data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +3 -2
- data/lib/capybara/spec/session/evaluate_script_spec.rb +4 -3
- data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
- data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
- data/lib/capybara/spec/session/find_button_spec.rb +4 -3
- data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
- data/lib/capybara/spec/session/find_field_spec.rb +9 -15
- data/lib/capybara/spec/session/find_link_spec.rb +6 -5
- data/lib/capybara/spec/session/find_spec.rb +37 -31
- data/lib/capybara/spec/session/first_spec.rb +60 -33
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
- data/lib/capybara/spec/session/go_back_spec.rb +1 -0
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +15 -15
- data/lib/capybara/spec/session/has_button_spec.rb +2 -1
- data/lib/capybara/spec/session/has_css_spec.rb +3 -2
- data/lib/capybara/spec/session/has_current_path_spec.rb +12 -28
- data/lib/capybara/spec/session/has_field_spec.rb +4 -3
- data/lib/capybara/spec/session/has_link_spec.rb +1 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +17 -17
- data/lib/capybara/spec/session/has_select_spec.rb +30 -29
- data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
- data/lib/capybara/spec/session/has_table_spec.rb +2 -1
- data/lib/capybara/spec/session/has_text_spec.rb +9 -13
- data/lib/capybara/spec/session/has_title_spec.rb +1 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
- data/lib/capybara/spec/session/headers.rb +2 -1
- data/lib/capybara/spec/session/html_spec.rb +1 -0
- data/lib/capybara/spec/session/node_spec.rb +91 -56
- data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
- data/lib/capybara/spec/session/refresh_spec.rb +6 -2
- data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
- data/lib/capybara/spec/session/response_code.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
- data/lib/capybara/spec/session/save_page_spec.rb +1 -17
- data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
- data/lib/capybara/spec/session/select_spec.rb +20 -20
- data/lib/capybara/spec/session/selectors_spec.rb +2 -2
- data/lib/capybara/spec/session/sibling_spec.rb +1 -1
- data/lib/capybara/spec/session/text_spec.rb +17 -3
- data/lib/capybara/spec/session/title_spec.rb +11 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
- data/lib/capybara/spec/session/unselect_spec.rb +6 -5
- data/lib/capybara/spec/session/visit_spec.rb +9 -3
- data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
- data/lib/capybara/spec/session/window/window_spec.rb +12 -12
- data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
- data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
- data/lib/capybara/spec/session/within_spec.rb +1 -0
- data/lib/capybara/spec/spec_helper.rb +34 -18
- data/lib/capybara/spec/test_app.rb +17 -9
- data/lib/capybara/spec/views/form.erb +7 -0
- data/lib/capybara/spec/views/with_html.erb +23 -1
- data/lib/capybara/spec/views/within_frames.erb +4 -1
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +6 -10
- data/lib/capybara.rb +28 -25
- data/spec/basic_node_spec.rb +1 -0
- data/spec/capybara_spec.rb +11 -50
- data/spec/dsl_spec.rb +5 -13
- data/spec/filter_set_spec.rb +5 -4
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
- data/spec/minitest_spec.rb +4 -3
- data/spec/minitest_spec_spec.rb +3 -2
- data/spec/per_session_config_spec.rb +9 -8
- data/spec/rack_test_spec.rb +21 -20
- data/spec/result_spec.rb +17 -16
- data/spec/rspec/features_spec.rb +17 -14
- data/spec/rspec/scenarios_spec.rb +5 -7
- data/spec/rspec/shared_spec_matchers.rb +96 -99
- data/spec/rspec/views_spec.rb +2 -1
- data/spec/rspec_matchers_spec.rb +18 -2
- data/spec/rspec_spec.rb +11 -15
- data/spec/selector_spec.rb +5 -6
- data/spec/selenium_spec_chrome.rb +9 -4
- data/spec/selenium_spec_edge.rb +27 -0
- data/spec/selenium_spec_ie.rb +31 -0
- data/spec/selenium_spec_marionette.rb +28 -12
- data/spec/server_spec.rb +33 -33
- data/spec/session_spec.rb +2 -1
- data/spec/shared_selenium_session.rb +36 -22
- data/spec/spec_helper.rb +3 -6
- metadata +68 -85
- data/lib/capybara/query.rb +0 -7
- data/spec/selenium_spec_firefox.rb +0 -68
data/lib/capybara/minitest.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'minitest'
|
3
4
|
require 'capybara/dsl'
|
4
5
|
|
@@ -41,17 +42,16 @@ module Capybara
|
|
41
42
|
# @!method assert_no_current_path
|
42
43
|
# see {Capybara::SessionMatchers#assert_no_current_path}
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
45
|
+
%w[assert_text assert_no_text assert_title assert_no_title assert_current_path assert_no_current_path].each do |assertion_name|
|
46
|
+
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
47
47
|
def #{assertion_name} *args
|
48
48
|
self.assertions +=1
|
49
|
-
subject,
|
49
|
+
subject, args = determine_subject(args)
|
50
50
|
subject.#{assertion_name}(*args)
|
51
51
|
rescue Capybara::ExpectationNotMet => e
|
52
52
|
raise ::Minitest::Assertion, e.message
|
53
53
|
end
|
54
|
-
|
54
|
+
ASSERTION
|
55
55
|
end
|
56
56
|
|
57
57
|
alias_method :refute_title, :assert_no_title
|
@@ -81,190 +81,191 @@ module Capybara
|
|
81
81
|
# @!method assert_xpath
|
82
82
|
# see {Capybara::Node::Matchers#assert_not_matches_selector}
|
83
83
|
|
84
|
-
%w
|
84
|
+
%w[assert_selector assert_no_selector
|
85
85
|
assert_all_of_selectors assert_none_of_selectors
|
86
|
-
assert_matches_selector assert_not_matches_selector
|
87
|
-
|
86
|
+
assert_matches_selector assert_not_matches_selector].each do |assertion_name|
|
87
|
+
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
88
88
|
def #{assertion_name} *args, &optional_filter_block
|
89
89
|
self.assertions +=1
|
90
|
-
subject,
|
90
|
+
subject, args = determine_subject(args)
|
91
91
|
subject.#{assertion_name}(*args, &optional_filter_block)
|
92
92
|
rescue Capybara::ExpectationNotMet => e
|
93
93
|
raise ::Minitest::Assertion, e.message
|
94
94
|
end
|
95
|
-
|
95
|
+
ASSERTION
|
96
96
|
end
|
97
97
|
|
98
98
|
alias_method :refute_selector, :assert_no_selector
|
99
99
|
alias_method :refute_matches_selector, :assert_not_matches_selector
|
100
100
|
|
101
|
-
%w
|
101
|
+
%w[xpath css link button field select table].each do |selector_type|
|
102
102
|
define_method "assert_#{selector_type}" do |*args, &optional_filter_block|
|
103
|
-
subject,
|
103
|
+
subject, args = determine_subject(args)
|
104
104
|
locator, options = extract_locator(args)
|
105
105
|
assert_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
106
106
|
end
|
107
107
|
|
108
108
|
define_method "assert_no_#{selector_type}" do |*args, &optional_filter_block|
|
109
|
-
subject,
|
109
|
+
subject, args = determine_subject(args)
|
110
110
|
locator, options = extract_locator(args)
|
111
111
|
assert_no_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
112
112
|
end
|
113
113
|
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
114
114
|
end
|
115
115
|
|
116
|
-
%w
|
116
|
+
%w[checked unchecked].each do |field_type|
|
117
117
|
define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
|
118
|
-
subject,
|
118
|
+
subject, args = determine_subject(args)
|
119
119
|
locator, options = extract_locator(args)
|
120
120
|
assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
121
121
|
end
|
122
122
|
|
123
123
|
define_method "assert_no_#{field_type}_field" do |*args, &optional_filter_block|
|
124
|
-
subject,
|
124
|
+
subject, args = determine_subject(args)
|
125
125
|
locator, options = extract_locator(args)
|
126
126
|
assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
127
127
|
end
|
128
128
|
alias_method "refute_#{field_type}_field", "assert_no_#{field_type}_field"
|
129
129
|
end
|
130
130
|
|
131
|
-
%w
|
131
|
+
%w[xpath css].each do |selector_type|
|
132
132
|
define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
|
133
|
-
subject,
|
133
|
+
subject, args = determine_subject(args)
|
134
134
|
assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
135
135
|
end
|
136
136
|
|
137
137
|
define_method "assert_not_matches_#{selector_type}" do |*args, &optional_filter_block|
|
138
|
-
subject,
|
138
|
+
subject, args = determine_subject(args)
|
139
139
|
assert_not_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
140
140
|
end
|
141
141
|
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
|
142
142
|
end
|
143
143
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
private
|
144
|
+
##
|
145
|
+
# Assertion that there is xpath
|
146
|
+
#
|
147
|
+
# @!method assert_xpath
|
148
|
+
# see Capybara::Node::Matchers#has_xpath?
|
149
|
+
|
150
|
+
##
|
151
|
+
# Assertion that there is no xpath
|
152
|
+
#
|
153
|
+
# @!method refute_xpath
|
154
|
+
# @!method assert_no_xpath
|
155
|
+
# see Capybara::Node::Matchers#has_no_xpath?
|
156
|
+
|
157
|
+
##
|
158
|
+
# Assertion that there is css
|
159
|
+
#
|
160
|
+
# @!method assert_css
|
161
|
+
# see Capybara::Node::Matchers#has_css?
|
162
|
+
|
163
|
+
##
|
164
|
+
# Assertion that there is no css
|
165
|
+
#
|
166
|
+
# @!method refute_css
|
167
|
+
# @!method assert_no_css
|
168
|
+
# see Capybara::Node::Matchers#has_no_css?
|
169
|
+
|
170
|
+
##
|
171
|
+
# Assertion that there is link
|
172
|
+
#
|
173
|
+
# @!method assert_link
|
174
|
+
# see {Capybara::Node::Matchers#has_link?}
|
175
|
+
|
176
|
+
##
|
177
|
+
# Assertion that there is no link
|
178
|
+
#
|
179
|
+
# @!method assert_no_link
|
180
|
+
# @!method refute_link
|
181
|
+
# see {Capybara::Node::Matchers#has_no_link?}
|
182
|
+
|
183
|
+
##
|
184
|
+
# Assertion that there is button
|
185
|
+
#
|
186
|
+
# @!method assert_button
|
187
|
+
# see {Capybara::Node::Matchers#has_button?}
|
188
|
+
|
189
|
+
##
|
190
|
+
# Assertion that there is no button
|
191
|
+
#
|
192
|
+
# @!method refute_button
|
193
|
+
# @!method assert_no_button
|
194
|
+
# see {Capybara::Node::Matchers#has_no_button?}
|
195
|
+
|
196
|
+
##
|
197
|
+
# Assertion that there is field
|
198
|
+
#
|
199
|
+
# @!method assert_field
|
200
|
+
# see {Capybara::Node::Matchers#has_field?}
|
201
|
+
|
202
|
+
##
|
203
|
+
# Assertion that there is no field
|
204
|
+
#
|
205
|
+
# @!method refute_field
|
206
|
+
# @!method assert_no_field
|
207
|
+
# see {Capybara::Node::Matchers#has_no_field?}
|
208
|
+
|
209
|
+
##
|
210
|
+
# Assertion that there is checked_field
|
211
|
+
#
|
212
|
+
# @!method assert_checked_field
|
213
|
+
# see {Capybara::Node::Matchers#has_checked_field?}
|
214
|
+
|
215
|
+
##
|
216
|
+
# Assertion that there is no checked_field
|
217
|
+
#
|
218
|
+
# @!method assert_no_checked_field
|
219
|
+
# @!method refute_checked_field
|
220
|
+
|
221
|
+
##
|
222
|
+
# Assertion that there is unchecked_field
|
223
|
+
#
|
224
|
+
# @!method assert_unchecked_field
|
225
|
+
# see {Capybara::Node::Matchers#has_unchecked_field?}
|
226
|
+
|
227
|
+
##
|
228
|
+
# Assertion that there is no unchecked_field
|
229
|
+
#
|
230
|
+
# @!method assert_no_unchecked_field
|
231
|
+
# @!method refute_unchecked_field
|
232
|
+
|
233
|
+
##
|
234
|
+
# Assertion that there is select
|
235
|
+
#
|
236
|
+
# @!method assert_select
|
237
|
+
# see {Capybara::Node::Matchers#has_select?}
|
238
|
+
|
239
|
+
##
|
240
|
+
# Assertion that there is no select
|
241
|
+
#
|
242
|
+
# @!method refute_select
|
243
|
+
# @!method assert_no_select
|
244
|
+
# see {Capybara::Node::Matchers#has_no_select?}
|
245
|
+
|
246
|
+
##
|
247
|
+
# Assertion that there is table
|
248
|
+
#
|
249
|
+
# @!method assert_table
|
250
|
+
# see {Capybara::Node::Matchers#has_table?}
|
251
|
+
|
252
|
+
##
|
253
|
+
# Assertion that there is no table
|
254
|
+
#
|
255
|
+
# @!method refute_table
|
256
|
+
# @!method assert_no_table
|
257
|
+
# see {Capybara::Node::Matchers#has_no_table?}
|
258
|
+
|
259
|
+
private
|
261
260
|
|
262
261
|
def determine_subject(args)
|
263
262
|
case args.first
|
264
263
|
when Capybara::Session, Capybara::Node::Base, Capybara::Node::Simple
|
265
|
-
args
|
264
|
+
[args.shift, args]
|
265
|
+
when ->(arg) { arg.respond_to?(:to_capybara_node) }
|
266
|
+
[args.shift.to_capybara_node, args]
|
266
267
|
else
|
267
|
-
[page,
|
268
|
+
[page, args]
|
268
269
|
end
|
269
270
|
end
|
270
271
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Capybara
|
3
4
|
module Node
|
4
5
|
module Actions
|
5
|
-
|
6
6
|
##
|
7
7
|
#
|
8
8
|
# Finds a button or link and clicks it. See {Capybara::Node::Actions#click_button} and
|
@@ -20,8 +20,7 @@ module Capybara
|
|
20
20
|
#
|
21
21
|
# @return [Capybara::Node::Element] The element clicked
|
22
22
|
#
|
23
|
-
def click_link_or_button(locator=nil, options
|
24
|
-
locator, options = nil, locator if locator.is_a? Hash
|
23
|
+
def click_link_or_button(locator = nil, **options)
|
25
24
|
find(:link_or_button, locator, options).click
|
26
25
|
end
|
27
26
|
alias_method :click_on, :click_link_or_button
|
@@ -38,8 +37,7 @@ module Capybara
|
|
38
37
|
# @param options See {Capybara::Node::Finders#find_link}
|
39
38
|
#
|
40
39
|
# @return [Capybara::Node::Element] The element clicked
|
41
|
-
def click_link(locator=nil, options
|
42
|
-
locator, options = nil, locator if locator.is_a? Hash
|
40
|
+
def click_link(locator = nil, **options)
|
43
41
|
find(:link, locator, options).click
|
44
42
|
end
|
45
43
|
|
@@ -56,8 +54,7 @@ module Capybara
|
|
56
54
|
# @param [String] locator Which button to find
|
57
55
|
# @param options See {Capybara::Node::Finders#find_button}
|
58
56
|
# @return [Capybara::Node::Element] The element clicked
|
59
|
-
def click_button(locator=nil, options
|
60
|
-
locator, options = nil, locator if locator.is_a? Hash
|
57
|
+
def click_button(locator = nil, **options)
|
61
58
|
find(:button, locator, options).click
|
62
59
|
end
|
63
60
|
|
@@ -83,12 +80,8 @@ module Capybara
|
|
83
80
|
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
84
81
|
#
|
85
82
|
# @return [Capybara::Node::Element] The element filled_in
|
86
|
-
def fill_in(locator,
|
87
|
-
|
88
|
-
raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with)
|
89
|
-
with = options.delete(:with)
|
90
|
-
fill_options = options.delete(:fill_options)
|
91
|
-
options[:with] = options.delete(:currently_with) if options.has_key?(:currently_with)
|
83
|
+
def fill_in(locator = nil, with:, fill_options: {}, **options)
|
84
|
+
options[:with] = options.delete(:currently_with) if options.key?(:currently_with)
|
92
85
|
find(:fillable_field, locator, options).set(with, fill_options)
|
93
86
|
end
|
94
87
|
|
@@ -113,8 +106,8 @@ module Capybara
|
|
113
106
|
# @macro label_click
|
114
107
|
#
|
115
108
|
# @return [Capybara::Node::Element] The element chosen or the label clicked
|
116
|
-
def choose(locator, options
|
117
|
-
_check_with_label(:radio_button, true, locator, options)
|
109
|
+
def choose(locator = nil, **options)
|
110
|
+
_check_with_label(:radio_button, true, locator, **options)
|
118
111
|
end
|
119
112
|
|
120
113
|
##
|
@@ -136,8 +129,8 @@ module Capybara
|
|
136
129
|
# @macro waiting_behavior
|
137
130
|
#
|
138
131
|
# @return [Capybara::Node::Element] The element checked or the label clicked
|
139
|
-
def check(locator, options
|
140
|
-
_check_with_label(:checkbox, true, locator, options)
|
132
|
+
def check(locator, **options)
|
133
|
+
_check_with_label(:checkbox, true, locator, **options)
|
141
134
|
end
|
142
135
|
|
143
136
|
##
|
@@ -159,8 +152,8 @@ module Capybara
|
|
159
152
|
# @macro waiting_behavior
|
160
153
|
#
|
161
154
|
# @return [Capybara::Node::Element] The element unchecked or the label clicked
|
162
|
-
def uncheck(locator, options
|
163
|
-
_check_with_label(:checkbox, false, locator, options)
|
155
|
+
def uncheck(locator = nil, **options)
|
156
|
+
_check_with_label(:checkbox, false, locator, **options)
|
164
157
|
end
|
165
158
|
|
166
159
|
##
|
@@ -180,13 +173,9 @@ module Capybara
|
|
180
173
|
# @option options [String] :from The id, name or label of the select box
|
181
174
|
#
|
182
175
|
# @return [Capybara::Node::Element] The option element selected
|
183
|
-
def select(value, options
|
184
|
-
|
185
|
-
|
186
|
-
find(:select, from, options).find(:option, value, options).select_option
|
187
|
-
else
|
188
|
-
find(:option, value, options).select_option
|
189
|
-
end
|
176
|
+
def select(value = nil, from: nil, **options)
|
177
|
+
scope = from ? find(:select, from, options) : self
|
178
|
+
scope.find(:option, value, options).select_option
|
190
179
|
end
|
191
180
|
|
192
181
|
##
|
@@ -203,13 +192,9 @@ module Capybara
|
|
203
192
|
# @param [Hash{:from => String}] options The id, name or label of the select box
|
204
193
|
#
|
205
194
|
# @return [Capybara::Node::Element] The option element unselected
|
206
|
-
def unselect(value, options
|
207
|
-
|
208
|
-
|
209
|
-
find(:select, from, options).find(:option, value, options).unselect_option
|
210
|
-
else
|
211
|
-
find(:option, value, options).unselect_option
|
212
|
-
end
|
195
|
+
def unselect(value = nil, from: nil, **options)
|
196
|
+
scope = from ? find(:select, from, options) : self
|
197
|
+
scope.find(:option, value, options).unselect_option
|
213
198
|
end
|
214
199
|
|
215
200
|
##
|
@@ -233,68 +218,44 @@ module Capybara
|
|
233
218
|
# @option options [true, Hash] make_visible A Hash of CSS styles to change before attempting to attach the file, if `true` { opacity: 1, display: 'block', visibility: 'visible' } is used (may not be supported by all drivers)
|
234
219
|
#
|
235
220
|
# @return [Capybara::Node::Element] The file field element
|
236
|
-
def attach_file(locator, path, options
|
237
|
-
locator, path, options = nil, locator, path if path.is_a? Hash
|
221
|
+
def attach_file(locator = nil, path, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
|
238
222
|
Array(path).each do |p|
|
239
223
|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
|
240
224
|
end
|
241
225
|
# Allow user to update the CSS style of the file input since they are so often hidden on a page
|
242
|
-
if
|
243
|
-
|
244
|
-
ff
|
245
|
-
_update_style(ff, style)
|
246
|
-
if ff.visible?
|
247
|
-
begin
|
248
|
-
ff.set(path)
|
249
|
-
ensure
|
250
|
-
_reset_style(ff)
|
251
|
-
end
|
252
|
-
else
|
253
|
-
raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible"
|
254
|
-
end
|
226
|
+
if make_visible
|
227
|
+
ff = find(:file_field, locator, options.merge(visible: :all))
|
228
|
+
while_visible(ff, make_visible) { |el| el.set(path) }
|
255
229
|
else
|
256
230
|
find(:file_field, locator, options).set(path)
|
257
231
|
end
|
258
232
|
end
|
259
233
|
|
260
234
|
private
|
261
|
-
def _update_style(element, style)
|
262
|
-
script = <<-JS
|
263
|
-
var el = arguments[0];
|
264
|
-
el.capybara_style_cache = el.style.cssText;
|
265
|
-
var css = arguments[1];
|
266
|
-
for (var prop in css){
|
267
|
-
if (css.hasOwnProperty(prop)) {
|
268
|
-
el.style[prop] = css[prop]
|
269
|
-
}
|
270
|
-
}
|
271
|
-
JS
|
272
|
-
begin
|
273
|
-
session.execute_script(script, element, style)
|
274
|
-
rescue Capybara::NotSupportedByDriverError
|
275
|
-
warn "The :make_visible option is not supported by the current driver - ignoring"
|
276
|
-
end
|
277
|
-
end
|
278
235
|
|
279
|
-
def
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
el.style.cssText = el.capybara_style_cache;
|
284
|
-
delete el.capybara_style_cache;
|
285
|
-
}
|
286
|
-
JS
|
236
|
+
def while_visible(element, visible_css)
|
237
|
+
visible_css = { opacity: 1, display: 'block', visibility: 'visible' } if visible_css == true
|
238
|
+
_update_style(element, visible_css)
|
239
|
+
raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible" unless element.visible?
|
287
240
|
begin
|
288
|
-
|
289
|
-
|
241
|
+
yield element
|
242
|
+
ensure
|
243
|
+
_reset_style(element)
|
290
244
|
end
|
291
245
|
end
|
292
246
|
|
247
|
+
def _update_style(element, style)
|
248
|
+
session.execute_script(UPDATE_STYLE_SCRIPT, element, style)
|
249
|
+
rescue Capybara::NotSupportedByDriverError
|
250
|
+
warn "The :make_visible option is not supported by the current driver - ignoring"
|
251
|
+
end
|
293
252
|
|
294
|
-
def
|
295
|
-
|
296
|
-
|
253
|
+
def _reset_style(element)
|
254
|
+
session.execute_script(RESET_STYLE_SCRIPT, element)
|
255
|
+
rescue # swallow extra errors
|
256
|
+
end
|
297
257
|
|
258
|
+
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
|
298
259
|
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
299
260
|
begin
|
300
261
|
el = find(selector, locator, options)
|
@@ -303,15 +264,33 @@ module Capybara
|
|
303
264
|
raise unless allow_label_click && catch_error?(e)
|
304
265
|
begin
|
305
266
|
el ||= find(selector, locator, options.merge(visible: :all))
|
306
|
-
|
307
|
-
|
308
|
-
rescue
|
267
|
+
res = find(:label, for: el, visible: true).click unless el.checked? == checked
|
268
|
+
res
|
269
|
+
rescue # swallow extra errors - raise original
|
309
270
|
raise e
|
310
271
|
end
|
311
272
|
end
|
312
273
|
end
|
313
274
|
end
|
314
275
|
|
276
|
+
UPDATE_STYLE_SCRIPT = <<-'JS'.freeze
|
277
|
+
var el = arguments[0];
|
278
|
+
el.capybara_style_cache = el.style.cssText;
|
279
|
+
var css = arguments[1];
|
280
|
+
for (var prop in css){
|
281
|
+
if (css.hasOwnProperty(prop)) {
|
282
|
+
el.style[prop] = css[prop]
|
283
|
+
}
|
284
|
+
}
|
285
|
+
JS
|
286
|
+
|
287
|
+
RESET_STYLE_SCRIPT = <<-'JS'.freeze
|
288
|
+
var el = arguments[0];
|
289
|
+
if (el.hasOwnProperty('capybara_style_cache')) {
|
290
|
+
el.style.cssText = el.capybara_style_cache;
|
291
|
+
delete el.capybara_style_cache;
|
292
|
+
}
|
293
|
+
JS
|
315
294
|
end
|
316
295
|
end
|
317
296
|
end
|
data/lib/capybara/node/base.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Capybara
|
3
4
|
module Node
|
4
|
-
|
5
5
|
##
|
6
6
|
#
|
7
7
|
# A {Capybara::Node::Base} represents either an element on a page through the subclass
|
@@ -67,26 +67,23 @@ module Capybara
|
|
67
67
|
# time has passed. On rubies/platforms which don't support access to a monotonic process clock
|
68
68
|
# if the return value of `Time.now` is stubbed out, Capybara will raise `Capybara::FrozenInTime`.
|
69
69
|
#
|
70
|
-
# @param [Integer] seconds
|
71
|
-
# @param
|
72
|
-
# @option options [Array<Exception>] :errors (driver.invalid_element_errors +
|
70
|
+
# @param [Integer] seconds (current sessions default_max_wait_time) Maximum number of seconds to retry this block
|
71
|
+
# @param [Array<Exception>] errors (driver.invalid_element_errors +
|
73
72
|
# [Capybara::ElementNotFound]) exception types that cause the block to be rerun
|
74
73
|
# @return [Object] The result of the given block
|
75
74
|
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
|
76
75
|
#
|
77
|
-
def synchronize(seconds=session_options.default_max_wait_time,
|
78
|
-
start_time = Capybara::Helpers.monotonic_time
|
79
|
-
|
76
|
+
def synchronize(seconds = session_options.default_max_wait_time, errors: nil)
|
80
77
|
if session.synchronized
|
81
78
|
yield
|
82
79
|
else
|
83
80
|
session.synchronized = true
|
81
|
+
start_time = Capybara::Helpers.monotonic_time
|
84
82
|
begin
|
85
83
|
yield
|
86
84
|
rescue => e
|
87
85
|
session.raise_server_error!
|
88
|
-
raise e unless driver.wait?
|
89
|
-
raise e unless catch_error?(e, options[:errors])
|
86
|
+
raise e unless driver.wait? && catch_error?(e, errors)
|
90
87
|
raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds
|
91
88
|
sleep(0.05)
|
92
89
|
raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time
|
@@ -108,24 +105,20 @@ module Capybara
|
|
108
105
|
base.find_xpath(xpath)
|
109
106
|
end
|
110
107
|
|
111
|
-
# @deprecated Use query_scope instead
|
112
|
-
def parent
|
113
|
-
warn "DEPRECATED: #parent is deprecated in favor of #query_scope - Note: #parent was not the elements parent in the document so it's most likely not what you wanted anyway"
|
114
|
-
query_scope
|
115
|
-
end
|
116
|
-
|
117
108
|
# @api private
|
118
109
|
def session_options
|
119
110
|
session.config
|
120
111
|
end
|
121
112
|
|
113
|
+
def to_capybara_node
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
122
117
|
protected
|
123
118
|
|
124
119
|
def catch_error?(error, errors = nil)
|
125
120
|
errors ||= (driver.invalid_element_errors + [Capybara::ElementNotFound])
|
126
|
-
errors.any?
|
127
|
-
error.is_a?(type)
|
128
|
-
end
|
121
|
+
errors.any? { |type| error.is_a?(type) }
|
129
122
|
end
|
130
123
|
|
131
124
|
def driver
|