capybara 2.15.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.
Files changed (177) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +137 -2
  3. data/README.md +36 -25
  4. data/lib/capybara/config.rb +11 -57
  5. data/lib/capybara/cucumber.rb +2 -3
  6. data/lib/capybara/driver/base.rb +19 -16
  7. data/lib/capybara/driver/node.rb +5 -4
  8. data/lib/capybara/dsl.rb +1 -0
  9. data/lib/capybara/helpers.rb +19 -29
  10. data/lib/capybara/minitest/spec.rb +16 -13
  11. data/lib/capybara/minitest.rb +140 -137
  12. data/lib/capybara/node/actions.rb +68 -89
  13. data/lib/capybara/node/base.rb +11 -18
  14. data/lib/capybara/node/document.rb +2 -2
  15. data/lib/capybara/node/document_matchers.rb +8 -8
  16. data/lib/capybara/node/element.rb +32 -42
  17. data/lib/capybara/node/finders.rb +64 -71
  18. data/lib/capybara/node/matchers.rb +50 -71
  19. data/lib/capybara/node/simple.rb +11 -17
  20. data/lib/capybara/queries/ancestor_query.rb +12 -8
  21. data/lib/capybara/queries/base_query.rb +22 -18
  22. data/lib/capybara/queries/current_path_query.rb +12 -25
  23. data/lib/capybara/queries/match_query.rb +3 -7
  24. data/lib/capybara/queries/selector_query.rb +100 -96
  25. data/lib/capybara/queries/sibling_query.rb +5 -5
  26. data/lib/capybara/queries/text_query.rb +35 -35
  27. data/lib/capybara/queries/title_query.rb +8 -11
  28. data/lib/capybara/rack_test/browser.rb +15 -18
  29. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  30. data/lib/capybara/rack_test/driver.rb +6 -10
  31. data/lib/capybara/rack_test/form.rb +52 -39
  32. data/lib/capybara/rack_test/node.rb +93 -63
  33. data/lib/capybara/rails.rb +2 -6
  34. data/lib/capybara/result.rb +22 -22
  35. data/lib/capybara/rspec/compound.rb +5 -10
  36. data/lib/capybara/rspec/features.rb +17 -48
  37. data/lib/capybara/rspec/matcher_proxies.rb +31 -15
  38. data/lib/capybara/rspec/matchers.rb +116 -58
  39. data/lib/capybara/rspec.rb +5 -10
  40. data/lib/capybara/selector/css.rb +6 -11
  41. data/lib/capybara/selector/filter.rb +1 -17
  42. data/lib/capybara/selector/filter_set.rb +18 -15
  43. data/lib/capybara/selector/filters/base.rb +7 -6
  44. data/lib/capybara/selector/filters/expression_filter.rb +6 -23
  45. data/lib/capybara/selector/filters/node_filter.rb +2 -12
  46. data/lib/capybara/selector/selector.rb +28 -34
  47. data/lib/capybara/selector.rb +129 -117
  48. data/lib/capybara/selenium/driver.rb +172 -163
  49. data/lib/capybara/selenium/node.rb +218 -104
  50. data/lib/capybara/server.rb +3 -2
  51. data/lib/capybara/session/config.rb +47 -59
  52. data/lib/capybara/session/matchers.rb +23 -14
  53. data/lib/capybara/session.rb +175 -229
  54. data/lib/capybara/spec/fixtures/no_extension +1 -0
  55. data/lib/capybara/spec/public/test.js +38 -6
  56. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
  57. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
  58. data/lib/capybara/spec/session/accept_prompt_spec.rb +30 -1
  59. data/lib/capybara/spec/session/all_spec.rb +31 -18
  60. data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
  61. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
  62. data/lib/capybara/spec/session/assert_current_path.rb +12 -11
  63. data/lib/capybara/spec/session/assert_selector.rb +1 -0
  64. data/lib/capybara/spec/session/assert_text.rb +31 -23
  65. data/lib/capybara/spec/session/assert_title.rb +13 -3
  66. data/lib/capybara/spec/session/attach_file_spec.rb +57 -29
  67. data/lib/capybara/spec/session/body_spec.rb +1 -0
  68. data/lib/capybara/spec/session/check_spec.rb +7 -6
  69. data/lib/capybara/spec/session/choose_spec.rb +5 -4
  70. data/lib/capybara/spec/session/click_button_spec.rb +24 -32
  71. data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
  72. data/lib/capybara/spec/session/click_link_spec.rb +8 -7
  73. data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
  74. data/lib/capybara/spec/session/current_url_spec.rb +19 -8
  75. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
  76. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
  77. data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
  78. data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
  79. data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
  80. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  81. data/lib/capybara/spec/session/evaluate_script_spec.rb +5 -4
  82. data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
  83. data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
  84. data/lib/capybara/spec/session/find_button_spec.rb +4 -3
  85. data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
  86. data/lib/capybara/spec/session/find_field_spec.rb +9 -15
  87. data/lib/capybara/spec/session/find_link_spec.rb +6 -5
  88. data/lib/capybara/spec/session/find_spec.rb +37 -31
  89. data/lib/capybara/spec/session/first_spec.rb +60 -33
  90. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  91. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  92. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
  93. data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
  94. data/lib/capybara/spec/session/go_back_spec.rb +1 -0
  95. data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
  96. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  97. data/lib/capybara/spec/session/has_button_spec.rb +2 -1
  98. data/lib/capybara/spec/session/has_css_spec.rb +3 -2
  99. data/lib/capybara/spec/session/has_current_path_spec.rb +49 -22
  100. data/lib/capybara/spec/session/has_field_spec.rb +4 -3
  101. data/lib/capybara/spec/session/has_link_spec.rb +5 -4
  102. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  103. data/lib/capybara/spec/session/has_select_spec.rb +32 -31
  104. data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
  105. data/lib/capybara/spec/session/has_table_spec.rb +2 -1
  106. data/lib/capybara/spec/session/has_text_spec.rb +9 -13
  107. data/lib/capybara/spec/session/has_title_spec.rb +1 -0
  108. data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
  109. data/lib/capybara/spec/session/headers.rb +2 -1
  110. data/lib/capybara/spec/session/html_spec.rb +1 -0
  111. data/lib/capybara/spec/session/node_spec.rb +107 -58
  112. data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
  113. data/lib/capybara/spec/session/refresh_spec.rb +6 -2
  114. data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
  115. data/lib/capybara/spec/session/response_code.rb +1 -0
  116. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  117. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
  118. data/lib/capybara/spec/session/save_page_spec.rb +1 -17
  119. data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
  120. data/lib/capybara/spec/session/select_spec.rb +21 -20
  121. data/lib/capybara/spec/session/selectors_spec.rb +2 -2
  122. data/lib/capybara/spec/session/sibling_spec.rb +1 -1
  123. data/lib/capybara/spec/session/text_spec.rb +17 -3
  124. data/lib/capybara/spec/session/title_spec.rb +11 -1
  125. data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
  126. data/lib/capybara/spec/session/unselect_spec.rb +7 -6
  127. data/lib/capybara/spec/session/visit_spec.rb +64 -3
  128. data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
  129. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  130. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  131. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
  132. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
  133. data/lib/capybara/spec/session/window/window_spec.rb +12 -12
  134. data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
  135. data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
  136. data/lib/capybara/spec/session/within_spec.rb +1 -0
  137. data/lib/capybara/spec/spec_helper.rb +36 -18
  138. data/lib/capybara/spec/test_app.rb +17 -9
  139. data/lib/capybara/spec/views/form.erb +7 -0
  140. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  141. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  142. data/lib/capybara/spec/views/with_hover.erb +5 -0
  143. data/lib/capybara/spec/views/with_html.erb +27 -1
  144. data/lib/capybara/spec/views/with_js.erb +11 -0
  145. data/lib/capybara/spec/views/within_frames.erb +4 -1
  146. data/lib/capybara/version.rb +2 -1
  147. data/lib/capybara/window.rb +6 -10
  148. data/lib/capybara.rb +29 -26
  149. data/spec/basic_node_spec.rb +1 -0
  150. data/spec/capybara_spec.rb +16 -69
  151. data/spec/dsl_spec.rb +5 -13
  152. data/spec/filter_set_spec.rb +5 -4
  153. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
  154. data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
  155. data/spec/minitest_spec.rb +13 -4
  156. data/spec/minitest_spec_spec.rb +12 -3
  157. data/spec/per_session_config_spec.rb +9 -8
  158. data/spec/rack_test_spec.rb +21 -20
  159. data/spec/result_spec.rb +17 -16
  160. data/spec/rspec/features_spec.rb +17 -14
  161. data/spec/rspec/scenarios_spec.rb +5 -7
  162. data/spec/rspec/shared_spec_matchers.rb +96 -99
  163. data/spec/rspec/views_spec.rb +2 -1
  164. data/spec/rspec_matchers_spec.rb +18 -2
  165. data/spec/rspec_spec.rb +11 -15
  166. data/spec/selector_spec.rb +5 -6
  167. data/spec/selenium_spec_chrome.rb +20 -11
  168. data/spec/selenium_spec_edge.rb +27 -0
  169. data/spec/selenium_spec_ie.rb +31 -0
  170. data/spec/selenium_spec_marionette.rb +38 -12
  171. data/spec/server_spec.rb +33 -33
  172. data/spec/session_spec.rb +2 -1
  173. data/spec/shared_selenium_session.rb +82 -22
  174. data/spec/spec_helper.rb +3 -6
  175. metadata +76 -81
  176. data/lib/capybara/query.rb +0 -7
  177. data/spec/selenium_spec_firefox.rb +0 -68
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
4
  module Node
