capybara 3.16.1 → 3.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +321 -0
  4. data/README.md +51 -60
  5. data/lib/capybara.rb +71 -114
  6. data/lib/capybara/config.rb +8 -5
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/node.rb +15 -3
  9. data/lib/capybara/dsl.rb +10 -2
  10. data/lib/capybara/helpers.rb +5 -3
  11. data/lib/capybara/minitest.rb +242 -141
  12. data/lib/capybara/minitest/spec.rb +159 -90
  13. data/lib/capybara/node/actions.rb +85 -74
  14. data/lib/capybara/node/base.rb +4 -4
  15. data/lib/capybara/node/document.rb +2 -2
  16. data/lib/capybara/node/document_matchers.rb +3 -3
  17. data/lib/capybara/node/element.rb +216 -117
  18. data/lib/capybara/node/finders.rb +65 -65
  19. data/lib/capybara/node/matchers.rb +228 -126
  20. data/lib/capybara/node/simple.rb +9 -4
  21. data/lib/capybara/queries/ancestor_query.rb +5 -7
  22. data/lib/capybara/queries/base_query.rb +2 -1
  23. data/lib/capybara/queries/current_path_query.rb +1 -1
  24. data/lib/capybara/queries/selector_query.rb +296 -30
  25. data/lib/capybara/queries/sibling_query.rb +5 -4
  26. data/lib/capybara/queries/style_query.rb +2 -2
  27. data/lib/capybara/queries/text_query.rb +13 -1
  28. data/lib/capybara/queries/title_query.rb +1 -1
  29. data/lib/capybara/rack_test/browser.rb +7 -2
  30. data/lib/capybara/rack_test/driver.rb +1 -1
  31. data/lib/capybara/rack_test/form.rb +1 -1
  32. data/lib/capybara/rack_test/node.rb +43 -7
  33. data/lib/capybara/registration_container.rb +44 -0
  34. data/lib/capybara/registrations/drivers.rb +36 -0
  35. data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
  36. data/lib/capybara/registrations/servers.rb +44 -0
  37. data/lib/capybara/result.rb +36 -8
  38. data/lib/capybara/rspec/matcher_proxies.rb +6 -4
  39. data/lib/capybara/rspec/matchers.rb +100 -63
  40. data/lib/capybara/rspec/matchers/base.rb +23 -10
  41. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  42. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  43. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  44. data/lib/capybara/rspec/matchers/have_selector.rb +16 -8
  45. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  46. data/lib/capybara/rspec/matchers/have_text.rb +4 -4
  47. data/lib/capybara/rspec/matchers/have_title.rb +2 -2
  48. data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
  49. data/lib/capybara/rspec/matchers/match_style.rb +2 -2
  50. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  51. data/lib/capybara/selector.rb +219 -588
  52. data/lib/capybara/selector/builders/css_builder.rb +10 -6
  53. data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
  54. data/lib/capybara/selector/css.rb +4 -2
  55. data/lib/capybara/selector/definition.rb +277 -0
  56. data/lib/capybara/selector/definition/button.rb +52 -0
  57. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  58. data/lib/capybara/selector/definition/css.rb +10 -0
  59. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  60. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  61. data/lib/capybara/selector/definition/element.rb +27 -0
  62. data/lib/capybara/selector/definition/field.rb +40 -0
  63. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  64. data/lib/capybara/selector/definition/file_field.rb +13 -0
  65. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  66. data/lib/capybara/selector/definition/frame.rb +17 -0
  67. data/lib/capybara/selector/definition/id.rb +6 -0
  68. data/lib/capybara/selector/definition/label.rb +62 -0
  69. data/lib/capybara/selector/definition/link.rb +54 -0
  70. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  71. data/lib/capybara/selector/definition/option.rb +27 -0
  72. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  73. data/lib/capybara/selector/definition/select.rb +81 -0
  74. data/lib/capybara/selector/definition/table.rb +109 -0
  75. data/lib/capybara/selector/definition/table_row.rb +21 -0
  76. data/lib/capybara/selector/definition/xpath.rb +5 -0
  77. data/lib/capybara/selector/filter_set.rb +13 -9
  78. data/lib/capybara/selector/filters/base.rb +11 -2
  79. data/lib/capybara/selector/filters/locator_filter.rb +13 -3
  80. data/lib/capybara/selector/regexp_disassembler.rb +9 -2
  81. data/lib/capybara/selector/selector.rb +43 -448
  82. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  83. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  84. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  85. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  86. data/lib/capybara/selenium/driver.rb +125 -56
  87. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +73 -17
  88. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
  89. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +41 -2
  90. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +14 -1
  91. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +14 -5
  92. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  93. data/lib/capybara/selenium/extensions/find.rb +67 -45
  94. data/lib/capybara/selenium/extensions/html5_drag.rb +152 -36
  95. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  96. data/lib/capybara/selenium/logger_suppressor.rb +34 -0
  97. data/lib/capybara/selenium/node.rb +227 -56
  98. data/lib/capybara/selenium/nodes/chrome_node.rb +93 -8
  99. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  100. data/lib/capybara/selenium/nodes/firefox_node.rb +37 -59
  101. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  102. data/lib/capybara/selenium/nodes/safari_node.rb +27 -54
  103. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  104. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  105. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  106. data/lib/capybara/selenium/patches/logs.rb +45 -0
  107. data/lib/capybara/server.rb +19 -3
  108. data/lib/capybara/server/animation_disabler.rb +2 -2
  109. data/lib/capybara/server/checker.rb +6 -2
  110. data/lib/capybara/server/middleware.rb +23 -13
  111. data/lib/capybara/session.rb +124 -106
  112. data/lib/capybara/session/config.rb +12 -10
  113. data/lib/capybara/session/matchers.rb +6 -6
  114. data/lib/capybara/spec/public/offset.js +6 -0
  115. data/lib/capybara/spec/public/test.js +94 -5
  116. data/lib/capybara/spec/session/all_spec.rb +84 -6
  117. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  118. data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
  119. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  120. data/lib/capybara/spec/session/attach_file_spec.rb +14 -6
  121. data/lib/capybara/spec/session/check_spec.rb +10 -4
  122. data/lib/capybara/spec/session/choose_spec.rb +8 -2
  123. data/lib/capybara/spec/session/click_button_spec.rb +44 -1
  124. data/lib/capybara/spec/session/click_link_spec.rb +11 -0
  125. data/lib/capybara/spec/session/evaluate_script_spec.rb +12 -0
  126. data/lib/capybara/spec/session/fill_in_spec.rb +37 -2
  127. data/lib/capybara/spec/session/find_spec.rb +60 -6
  128. data/lib/capybara/spec/session/first_spec.rb +1 -1
  129. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
  130. data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
  131. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  132. data/lib/capybara/spec/session/has_button_spec.rb +16 -0
  133. data/lib/capybara/spec/session/has_css_spec.rb +35 -6
  134. data/lib/capybara/spec/session/has_current_path_spec.rb +6 -4
  135. data/lib/capybara/spec/session/has_field_spec.rb +34 -0
  136. data/lib/capybara/spec/session/has_select_spec.rb +32 -4
  137. data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
  138. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  139. data/lib/capybara/spec/session/has_table_spec.rb +51 -5
  140. data/lib/capybara/spec/session/has_text_spec.rb +47 -0
  141. data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
  142. data/lib/capybara/spec/session/node_spec.rb +574 -16
  143. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  144. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  145. data/lib/capybara/spec/session/scroll_spec.rb +1 -1
  146. data/lib/capybara/spec/session/select_spec.rb +5 -10
  147. data/lib/capybara/spec/session/selectors_spec.rb +24 -3
  148. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  149. data/lib/capybara/spec/session/unselect_spec.rb +1 -1
  150. data/lib/capybara/spec/session/window/window_spec.rb +10 -9
  151. data/lib/capybara/spec/spec_helper.rb +7 -2
  152. data/lib/capybara/spec/test_app.rb +26 -21
  153. data/lib/capybara/spec/views/animated.erb +49 -0
  154. data/lib/capybara/spec/views/form.erb +25 -4
  155. data/lib/capybara/spec/views/frame_child.erb +2 -1
  156. data/lib/capybara/spec/views/frame_one.erb +1 -0
  157. data/lib/capybara/spec/views/obscured.erb +9 -9
  158. data/lib/capybara/spec/views/offset.erb +32 -0
  159. data/lib/capybara/spec/views/react.erb +45 -0
  160. data/lib/capybara/spec/views/spatial.erb +31 -0
  161. data/lib/capybara/spec/views/with_animation.erb +29 -1
  162. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  163. data/lib/capybara/spec/views/with_html.erb +28 -2
  164. data/lib/capybara/spec/views/with_js.erb +2 -1
  165. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  166. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  167. data/lib/capybara/version.rb +1 -1
  168. data/lib/capybara/window.rb +10 -10
  169. data/spec/basic_node_spec.rb +6 -6
  170. data/spec/capybara_spec.rb +28 -28
  171. data/spec/dsl_spec.rb +16 -3
  172. data/spec/filter_set_spec.rb +5 -5
  173. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  174. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  175. data/spec/minitest_spec.rb +12 -2
  176. data/spec/minitest_spec_spec.rb +56 -45
  177. data/spec/rack_test_spec.rb +25 -12
  178. data/spec/regexp_dissassembler_spec.rb +53 -39
  179. data/spec/result_spec.rb +50 -54
  180. data/spec/rspec/features_spec.rb +1 -0
  181. data/spec/rspec/shared_spec_matchers.rb +78 -62
  182. data/spec/rspec_spec.rb +5 -5
  183. data/spec/sauce_spec_chrome.rb +1 -0
  184. data/spec/selector_spec.rb +26 -16
  185. data/spec/selenium_spec_chrome.rb +84 -5
  186. data/spec/selenium_spec_chrome_remote.rb +23 -8
  187. data/spec/selenium_spec_edge.rb +23 -8
  188. data/spec/selenium_spec_firefox.rb +16 -21
  189. data/spec/selenium_spec_firefox_remote.rb +4 -13
  190. data/spec/selenium_spec_ie.rb +23 -15
  191. data/spec/selenium_spec_safari.rb +17 -17
  192. data/spec/server_spec.rb +87 -42
  193. data/spec/session_spec.rb +11 -4
  194. data/spec/shared_selenium_node.rb +83 -0
  195. data/spec/shared_selenium_session.rb +62 -72
  196. data/spec/spec_helper.rb +43 -5
  197. metadata +114 -16