4
5
  module Finders
5
-
6
6
  ##
7
7
  #
8
8
  # Find an {Capybara::Node::Element} based on the given arguments. +find+ will raise an error if the element
@@ -28,13 +28,9 @@ module Capybara
28
28
  # @return [Capybara::Node::Element] The found element
29
29
  # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
30
30
  #
31
- def find(*args, &optional_filter_block)
32
- if args.last.is_a? Hash
33
- args.last[:session_options] = session_options
34
- else
35
- args.push(session_options: session_options)
36
- end
37
- synced_resolve Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
31
+ def find(*args, **options, &optional_filter_block)
32
+ options[:session_options] = session_options
33
+ synced_resolve Capybara::Queries::SelectorQuery.new(*args, options, &optional_filter_block)
38
34
  end
39
35
 
40
36
  ##
@@ -57,13 +53,9 @@ module Capybara
57
53
  # @return [Capybara::Node::Element] The found element
58
54
  # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
59
55
  #
60
- def ancestor(*args, &optional_filter_block)
61
- if args.last.is_a? Hash
62
- args.last[:session_options] = session_options
63
- else
64
- args.push(session_options: session_options)
65
- end
66
- synced_resolve Capybara::Queries::AncestorQuery.new(*args, &optional_filter_block)
56
+ def ancestor(*args, **options, &optional_filter_block)
57
+ options[:session_options] = session_options
58
+ synced_resolve Capybara::Queries::AncestorQuery.new(*args, **options, &optional_filter_block)
67
59
  end