@@ -5,6 +5,7 @@ require 'nokogiri'
5
5
  require 'xpath'
6
6
  require 'forwardable'
7
7
  require 'capybara/config'
8
+ require 'capybara/registration_container'
8
9
 
9
10
  module Capybara
10
11
  class CapybaraError < StandardError; end
@@ -66,36 +67,47 @@ module Capybara
66
67
  # config.app_host = 'http://www.google.com'
67
68
  # end
68
69
  #
69
- # === Configurable options
70
- #
71
- # [app_host = String/nil] The default host to use when giving a relative URL to visit, must be a valid URL e.g. http://www.example.com
72
- # [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL unless another port is explicitly specified (Default: false)
73
- # [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
74
- # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
75
- # [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
76
- # [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [Exception])
77
- # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
78
- # [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
79
- # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
80
- # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
81
- # [save_path = String] Where to put pages saved through save_(page|screenshot), save_and_open_(page|screenshot) (Default: Dir.pwd)
82
- # [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
83
- # [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
84
- # [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
85
- # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
86
- # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
87
- # [default_set_options = Hash] The default options passed to Node::set (Default: {})
88
- # [test_id = Symbol/String/nil] Optional attribute to match locator aginst with builtin selectors along with id (Default: nil)
89
- # [predicates_wait = Boolean] Whether Capybaras predicate matchers use waiting behavior by default (Default: true)
90
- # [default_normalize_ws = Boolean] Whether text predicates and matchers use normalize whitespace behaviour (Default: false)
91
- # [allow_gumbo = Boolean] When `nokogumbo` is available, whether it will be used to parse HTML strings (Default: false)
92
- #
93
- # === DSL Options
94
- #
95
- # when using capybara/dsl, the following options are also available:
96
- #
97
- # [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
98
- # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
70
+ # #### Configurable options
71
+ #
72
+ # - **allow_gumbo** (Boolean = `false`) - When `nokogumbo` is available, whether it will be used to parse HTML strings.
73
+ # - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
74
+ # unless another port is explicitly specified.
75
+ # - **app_host** (String, `nil`) - The default host to use when giving a relative URL to visit, must be a valid URL e.g. `http://www.example.com`.
76
+ # - **asset_host** (String = `nil`) - Where dynamic assets are hosted - will be prepended to relative asset locations if present.
77
+ # - **automatic_label_click** (Boolean = `false`) - Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check},
78
+ # {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated `<label>` element if the checkbox/radio button are non-visible.
79
+ # - **automatic_reload** (Boolean = `true`) - Whether to automatically reload elements as Capybara is waiting.
80
+ # - **default_max_wait_time** (Numeric = `2`) - The maximum number of seconds to wait for asynchronous processes to finish.
81
+ # - **default_normalize_ws** (Boolean = `false`) - Whether text predicates and matchers use normalize whitespace behavior.
82
+ # - **default_selector** (`:css`, `:xpath` = `:css`) - Methods which take a selector use the given type by default. See also {Capybara::Selector}.
83
+ # - **default_set_options** (Hash = `{}`) - The default options passed to {Capybara::Node::Element#set Element#set}.
84
+ # - **enable_aria_label** (Boolean = `false`) - Whether fields, links, and buttons will match against `aria-label` attribute.
85
+ # - **enable_aria_role** (Boolean = `false`) - Selectors will check for relevant aria role (currently only `button`).
86
+ # - **exact** (Boolean = `false`) - Whether locators are matched exactly or with substrings. Only affects selector conditions
87
+ # written using the `XPath#is` method.
88
+ # - **exact_text** (Boolean = `false`) - Whether the text matchers and `:text` filter match exactly or on substrings.
89
+ # - **ignore_hidden_elements** (Boolean = `true`) - Whether to ignore hidden elements on the page.
90
+ # - **match** (`:one`, `:first`, `:prefer_exact`, `:smart` = `:smart`) - The matching strategy to find nodes.
91
+ # - **predicates_wait** (Boolean = `true`) - Whether Capybara's predicate matchers use waiting behavior by default.
92
+ # - **raise_server_errors** (Boolean = `true`) - Should errors raised in the server be raised in the tests?
93
+ # - **reuse_server** (Boolean = `true`) - Whether to reuse the server thread between multiple sessions using the same app object.
94
+ # - **run_server** (Boolean = `true`) - Whether to start a Rack server for the given Rack app.
95
+ # - **save_path** (String = `Dir.pwd`) - Where to put pages saved through {Capybara::Session#save_page save_page}, {Capybara::Session#save_screenshot save_screenshot},
96
+ # {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
97
+ # - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
98
+ # - **server_port** (Integer) - The port Capybara will run the application server on, if not specified a random port will be used.
99
+ # - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
100
+ # and {configure raise_server_errors} is `true`.
101
+ # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
102
+ # - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually.
103
+ # - **w3c_click_offset** (Boolean = 'false') - Whether click offsets should be from element center (true) or top left (false)
104
+ #
105
+ # #### DSL Options
106
+ #
107
+ # When using `capybara/dsl`, the following options are also available:
108
+ #
109
+ # - **default_driver** (Symbol = `:rack_test`) - The name of the driver to use by default.
110
+ # - **javascript_driver** (Symbol = `:selenium`) - The name of a driver to use for JavaScript enabled tests.
99
111
  #