68
60
 
69
61
  ##
@@ -87,13 +79,9 @@ module Capybara
87
79
  # @return [Capybara::Node::Element] The found element
88
80
  # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
89
81
  #
90
- def sibling(*args, &optional_filter_block)
91
- if args.last.is_a? Hash
92
- args.last[:session_options] = session_options
93
- else
94
- args.push(session_options: session_options)
95
- end
96
- synced_resolve Capybara::Queries::SiblingQuery.new(*args, &optional_filter_block)
82
+ def sibling(*args, **options, &optional_filter_block)
83
+ options[:session_options] = session_options
84
+ synced_resolve Capybara::Queries::SiblingQuery.new(*args, **options, &optional_filter_block)
97
85
  end
98
86
 
99
87
  ##
@@ -123,11 +111,9 @@ module Capybara
123
111
  # @return [Capybara::Node::Element] The found element
124
112
  #
125
113
 
126
- def find_field(locator=nil, options={}, &optional_filter_block)
127
- locator, options = nil, locator if locator.is_a? Hash
114
+ def find_field(locator = nil, **options, &optional_filter_block)
128
115
  find(:field, locator, options, &optional_filter_block)
129
116
  end
130
- alias_method :field_labeled, :find_field
131
117
 
132
118
  ##
133
119
  #
@@ -145,8 +131,7 @@ module Capybara
145
131
  # @option options [String, Array<String>] class Match links that match the class(es) provided
146
132
  # @return [Capybara::Node::Element] The found element
147
133
  #
148
- def find_link(locator=nil, options={}, &optional_filter_block)
149
- locator, options = nil, locator if locator.is_a? Hash
134
+ def find_link(locator = nil, **options, &optional_filter_block)
150
135
  find(:link, locator, options, &optional_filter_block)
151
136
  end
152
137
 
@@ -171,11 +156,10 @@ module Capybara
171
156
  # @option options [String] id Match buttons with the id provided
172
157
  # @option options [String] title Match buttons with the title provided
173
158
  # @option options [String] value Match buttons with the value provided
174
- # @option options [String, Array<String>] class Match links that match the class(es) provided
159
+ # @option options [String, Array<String>] class Match buttons that match the class(es) provided
175
160
  # @return [Capybara::Node::Element] The found element
176
161
  #
177
- def find_button(locator=nil, options={}, &optional_filter_block)
178
- locator, options = nil, locator if locator.is_a? Hash
162
+ def find_button(locator = nil, **options, &optional_filter_block)
179
163
  find(:button, locator, options, &optional_filter_block)
180
164
  end
181
165
 
@@ -189,7 +173,7 @@ module Capybara
189
173
  #
190
174
  # @return [Capybara::Node::Element] The found element
191
175
  #
192
- def find_by_id(id, options={}, &optional_filter_block)
176
+ def find_by_id(id, **options, &optional_filter_block)
193
177
  find(:id, id, options, &optional_filter_block)
194
178
  end
195
179
 
@@ -221,10 +205,11 @@ module Capybara
221
205
  # page.all('a', text: 'Home')
222
206
  # page.all('#menu li', visible: true)