100
112
  def configure
101
113
  yield config
@@ -115,7 +127,7 @@ module Capybara
115
127
  # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
116
128
  #
117
129
  def register_driver(name, &block)
118
- drivers[name] = block
130
+ drivers.send(:register, name, block)
119
131
  end
120
132
 
121
133
  ##
@@ -134,7 +146,7 @@ module Capybara
134
146
  # @yieldparam host The host/ip to bind to
135
147
  #
136
148
  def register_server(name, &block)
137
- servers[name.to_sym] = block
149
+ servers.send(:register, name.to_sym, block)
138
150
  end
139
151
 
140
152
  ##
@@ -188,11 +200,11 @@ module Capybara
188
200
  end
189
201
 
190
202
  def drivers
191
- @drivers ||= {}
203
+ @drivers ||= RegistrationContainer.new
192
204
  end
193
205
 
194
206
  def servers
195
- @servers ||= {}
207
+ @servers ||= RegistrationContainer.new
196
208
  end
197
209
 
198
210
  # Wraps the given string, which should contain an HTML document or fragment
@@ -201,15 +213,13 @@ module Capybara
201
213
  # any string containing HTML in the exact same way you would query the current document in a Capybara
202
214
  # session.
203
215
  #
204
- # Example: A single element
205
- #
216
+ # @example A single element
206
217
  # node = Capybara.string('<a href="foo">bar</a>')
207
218
  # anchor = node.first('a')
208
219
  # anchor[:href] #=> 'foo'
209
220
  # anchor.text #=> 'bar'
210
221
  #