223
207
  #
224
- # By default if no elements are found, an empty array is returned;
225
- # however, expectations can be set on the number of elements to be found which
226
- # will trigger Capybara's waiting behavior for the expectations to match.The
227
- # expectations can be set using
208
+ # By default Capybara's waiting behavior will wait up to `Capybara.default_max_wait_time`
209
+ # seconds for matching elements to be available and then return an empty result if none
210
+ # are available. It is possible to set expectations on the number of results located and
211
+ # Capybara will raise an exception if the number of elements located don't satisfy the
212
+ # specified conditions. The expectations can be set using
228
213
  #
229
214
  # page.assert_selector('p#foo', count: 4)
230
215
  # page.assert_selector('p#foo', maximum: 10)
@@ -235,9 +220,9 @@ module Capybara
235
220
  # count matching.
236
221
  #
237
222
  # @param [Symbol] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to Capybara.default_selector
238
- # @param [String] locator The selector
223
+ # @param [String] locator The locator for the specified selector
239
224
  # @option options [String, Regexp] text Only find elements which contain this text or match this regexp
240
- # @option options [String, Boolean] exact_text (Capybara.exact_text) When String the string the elements contained text must match exactly, when Boolean controls whether the :text option must match exactly
225
+ # @option options [String, Boolean] exact_text (Capybara.exact_text) When String the elements contained text must match exactly, when Boolean controls whether the :text option must match exactly
241
226
  # @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
242
227
  # * true - only finds visible elements.
243
228
  # * false - finds invisible _and_ visible elements.
@@ -249,24 +234,28 @@ module Capybara
249
234
  # @option options [Integer] minimum Minimum number of matches that are expected to be found
250
235
  # @option options [Range] between Number of matches found must be within the given range
251
236
  # @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
252
- # @option options [Integer] wait (Capybara.default_max_wait_time) The time to wait for element count expectations to become true
237
+ # @option options [Integer, false] wait (Capybara.default_max_wait_time) The time to wait for matching elements to become available
253
238
  # @overload all([kind = Capybara.default_selector], locator = nil, options = {})
254
239
  # @overload all([kind = Capybara.default_selector], locator = nil, options = {}, &filter_block)
255
240
  # @yieldparam element [Capybara::Node::Element] The element being considered for inclusion in the results
256
241
  # @yieldreturn [Boolean] Should the element be considered in the results?
257
242
  # @return [Capybara::Result] A collection of found elements
258
- #
259
- def all(*args, &optional_filter_block)
260
- if args.last.is_a? Hash
261
- args.last[:session_options] = session_options
262
- else
263
- args.push(session_options: session_options)
264
- end
265
- query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
266
- synchronize(query.wait) do
267
- result = query.resolve_for(self)
268
- raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
269
- result
243
+ # @raise [Capybara::ExpectationNotMet] The number of elements found doesn't match the specified conditions
244
+ def all(*args, **options, &optional_filter_block)
245
+ minimum_specified = options_include_minimum?(options)
246
+ options = { minimum: 1 }.merge(options) unless minimum_specified
247
+ options[:session_options] = session_options
248
+ query = Capybara::Queries::SelectorQuery.new(*args.push(options), &optional_filter_block)
249
+ result = nil
250
+ begin
251
+ synchronize(query.wait) do
252
+ result = query.resolve_for(self)
253
+ raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
254
+ result
255
+ end
256
+ rescue Capybara::ExpectationNotMet
257
+ raise if minimum_specified || (result.compare_count == 1)
258
+ Result.new([], nil)
270
259
  end
271
260
  end
272
261
  alias_method :find_all, :all
@@ -274,47 +263,51 @@ module Capybara
274
263
  ##
275
264
  #
276
265
  # Find the first element on the page matching the given selector
277
- # and options, or nil if no element matches. By default no waiting
278
- # behavior occurs, however if {Capybara.wait_on_first_by_default} is set to true
279
- # it will trigger Capybara's waiting behavior for a minimum of 1 matching element to be found and
280
- # return the first. Waiting behavior can also be triggered by passing in any of the count
281
- # expectation options.
266
+ # and options. By default `first` will wait up to `Capybara.default_max_wait_time`
267
+ # seconds for matching elements to appear and then raise an error if no matching
268
+ # element is found, or `nil` if the provided count options allow for empty results.
282
269
  #
283
270
  # @overload first([kind], locator, options)
284
271
  # @param [:css, :xpath] kind The type of selector
285
272
  # @param [String] locator The selector
286
273
  # @param [Hash] options Additional options; see {#all}
287
274
  # @return [Capybara::Node::Element] The found element or nil
275
+ # @raise [Capybara::ElementNotFound] If element(s) matching the provided options can't be found before time expires
288
276
  #
289
- def first(*args, &optional_filter_block)
290
- if session_options.wait_on_first_by_default
291
- options = if args.last.is_a?(Hash) then args.pop.dup else {} end
292
- args.push({minimum: 1}.merge(options))
293
- end
294
- all(*args, &optional_filter_block).first
295
- rescue Capybara::ExpectationNotMet
296
- nil
277
+ def first(*args, **options, &optional_filter_block)
278
+ options = { minimum: 1 }.merge(options) unless options_include_minimum?(options)
279
+ all(*args, **options, &optional_filter_block).first
297
280
  end
298
281
 
299
- private
282
+ private
300
283
 
301
284
  def synced_resolve(query)
302
285
  synchronize(query.wait) do
303
- if (query.match == :smart or query.match == :prefer_exact)
286
+ if prefer_exact?(query)
304
287
  result = query.resolve_for(self, true)
305
288
  result = query.resolve_for(self, false) if result.empty? && query.supports_exact? && !query.exact?
306
289
  else
307
290
  result = query.resolve_for(self)
308
291
  end
309
- if query.match == :one or query.match == :smart and result.size > 1
310
- raise Capybara::Ambiguous.new("Ambiguous match, found #{result.size} elements matching #{query.description}")
311
- end
312
- if result.empty?
313
- raise Capybara::ElementNotFound.new("Unable to find #{query.description}")
314
- end
292
+
293
+ raise Capybara::Ambiguous, "Ambiguous match, found #{result.size} elements matching #{query.description}" if ambiguous?(query, result)
294
+ raise Capybara::ElementNotFound, "Unable to find #{query.description}" if result.empty?
295
+
315
296
  result.first
316
297
  end.tap(&:allow_reload!)
317
298
  end
299
+
300
+ def ambiguous?(query, result)
301
+ query.match == :one or query.match == :smart and result.size > 1
302
+ end
303
+
304
+ def prefer_exact?(query)
305
+ query.match == :smart or query.match == :prefer_exact
306
+ end
307
+
308
+ def options_include_minimum?(opts)
309
+ %i[count minimum between].any? { |k| opts.key?(k) }
310
+ end
318
311
  end
319
312
  end
320
313
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
4
  module Node
4
5
  module Matchers
5
-
6
6
  ##
7
7
  #
8
8
  # Checks if a given selector is on the page or a descendant of the current node.
@@ -39,7 +39,7 @@ module Capybara
39
39
  def has_selector?(*args, &optional_filter_block)
40
40
  assert_selector(*args, &optional_filter_block)
41
41
  rescue Capybara::ExpectationNotMet
42
- return false
42
+ false
43
43
  end
44
44
 
45
45
  ##
@@ -53,7 +53,7 @@ module Capybara
53
53
  def has_no_selector?(*args, &optional_filter_block)
54
54
  assert_no_selector(*args, &optional_filter_block)
55
55
  rescue Capybara::ExpectationNotMet
56
- return false
56
+ false
57
57
  end
58
58
 
59
59
  ##
@@ -91,7 +91,7 @@ module Capybara
91
91
  #
92
92
  def assert_selector(*args, &optional_filter_block)
93
93
  _verify_selector_result(args, optional_filter_block) do |result, query|
94
- unless result.matches_count? && ((!result.empty?) || query.expects_none?)
94
+ unless result.matches_count? && (!result.empty? || query.expects_none?)
95
95
  raise Capybara::ExpectationNotMet, result.failure_message
96
96
  end
97
97
  end
@@ -112,10 +112,9 @@ module Capybara
112
112
  #
113
113
  # @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, options = {})
114
114
  #
115
- def assert_all_of_selectors(*args, &optional_filter_block)
116
- options = if args.last.is_a?(Hash) then args.pop.dup else {} end
117
- selector = if args.first.is_a?(Symbol) then args.shift else session_options.default_selector end
118
- wait = options.fetch(:wait, session_options.default_max_wait_time)
115
+ def assert_all_of_selectors(*args, wait: nil, **options, &optional_filter_block)
116
+ wait = session_options.default_max_wait_time if wait.nil?
117
+ selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
119
118
  synchronize(wait) do
120
119
  args.each do |locator|
121
120
  assert_selector(selector, locator, options, &optional_filter_block)
@@ -138,10 +137,9 @@ module Capybara
138
137
  #
139
138
  # @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, options = {})
140
139
  #
141
- def assert_none_of_selectors(*args, &optional_filter_block)
142
- options = if args.last.is_a?(Hash) then args.pop.dup else {} end
143
- selector = if args.first.is_a?(Symbol) then args.shift else session_options.default_selector end
144
- wait = options.fetch(:wait, session_options.default_max_wait_time)
140
+ def assert_none_of_selectors(*args, wait: nil, **options, &optional_filter_block)
141
+ wait = session_options.default_max_wait_time if wait.nil?
142
+ selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
145
143
  synchronize(wait) do