211
- # Example: Multiple elements
212
- #
222
+ # @example Multiple elements
213
223
  # node = Capybara.string <<-HTML
214
224
  # <ul>
215
225
  # <li id="home">Home</li>
@@ -297,7 +307,7 @@ module Capybara
297
307
 
298
308
  ##
299
309
  #
300
- # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver
310
+ # The current {Capybara::Session} based on what is set as {app} and {current_driver}.
301
311
  #
302
312
  # @return [Capybara::Session] The currently used session
303
313
  #
@@ -340,9 +350,10 @@ module Capybara
340
350
 
341
351
  ##
342
352
  #
343
- # Yield a block using a specific session name or Capybara::Session instance.
353
+ # Yield a block using a specific session name or {Capybara::Session} instance.
344
354
  #
345
- def using_session(name_or_session)
355
+ def using_session(name_or_session, &block)
356
+ previous_session = current_session
346
357
  previous_session_info = {
347
358
  specified_session: specified_session,
348
359
  session_name: session_name,
@@ -355,7 +366,12 @@ module Capybara
355
366
  else
356
367
  self.session_name = name_or_session
357
368
  end
358
- yield
369
+
370
+ if block.arity.zero?
371
+ yield
372
+ else
373
+ yield current_session, previous_session
374
+ end
359
375
  ensure
360
376
  self.session_name, self.specified_session = previous_session_info.values_at(:session_name, :specified_session)
361
377
  self.current_driver, self.app = previous_session_info.values_at(:current_driver, :app) if threadsafe
@@ -371,6 +387,10 @@ module Capybara
371
387
  def HTML(html) # rubocop:disable Naming/MethodName
372
388
  if Nokogiri.respond_to?(:HTML5) && Capybara.allow_gumbo # Nokogumbo installed and allowed for use
373
389
  Nokogiri::HTML5(html).tap do |document|
390
+ document.xpath('//template').each do |template|
391
+ # template elements content is not part of the document
392
+ template.inner_html = ''
393
+ end
374
394
  document.xpath('//textarea').each do |textarea|
375
395
  # The Nokogumbo HTML5 parser already returns spec compliant contents
376
396
  textarea['_capybara_raw_value'] = textarea.content
@@ -378,8 +398,12 @@ module Capybara
378
398
  end
379
399
  else
380
400
  Nokogiri::HTML(html).tap do |document|
401
+ document.xpath('//template').each do |template|
402
+ # template elements content is not part of the document
403
+ template.inner_html = ''
404
+ end
381
405
  document.xpath('//textarea').each do |textarea|
382
- textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/, '')
406
+ textarea['_capybara_raw_value'] = textarea.content.delete_prefix("\n")
383
407
  end
384
408
  end
385
409
  end
@@ -466,42 +490,8 @@ module Capybara
466
490
  require 'capybara/selenium/driver'
467
491
  end
468
492
 
469
- Capybara.register_server :default do |app, port, _host|
470
- Capybara.run_default_server(app, port)
471
- end
472
-
473
- Capybara.register_server :webrick do |app, port, host, **options|
474
- require 'rack/handler/webrick'
475
- options = { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options)
476
- Rack::Handler::WEBrick.run(app, options)
477
- end
478
-
479
- Capybara.register_server :puma do |app, port, host, **options|
480
- begin
481
- require 'rack/handler/puma'
482
- rescue LoadError
483
- raise LoadError, 'Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`.'
484
- else
485
- unless Rack::Handler::Puma.respond_to?(:config)
486
- raise LoadError, 'Capybara requires `puma` version 3.8.0 or higher, please upgrade `puma` or register and specify your own server block'
487
- end
488
- end
489
- # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
490
- # Therefore construct and run the Server instance ourselves.
491
- # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
492
- options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }.merge(options)
493
- conf = Rack::Handler::Puma.config(app, options)
494
- events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
495
-
496
- events.log 'Capybara starting Puma...'
497
- events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
498
- events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
499
-
500
- Puma::Server.new(conf.app, events, conf.options).tap do |s|
501
- s.binder.parse conf.options[:binds], s.events
502
- s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
503
- end.run.join
504
- end
493
+ require 'capybara/registrations/servers'
494
+ require 'capybara/registrations/drivers'
505
495
 
506
496
  Capybara.configure do |config|
507
497
  config.always_include_port = false
@@ -520,45 +510,12 @@ Capybara.configure do |config|
520
510
  config.visible_text_only = false
521
511
  config.automatic_label_click = false
522
512
  config.enable_aria_label = false
513
+ config.enable_aria_role = false
523
514
  config.reuse_server = true
524
515
  config.default_set_options = {}
525
516
  config.test_id = nil
526
517
  config.predicates_wait = true
527
518
  config.default_normalize_ws = false
528
519
  config.allow_gumbo = false
529
- end
530
-
531
- Capybara.register_driver :rack_test do |app|
532
- Capybara::RackTest::Driver.new(app)
533
- end
534
-
535
- Capybara.register_driver :selenium do |app|
536
- Capybara::Selenium::Driver.new(app)
537
- end
538
-
539
- Capybara.register_driver :selenium_headless do |app|
540
- Capybara::Selenium::Driver.load_selenium
541
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
542
- browser_options.args << '-headless'
543
- Capybara::Selenium::Driver.new(app, browser: :firefox, options: browser_options)
544
- end
545
-
546
- Capybara.register_driver :selenium_chrome do |app|
547
- Capybara::Selenium::Driver.load_selenium
548
- browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
549
- # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
550
- opts.args << '--disable-site-isolation-trials'
551
- end
552
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
553
- end
554
-
555
- Capybara.register_driver :selenium_chrome_headless do |app|
556
- Capybara::Selenium::Driver.load_selenium
557
- browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
558
- opts.args << '--headless'
559
- opts.args << '--disable-gpu' if Gem.win_platform?
560
- # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
561
- opts.args << '--disable-site-isolation-trials'
562
- end
563
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
520
+ config.w3c_click_offset = false
564
521
  end