146
144
  args.each do |locator|
147
145
  assert_no_selector(selector, locator, options, &optional_filter_block)
@@ -167,7 +165,7 @@ module Capybara
167
165
  #
168
166
  def assert_no_selector(*args, &optional_filter_block)
169
167
  _verify_selector_result(args, optional_filter_block) do |result, query|
170
- if result.matches_count? && ((!result.empty?) || query.expects_none?)
168
+ if result.matches_count? && (!result.empty? || query.expects_none?)
171
169
  raise Capybara::ExpectationNotMet, result.negative_failure_message
172
170
  end
173
171
  end
@@ -203,7 +201,7 @@ module Capybara
203
201
  # @option options [Integer] :count (nil) Number of times the expression should occur
204
202
  # @return [Boolean] If the expression exists
205
203
  #
206
- def has_xpath?(path, options={}, &optional_filter_block)
204
+ def has_xpath?(path, **options, &optional_filter_block)
207
205
  has_selector?(:xpath, path, options, &optional_filter_block)
208
206
  end
209
207
 
@@ -215,7 +213,7 @@ module Capybara
215
213
  # @param (see Capybara::Node::Finders#has_xpath?)
216
214
  # @return [Boolean]
217
215
  #
218
- def has_no_xpath?(path, options={}, &optional_filter_block)
216
+ def has_no_xpath?(path, **options, &optional_filter_block)
219
217
  has_no_selector?(:xpath, path, options, &optional_filter_block)
220
218
  end
221
219
 
@@ -242,7 +240,7 @@ module Capybara
242
240
  # @option options [Integer] :count (nil) Number of times the selector should occur
243
241
  # @return [Boolean] If the selector exists
244
242
  #
245
- def has_css?(path, options={}, &optional_filter_block)
243
+ def has_css?(path, **options, &optional_filter_block)
246
244
  has_selector?(:css, path, options, &optional_filter_block)
247
245
  end
248
246
 
@@ -254,7 +252,7 @@ module Capybara
254
252
  # @param (see Capybara::Node::Finders#has_css?)
255
253
  # @return [Boolean]
256
254
  #
257
- def has_no_css?(path, options={}, &optional_filter_block)
255
+ def has_no_css?(path, **options, &optional_filter_block)
258
256
  has_no_selector?(:css, path, options, &optional_filter_block)
259
257
  end
260
258
 
@@ -268,8 +266,7 @@ module Capybara
268
266
  # @option options [String, Regexp] :href The value the href attribute must be
269
267
  # @return [Boolean] Whether it exists
270
268
  #
271
- def has_link?(locator=nil, options={}, &optional_filter_block)
272
- locator, options = nil, locator if locator.is_a? Hash
269
+ def has_link?(locator = nil, **options, &optional_filter_block)
273
270
  has_selector?(:link, locator, options, &optional_filter_block)
274
271
  end
275
272
 
@@ -281,8 +278,7 @@ module Capybara
281
278
  # @param (see Capybara::Node::Finders#has_link?)
282
279
  # @return [Boolean] Whether it doesn't exist
283
280
  #
284
- def has_no_link?(locator=nil, options={}, &optional_filter_block)
285
- locator, options = nil, locator if locator.is_a? Hash
281
+ def has_no_link?(locator = nil, **options, &optional_filter_block)
286
282
  has_no_selector?(:link, locator, options, &optional_filter_block)
287
283
  end
288
284
 
@@ -294,8 +290,7 @@ module Capybara
294
290
  # @param [String] locator The text, value or id of a button to check for
295
291
  # @return [Boolean] Whether it exists
296
292
  #
297
- def has_button?(locator=nil, options={}, &optional_filter_block)
298
- locator, options = nil, locator if locator.is_a? Hash
293
+ def has_button?(locator = nil, **options, &optional_filter_block)
299
294
  has_selector?(:button, locator, options, &optional_filter_block)
300
295
  end
301
296
 
@@ -307,8 +302,7 @@ module Capybara
307
302
  # @param [String] locator The text, value or id of a button to check for
308
303
  # @return [Boolean] Whether it doesn't exist
309
304
  #
310
- def has_no_button?(locator=nil, options={}, &optional_filter_block)
311
- locator, options = nil, locator if locator.is_a? Hash
305
+ def has_no_button?(locator = nil, **options, &optional_filter_block)
312
306
  has_no_selector?(:button, locator, options, &optional_filter_block)
313
307
  end
314
308
 
@@ -334,8 +328,7 @@ module Capybara
334
328
  # @option options [String] :type The type attribute of the field
335
329
  # @return [Boolean] Whether it exists
336
330
  #
337
- def has_field?(locator=nil, options={}, &optional_filter_block)
338
- locator, options = nil, locator if locator.is_a? Hash
331
+ def has_field?(locator = nil, **options, &optional_filter_block)
339
332
  has_selector?(:field, locator, options, &optional_filter_block)
340
333
  end
341
334
 
@@ -349,8 +342,7 @@ module Capybara
349
342
  # @option options [String] :type The type attribute of the field
350
343
  # @return [Boolean] Whether it doesn't exist
351
344
  #
352
- def has_no_field?(locator=nil, options={}, &optional_filter_block)
353
- locator, options = nil, locator if locator.is_a? Hash
345
+ def has_no_field?(locator = nil, **options, &optional_filter_block)
354
346
  has_no_selector?(:field, locator, options, &optional_filter_block)
355
347
  end
356
348
 
@@ -363,8 +355,7 @@ module Capybara
363
355
  # @param [String] locator The label, name or id of a checked field
364
356
  # @return [Boolean] Whether it exists
365
357
  #
366
- def has_checked_field?(locator=nil, options={}, &optional_filter_block)
367
- locator, options = nil, locator if locator.is_a? Hash
358
+ def has_checked_field?(locator = nil, **options, &optional_filter_block)
368
359
  has_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
369
360
  end
370
361
 
@@ -377,8 +368,7 @@ module Capybara
377
368
  # @param [String] locator The label, name or id of a checked field
378
369
  # @return [Boolean] Whether it doesn't exist
379
370
  #
380
- def has_no_checked_field?(locator=nil, options={}, &optional_filter_block)
381
- locator, options = nil, locator if locator.is_a? Hash
371
+ def has_no_checked_field?(locator = nil, **options, &optional_filter_block)
382
372
  has_no_selector?(:field, locator, options.merge(checked: true), &optional_filter_block)
383
373
  end
384
374
 
@@ -391,8 +381,7 @@ module Capybara
391
381
  # @param [String] locator The label, name or id of an unchecked field
392
382
  # @return [Boolean] Whether it exists
393
383
  #
394
- def has_unchecked_field?(locator=nil, options={}, &optional_filter_block)
395
- locator, options = nil, locator if locator.is_a? Hash
384
+ def has_unchecked_field?(locator = nil, **options, &optional_filter_block)
396
385
  has_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
397
386
  end
398
387
 
@@ -405,8 +394,7 @@ module Capybara
405
394
  # @param [String] locator The label, name or id of an unchecked field
406
395
  # @return [Boolean] Whether it doesn't exist
407
396
  #
408
- def has_no_unchecked_field?(locator=nil, options={}, &optional_filter_block)
409
- locator, options = nil, locator if locator.is_a? Hash
397
+ def has_no_unchecked_field?(locator = nil, **options, &optional_filter_block)
410
398
  has_no_selector?(:field, locator, options.merge(unchecked: true), &optional_filter_block)
411
399
  end
412
400
 
@@ -439,8 +427,7 @@ module Capybara
439
427
  # @option options [String, Array] :with_selected Partial set of options which should minimally be selected
440
428
  # @return [Boolean] Whether it exists
441
429
  #
442
- def has_select?(locator=nil, options={}, &optional_filter_block)
443
- locator, options = nil, locator if locator.is_a? Hash
430
+ def has_select?(locator = nil, **options, &optional_filter_block)
444
431
  has_selector?(:select, locator, options, &optional_filter_block)
445
432
  end
446
433
 
@@ -452,8 +439,7 @@ module Capybara
452
439
  # @param (see Capybara::Node::Matchers#has_select?)
453
440
  # @return [Boolean] Whether it doesn't exist
454
441
  #
455
- def has_no_select?(locator=nil, options={}, &optional_filter_block)
456
- locator, options = nil, locator if locator.is_a? Hash
442
+ def has_no_select?(locator = nil, **options, &optional_filter_block)
457
443
  has_no_selector?(:select, locator, options, &optional_filter_block)
458
444
  end
459
445
 
@@ -467,8 +453,7 @@ module Capybara
467
453
  # @param [String] locator The id or caption of a table
468
454
  # @return [Boolean] Whether it exist
469
455
  #
470
- def has_table?(locator=nil, options={}, &optional_filter_block)
471
- locator, options = nil, locator if locator.is_a? Hash
456
+ def has_table?(locator = nil, **options, &optional_filter_block)
472
457
  has_selector?(:table, locator, options, &optional_filter_block)
473
458
  end
474
459
 
@@ -480,8 +465,7 @@ module Capybara
480
465
  # @param (see Capybara::Node::Matchers#has_table?)
481
466
  # @return [Boolean] Whether it doesn't exist
482
467
  #
483
- def has_no_table?(locator=nil, options={}, &optional_filter_block)
484
- locator, options = nil, locator if locator.is_a? Hash
468
+ def has_no_table?(locator = nil, **options, &optional_filter_block)
485
469
  has_no_selector?(:table, locator, options, &optional_filter_block)