@@ -7,8 +7,7 @@ module Capybara
7
7
  class Config
8
8
  extend Forwardable
9
9
 
10
- OPTIONS = %i[app reuse_server threadsafe default_wait_time server
11
- default_driver javascript_driver allow_gumbo].freeze
10
+ OPTIONS = %i[app reuse_server threadsafe server default_driver javascript_driver allow_gumbo].freeze
12
11
 
13
12
  attr_accessor :app
14
13
  attr_reader :reuse_server, :threadsafe
@@ -28,7 +27,9 @@ module Capybara
28
27
  attr_writer :reuse_server
29
28
 
30
29
  def threadsafe=(bool)
31
- raise 'Threadsafe setting cannot be changed once a session is created' if (bool != threadsafe) && Session.instance_created?
30
+ if (bool != threadsafe) && Session.instance_created?
31
+ raise 'Threadsafe setting cannot be changed once a session is created'
32
+ end
32
33
 
33
34
  @threadsafe = bool
34
35
  end
@@ -60,7 +61,7 @@ module Capybara
60
61
  @server = if name.respond_to? :call
61
62
  name
62
63
  elsif options
63
- proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, options) }
64
+ proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, **options) }
64
65
  else
65
66
  Capybara.servers[name.to_sym]
66
67
  end
@@ -84,7 +85,9 @@ module Capybara
84
85
 
85
86
  def deprecate(method, alternate_method, once = false)
86
87
  @deprecation_notified ||= {}
87
- warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once && @deprecation_notified[method]
88
+ unless once && @deprecation_notified[method]
89
+ warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead"
90
+ end
88
91
  @deprecation_notified[method] = true
89
92
  end
90
93
  end
@@ -22,6 +22,6 @@ end
22
22
  Before do |scenario|
23
23
  scenario.source_tag_names.each do |tag|
24
24
  driver_name = tag.sub(/^@/, '').to_sym
25
- Capybara.current_driver = driver_name if Capybara.drivers.key?(driver_name)
25
+ Capybara.current_driver = driver_name if Capybara.drivers[driver_name]
26
26
  end
27
27
  end
@@ -31,8 +31,8 @@ module Capybara
31
31
  raise NotImplementedError
32
32
  end
33
33
 
34
- # @param value String or Array. Array is only allowed if node has 'multiple' attribute
35
- # @param options [Hash{}] Driver specific options for how to set a value on a node
34
+ # @param value [String, Array] Array is only allowed if node has 'multiple' attribute
35
+ # @param options [Hash] Driver specific options for how to set a value on a node
36
36
  def set(value, **options)
37
37
  raise NotImplementedError
38
38
  end
@@ -65,7 +65,11 @@ module Capybara
65
65
  raise NotImplementedError
66
66
  end
67
67
 
68
- def drag_to(element)
68
+ def drag_to(element, **options)
69
+ raise NotImplementedError
70
+ end
71
+
72
+ def drop(*args)
69
73
  raise NotImplementedError
70
74
  end
71
75
 
@@ -85,6 +89,10 @@ module Capybara
85
89
  raise NotImplementedError
86
90
  end
87
91
 
92
+ def obscured?
93
+ raise NotImplementedError
94
+ end
95
+
88
96
  def checked?
89
97
  raise NotImplementedError
90
98
  end
@@ -105,6 +113,10 @@ module Capybara
105
113
  !!self[:multiple]
106
114
  end
107
115
 
116
+ def rect
117
+ raise NotSupportedByDriverError, 'Capybara::Driver::Node#rect'
118
+ end
119
+
108
120
  def path
109
121
  raise NotSupportedByDriverError, 'Capybara::Driver::Node#path'
110
122
  end
@@ -47,8 +47,16 @@ module Capybara
47
47
  end
48
48
 
49
49
  Session::DSL_METHODS.each do |method|
50
- define_method method do |*args, &block|
51
- page.send method, *args, &block
50
+ if RUBY_VERSION >= '2.7'
51
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
52
+ def #{method}(...)
53
+ page.method("#{method}").call(...)
54
+ end
55
+ METHOD
56
+ else
57
+ define_method method do |*args, &block|
58
+ page.send method, *args, &block
59
+ end
52
60
  end
53
61
  end
54
62
  end
@@ -3,7 +3,7 @@
3
3
  module Capybara
4
4
  # @api private
5
5
  module Helpers
6
- module_function # rubocop:disable Layout/IndentationWidth
6
+ module_function
7
7
 
8
8
  ##
9
9
  # @deprecated
@@ -41,7 +41,7 @@ module Capybara
41
41
  ##
42
42
  #
43
43
  # Injects a `<base>` tag into the given HTML code, pointing to
44
- # `Capybara.asset_host`.
44
+ # {Capybara.configure asset_host}.
45
45
  #
46
46
  # @param [String] html HTML code to inject into
47
47
  # @param [URL] host (Capybara.asset_host) The host from which assets should be loaded
@@ -87,7 +87,9 @@ module Capybara
87
87
  end
88
88
 
89
89
  def expired?
90
- raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead' if stalled?
90
+ if stalled?
91
+ raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead'
92
+ end
91
93
 
92
94
  current - @start >= @expire_in
93
95
  end
@@ -6,48 +6,54 @@ require 'capybara/dsl'
6
6
  module Capybara
7
7
  module Minitest
8
8
  module Assertions
9
- ## Assert text exists
9
+ ##
10
+ # Assert text exists
10
11
  #
12
+ # @!method assert_content
11
13
  # @!method assert_text
12
- # see {Capybara::Node::Matchers#assert_text}
14
+ # See {Capybara::Node::Matchers#assert_text}
13
15
 