486
470
  end
487
471
 
@@ -534,7 +518,7 @@ module Capybara
534
518
  # @param [String, XPath::Expression] xpath The XPath expression to match against the current code
535
519
  # @return [Boolean]
536
520
  #
537
- def matches_xpath?(xpath, options={}, &optional_filter_block)
521
+ def matches_xpath?(xpath, **options, &optional_filter_block)
538
522
  matches_selector?(:xpath, xpath, options, &optional_filter_block)
539
523
  end
540
524
 
@@ -545,7 +529,7 @@ module Capybara
545
529
  # @param [String] css The CSS selector to match against the current code
546
530
  # @return [Boolean]
547
531
  #
548
- def matches_css?(css, options={}, &optional_filter_block)
532
+ def matches_css?(css, **options, &optional_filter_block)
549
533
  matches_selector?(:css, css, options, &optional_filter_block)
550
534
  end
551
535
 
@@ -570,7 +554,7 @@ module Capybara
570
554
  # @param [String, XPath::Expression] xpath The XPath expression to match against the current code
571
555
  # @return [Boolean]
572
556
  #
573
- def not_matches_xpath?(xpath, options={}, &optional_filter_block)
557
+ def not_matches_xpath?(xpath, **options, &optional_filter_block)
574
558
  not_matches_selector?(:xpath, xpath, options, &optional_filter_block)
575
559
  end
576
560
 
@@ -581,11 +565,10 @@ module Capybara
581
565
  # @param [String] css The CSS selector to match against the current code
582
566
  # @return [Boolean]
583
567
  #
584
- def not_matches_css?(css, options={}, &optional_filter_block)
568
+ def not_matches_css?(css, **options, &optional_filter_block)
585
569
  not_matches_selector?(:css, css, options, &optional_filter_block)
586
570
  end
587
571
 
588
-
589
572
  ##
590
573
  # Asserts that the page or current node has the given text content,
591
574
  # ignoring any HTML tags.
@@ -656,7 +639,7 @@ module Capybara
656
639
  def has_text?(*args)
657
640
  assert_text(*args)
658
641
  rescue Capybara::ExpectationNotMet
659
- return false
642
+ false
660
643
  end
661
644
  alias_method :has_content?, :has_text?
662
645
 
@@ -670,53 +653,49 @@ module Capybara
670
653
  def has_no_text?(*args)
671
654
  assert_no_text(*args)
672
655
  rescue Capybara::ExpectationNotMet
673
- return false
656
+ false
674
657
  end
675
658
  alias_method :has_no_content?, :has_no_text?
676
659
 
677
660
  def ==(other)
678
- self.eql?(other) || (other.respond_to?(:base) && base == other.base)
661
+ eql?(other) || (other.respond_to?(:base) && base == other.base)
679
662
  end
680
663
 
681
664
  private
682
665
 
683
- def _verify_selector_result(query_args, optional_filter_block, &result_block)
684
- _set_query_session_options(query_args)
666
+ def _verify_selector_result(query_args, optional_filter_block)
667
+ query_args = _set_query_session_options(*query_args)
685
668
  query = Capybara::Queries::SelectorQuery.new(*query_args, &optional_filter_block)
686
669
  synchronize(query.wait) do
687
670
  result = query.resolve_for(self)
688
- result_block.call(result, query)
671
+ yield result, query
689
672
  end
690
- return true
673
+ true
691
674
  end
692
675
 
693
- def _verify_match_result(query_args, optional_filter_block, &result_block)
694
- _set_query_session_options(query_args)
676
+ def _verify_match_result(query_args, optional_filter_block)
677
+ query_args = _set_query_session_options(*query_args)
695
678
  query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
696
679
  synchronize(query.wait) do
697
- result = query.resolve_for(self.query_scope)
698
- result_block.call(result)
680
+ result = query.resolve_for(query_scope)
681
+ yield result
699
682
  end
700
- return true
683
+ true
701
684
  end
702
685
 
703
686
  def _verify_text(query_args)
704
- _set_query_session_options(query_args)
687
+ query_args = _set_query_session_options(*query_args)
705
688
  query = Capybara::Queries::TextQuery.new(*query_args)
706
689
  synchronize(query.wait) do
707
690
  count = query.resolve_for(self)
708
691
  yield(count, query)
709
692
  end
710
- return true
693
+ true
711
694
  end
712
695
 
713
- def _set_query_session_options(query_args)
714
- if query_args.last.is_a? Hash
715
- query_args.last[:session_options] = session_options
716
- else
717
- query_args.push(session_options: session_options)
718
- end
719
- query_args
696
+ def _set_query_session_options(*query_args, **query_options)
697
+ query_options[:session_options] = session_options
698
+ query_args.push(query_options)
720
699
  end
721
700
  end
722
701
  end