14
- ## Assert text does not exist
16
+ ##
17
+ # Assert text does not exist
15
18
  #
19
+ # @!method refute_content
20
+ # @!method assert_no_content
21
+ # @!method refute_text
16
22
  # @!method assert_no_text
17
- # see {Capybara::Node::Matchers#assert_no_text}
23
+ # See {Capybara::Node::Matchers#assert_no_text}
18
24
 
19
25
  ##
20
26
  # Assertion that page title does match
21
27
  #
22
28
  # @!method assert_title
23
- # see {Capybara::Node::DocumentMatchers#assert_title}
29
+ # See {Capybara::Node::DocumentMatchers#assert_title}
24
30
 
25
31
  ##
26
32
  # Assertion that page title does not match
27
33
  #
28
34
  # @!method refute_title
29
35
  # @!method assert_no_title
30
- # see {Capybara::Node::DocumentMatchers#assert_no_title}
36
+ # See {Capybara::Node::DocumentMatchers#assert_no_title}
31
37
 
32
38
  ##
33
39
  # Assertion that current path matches
34
40
  #
35
41
  # @!method assert_current_path
36
- # see {Capybara::SessionMatchers#assert_current_path}
42
+ # See {Capybara::SessionMatchers#assert_current_path}
37
43
 
38
44
  ##
39
45
  # Assertion that current page does not match
40
46
  #
41
47
  # @!method refute_current_path
42
48
  # @!method assert_no_current_path
43
- # see {Capybara::SessionMatchers#assert_no_current_path}
49
+ # See {Capybara::SessionMatchers#assert_no_current_path}
44
50
 
45
51
  %w[text no_text title no_title current_path no_current_path].each do |assertion_name|
46
52
  class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
47
- def assert_#{assertion_name} *args
53
+ def assert_#{assertion_name}(*args, **kwargs)
48
54
  self.assertions +=1
49
55
  subject, args = determine_subject(args)
50
- subject.assert_#{assertion_name}(*args)
56
+ subject.assert_#{assertion_name}(*args, **kwargs)
51
57
  rescue Capybara::ExpectationNotMet => e
52
58
  raise ::Minitest::Assertion, e.message
53
59
  end
@@ -61,34 +67,86 @@ module Capybara
61
67
  alias_method :assert_content, :assert_text
62
68
  alias_method :assert_no_content, :refute_text
63
69
 
64
- ## Assert selector exists on page
70
+ ##
71
+ # Assert selector exists on page
65
72
  #
66
73
  # @!method assert_selector
67
- # see {Capybara::Node::Matchers#assert_selector}
74
+ # See {Capybara::Node::Matchers#assert_selector}
68
75
 
69
- ## Assert selector does not exist on page
76
+ ##
77
+ # Assert selector does not exist on page
70
78
  #
79
+ # @!method refute_selector
71
80
  # @!method assert_no_selector
72
- # see {Capybara::Node::Matchers#assert_no_selector}
81
+ # See {Capybara::Node::Matchers#assert_no_selector}
73
82
 
74
- ## Assert element matches selector
83
+ ##
84
+ # Assert element matches selector
75
85
  #
76
86
  # @!method assert_matches_selector
77
- # see {Capybara::Node::Matchers#assert_matches_selector}
87
+ # See {Capybara::Node::Matchers#assert_matches_selector}
78
88
 
79
- ## Assert element does not match selector
89
+ ##
90
+ # Assert element does not match selector
80
91
  #
81
- # @!method assert_xpath
82
- # see {Capybara::Node::Matchers#assert_not_matches_selector}
92
+ # @!method refute_matches_selector
93
+ # @!method assert_not_matches_selector
94
+ # See {Capybara::Node::Matchers#assert_not_matches_selector}
83
95
 
84
- ## Assert element has the provided CSS styles
96
+ ##
97
+ # Assert all of the provided selectors exist on page
98
+ #
99
+ # @!method assert_all_of_selectors
100
+ # See {Capybara::Node::Matchers#assert_all_of_selectors}
101
+
102
+ ##
103
+ # Assert none of the provided selectors exist on page
104
+ #
105
+ # @!method assert_none_of_selectors
106
+ # See {Capybara::Node::Matchers#assert_none_of_selectors}
107
+
108
+ ##
109
+ # Assert any of the provided selectors exist on page
110
+ #
111
+ # @!method assert_any_of_selectors
112
+ # See {Capybara::Node::Matchers#assert_any_of_selectors}
113
+
114
+ ##
115
+ # Assert element has the provided CSS styles
85
116
  #
86
117
  # @!method assert_matches_style
87
- # see {Capybara::Node::Matchers#assert_matches_style}
118
+ # See {Capybara::Node::Matchers#assert_matches_style}
119
+
120
+ ##
121
+ # Assert element has a matching sibling
122
+ #
123
+ # @!method assert_sibling
124
+ # See {Capybara::Node::Matchers#assert_sibling}
125
+
126
+ ##
127
+ # Assert element does not have a matching sibling
128
+ #
129
+ # @!method refute_sibling
130
+ # @!method assert_no_sibling
131
+ # See {Capybara::Node::Matchers#assert_no_sibling}
132
+
133
+ ##
134
+ # Assert element has a matching ancestor
135
+ #
136
+ # @!method assert_ancestor
137
+ # See {Capybara::Node::Matchers#assert_ancestor}
138
+
139
+ ##
140
+ # Assert element does not have a matching ancestor
141
+ #
142
+ # @!method refute_ancestor
143
+ # @!method assert_no_ancestor
144
+ # See {Capybara::Node::Matchers#assert_no_ancestor}
88
145
 
89
146
  %w[selector no_selector matches_style
90
147
  all_of_selectors none_of_selectors any_of_selectors
91
- matches_selector not_matches_selector].each do |assertion_name|
148
+ matches_selector not_matches_selector
149
+ sibling no_sibling ancestor no_ancestor].each do |assertion_name|
92
150
  class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
93
151
  def assert_#{assertion_name} *args, &optional_filter_block
94
152
  self.assertions +=1
@@ -98,23 +156,145 @@ module Capybara
98
156
  raise ::Minitest::Assertion, e.message
99
157
  end
100
158
  ASSERTION
159
+ ruby2_keywords "assert_#{assertion_name}" if respond_to?(:ruby2_keywords)
101
160
  end
102
161
 
103
162
  alias_method :refute_selector, :assert_no_selector
104
163
  alias_method :refute_matches_selector, :assert_not_matches_selector
164
+ alias_method :refute_ancestor, :assert_no_ancestor
165
+ alias_method :refute_sibling, :assert_no_sibling
166
+
167
+ ##
168
+ # Assert that provided xpath exists
169
+ #
170
+ # @!method assert_xpath
171
+ # See {Capybara::Node::Matchers#has_xpath?}
172
+
173
+ ##
174
+ # Assert that provide xpath does not exist
175
+ #
176
+ # @!method refute_xpath
177
+ # @!method assert_no_xpath
178
+ # See {Capybara::Node::Matchers#has_no_xpath?}
179
+
180
+ ##
181
+ # Assert that provided css exists
182
+ #
183
+ # @!method assert_css
184
+ # See {Capybara::Node::Matchers#has_css?}
185
+
186
+ ##
187
+ # Assert that provided css does not exist
188
+ #
189
+ # @!method refute_css
190
+ # @!method assert_no_css
191
+ # See {Capybara::Node::Matchers#has_no_css?}
192
+
193
+ ##
194
+ # Assert that provided link exists
195
+ #
196
+ # @!method assert_link
197
+ # See {Capybara::Node::Matchers#has_link?}
198
+
199
+ ##
200
+ # Assert that provided link does not exist
201
+ #
202
+ # @!method assert_no_link
203
+ # @!method refute_link
204
+ # See {Capybara::Node::Matchers#has_no_link?}
205
+
206
+ ##
207
+ # Assert that provided button exists
208
+ #
209
+ # @!method assert_button
210
+ # See {Capybara::Node::Matchers#has_button?}
211
+
212
+ ##
213
+ # Assert that provided button does not exist
214
+ #
215
+ # @!method refute_button
216
+ # @!method assert_no_button
217
+ # See {Capybara::Node::Matchers#has_no_button?}
218
+
219
+ ##
220
+ # Assert that provided field exists
221
+ #
222
+ # @!method assert_field
223
+ # See {Capybara::Node::Matchers#has_field?}
224
+
225
+ ##
226
+ # Assert that provided field does not exist
227
+ #
228
+ # @!method refute_field
229
+ # @!method assert_no_field
230
+ # See {Capybara::Node::Matchers#has_no_field?}
231
+
232
+ ##
233
+ # Assert that provided checked field exists
234
+ #
235
+ # @!method assert_checked_field
236
+ # See {Capybara::Node::Matchers#has_checked_field?}
237
+
238
+ ##
239
+ # Assert that provided checked_field does not exist
240
+ #
241
+ # @!method assert_no_checked_field
242
+ # @!method refute_checked_field
243
+ # See {Capybara::Node::Matchers#has_no_checked_field?}
244
+
245
+ ##
246
+ # Assert that provided unchecked field exists
247
+ #
248
+ # @!method assert_unchecked_field
249
+ # See {Capybara::Node::Matchers#has_unchecked_field?}
250
+
251
+ ##
252
+ # Assert that provided unchecked field does not exist
253
+ #
254
+ # @!method assert_no_unchecked_field
255
+ # @!method refute_unchecked_field
256
+ # See {Capybara::Node::Matchers#has_no_unchecked_field?}
257
+
258
+ ##
259
+ # Assert that provided select exists
260
+ #
261
+ # @!method assert_select
262
+ # See {Capybara::Node::Matchers#has_select?}
263
+
264
+ ##
265
+ # Assert that provided select does not exist
266
+ #
267
+ # @!method refute_select
268
+ # @!method assert_no_select
269
+ # See {Capybara::Node::Matchers#has_no_select?}
270
+
271
+ ##
272
+ # Assert that provided table exists
273
+ #
274
+ # @!method assert_table
275
+ # See {Capybara::Node::Matchers#has_table?}
276
+
277
+ ##
278
+ # Assert that provided table does not exist
279
+ #
280
+ # @!method refute_table
281
+ # @!method assert_no_table
282
+ # See {Capybara::Node::Matchers#has_no_table?}
105
283
 
106
284
  %w[xpath css link button field select table].each do |selector_type|
107
285
  define_method "assert_#{selector_type}" do |*args, &optional_filter_block|
108
286
  subject, args = determine_subject(args)
109
287
  locator, options = extract_locator(args)
110
- assert_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
288
+ assert_selector(subject, selector_type.to_sym, locator, **options, &optional_filter_block)
111
289
  end
290
+ ruby2_keywords "assert_#{selector_type}" if respond_to?(:ruby2_keywords)
112
291
 
113
292
  define_method "assert_no_#{selector_type}" do |*args, &optional_filter_block|
114
293
  subject, args = determine_subject(args)
115
294
  locator, options = extract_locator(args)
116
- assert_no_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
295
+ assert_no_selector(subject, selector_type.to_sym, locator, **options, &optional_filter_block)
117
296
  end
297
+ ruby2_keywords "assert_no_#{selector_type}" if respond_to?(:ruby2_keywords)
118
298
  alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
119
299
  end
120
300
 
@@ -122,145 +302,66 @@ module Capybara
122
302
  define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
123
303
  subject, args = determine_subject(args)
124
304
  locator, options = extract_locator(args)
125
- assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
305
+ assert_selector(subject, :field, locator, **options.merge(field_type.to_sym => true), &optional_filter_block)
126
306
  end
307
+ ruby2_keywords "assert_#{field_type}_field" if respond_to?(:ruby2_keywords)
127
308
 
128
309
  define_method "assert_no_#{field_type}_field" do |*args, &optional_filter_block|
129
310
  subject, args = determine_subject(args)
130
311
  locator, options = extract_locator(args)
131
- assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
312
+ assert_no_selector(
313
+ subject,
314
+ :field,
315
+ locator,
316
+ **options.merge(field_type.to_sym => true),
317
+ &optional_filter_block
318
+ )
132
319
  end
320
+ ruby2_keywords "assert_no_#{field_type}_field" if respond_to?(:ruby2_keywords)
133
321
  alias_method "refute_#{field_type}_field", "assert_no_#{field_type}_field"
134
322
  end
135
323
 
324
+ ##
325
+ # Assert that element matches xpath
326
+ #
327
+ # @!method assert_matches_xpath
328
+ # See {Capybara::Node::Matchers#matches_xpath?}
329
+
330
+ ##
331
+ # Assert that element does not match xpath
332
+ #
333
+ # @!method refute_matches_xpath
334
+ # @!method assert_not_matches_xpath
335
+ # See {Capybara::Node::Matchers#not_matches_xpath?}
336
+
337
+ ##
338
+ # Assert that element matches css
339
+ #
340
+ # @!method assert_matches_css
341
+ # See {Capybara::Node::Matchers#matches_css?}
342
+
343
+ ##
344
+ # Assert that element matches css
345
+ #
346
+ # @!method refute_matches_css
347
+ # @!method assert_not_matches_css
348
+ # See {Capybara::Node::Matchers#not_matches_css?}
349
+
136
350
  %w[xpath css].each do |selector_type|
137
351
  define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
138
352
  subject, args = determine_subject(args)
139
353
  assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
140
354
  end
355
+ ruby2_keywords "assert_matches_#{selector_type}" if respond_to?(:ruby2_keywords)
141
356
 
142
357
  define_method "assert_not_matches_#{selector_type}" do |*args, &optional_filter_block|
143
358
  subject, args = determine_subject(args)
144
359
  assert_not_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
145
360
  end
361
+ ruby2_keywords "assert_not_matches_#{selector_type}" if respond_to?(:ruby2_keywords)
146
362
  alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
147
363
  end
148
364
 
149
- ##
150
- # Assertion that there is xpath
151
- #
152
- # @!method assert_xpath
153
- # see Capybara::Node::Matchers#has_xpath?
154
-
155
- ##
156
- # Assertion that there is no xpath
157
- #
158
- # @!method refute_xpath
159
- # @!method assert_no_xpath
160
- # see Capybara::Node::Matchers#has_no_xpath?
161
-
162
- ##
163
- # Assertion that there is css
164
- #
165
- # @!method assert_css
166
- # see Capybara::Node::Matchers#has_css?
167
-
168
- ##
169
- # Assertion that there is no css
170
- #
171
- # @!method refute_css
172
- # @!method assert_no_css
173
- # see Capybara::Node::Matchers#has_no_css?
174
-
175
- ##
176
- # Assertion that there is link
177
- #
178
- # @!method assert_link
179
- # see {Capybara::Node::Matchers#has_link?}
180
-
181
- ##
182
- # Assertion that there is no link
183
- #
184
- # @!method assert_no_link
185
- # @!method refute_link
186
- # see {Capybara::Node::Matchers#has_no_link?}
187
-
188
- ##
189
- # Assertion that there is button
190
- #
191
- # @!method assert_button
192
- # see {Capybara::Node::Matchers#has_button?}
193
-
194
- ##
195
- # Assertion that there is no button
196
- #
197
- # @!method refute_button
198
- # @!method assert_no_button
199
- # see {Capybara::Node::Matchers#has_no_button?}
200
-
201
- ##
202
- # Assertion that there is field
203
- #
204
- # @!method assert_field
205
- # see {Capybara::Node::Matchers#has_field?}
206
-
207
- ##
208
- # Assertion that there is no field
209
- #
210
- # @!method refute_field
211
- # @!method assert_no_field
212
- # see {Capybara::Node::Matchers#has_no_field?}
213
-
214
- ##
215
- # Assertion that there is checked_field
216
- #
217
- # @!method assert_checked_field
218
- # see {Capybara::Node::Matchers#has_checked_field?}
219
-
220
- ##
221
- # Assertion that there is no checked_field
222
- #
223
- # @!method assert_no_checked_field
224
- # @!method refute_checked_field
225
-
226
- ##
227
- # Assertion that there is unchecked_field
228
- #
229
- # @!method assert_unchecked_field
230
- # see {Capybara::Node::Matchers#has_unchecked_field?}
231
-
232
- ##
233
- # Assertion that there is no unchecked_field
234
- #
235
- # @!method assert_no_unchecked_field
236
- # @!method refute_unchecked_field
237
-
238
- ##
239
- # Assertion that there is select
240
- #
241
- # @!method assert_select
242
- # see {Capybara::Node::Matchers#has_select?}
243
-
244
- ##
245
- # Assertion that there is no select
246
- #
247
- # @!method refute_select
248
- # @!method assert_no_select
249
- # see {Capybara::Node::Matchers#has_no_select?}
250
-
251
- ##
252
- # Assertion that there is table
253
- #
254
- # @!method assert_table
255
- # see {Capybara::Node::Matchers#has_table?}
256
-
257
- ##
258
- # Assertion that there is no table
259
- #
260
- # @!method refute_table
261
- # @!method assert_no_table
262
- # see {Capybara::Node::Matchers#has_no_table?}
263
-
264
365
  private
265
366
 
266
367
  def determine_subject(args)