capybara 3.3.0 → 3.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +803 -13
  4. data/License.txt +1 -1
  5. data/README.md +257 -84
  6. data/lib/capybara/config.rb +25 -9
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +17 -3
  9. data/lib/capybara/driver/node.rb +31 -6
  10. data/lib/capybara/dsl.rb +9 -7
  11. data/lib/capybara/helpers.rb +31 -7
  12. data/lib/capybara/minitest/spec.rb +180 -88
  13. data/lib/capybara/minitest.rb +262 -149
  14. data/lib/capybara/node/actions.rb +202 -116
  15. data/lib/capybara/node/base.rb +34 -19
  16. data/lib/capybara/node/document.rb +14 -2
  17. data/lib/capybara/node/document_matchers.rb +10 -12
  18. data/lib/capybara/node/element.rb +269 -115
  19. data/lib/capybara/node/finders.rb +99 -77
  20. data/lib/capybara/node/matchers.rb +327 -151
  21. data/lib/capybara/node/simple.rb +48 -13
  22. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  23. data/lib/capybara/queries/active_element_query.rb +18 -0
  24. data/lib/capybara/queries/ancestor_query.rb +8 -9
  25. data/lib/capybara/queries/base_query.rb +23 -16
  26. data/lib/capybara/queries/current_path_query.rb +16 -6
  27. data/lib/capybara/queries/match_query.rb +1 -0
  28. data/lib/capybara/queries/selector_query.rb +587 -130
  29. data/lib/capybara/queries/sibling_query.rb +8 -6
  30. data/lib/capybara/queries/style_query.rb +6 -2
  31. data/lib/capybara/queries/text_query.rb +28 -14
  32. data/lib/capybara/queries/title_query.rb +2 -2
  33. data/lib/capybara/rack_test/browser.rb +92 -25
  34. data/lib/capybara/rack_test/driver.rb +16 -7
  35. data/lib/capybara/rack_test/errors.rb +6 -0
  36. data/lib/capybara/rack_test/form.rb +68 -41
  37. data/lib/capybara/rack_test/node.rb +106 -39
  38. data/lib/capybara/rails.rb +1 -1
  39. data/lib/capybara/registration_container.rb +41 -0
  40. data/lib/capybara/registrations/drivers.rb +42 -0
  41. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  42. data/lib/capybara/registrations/servers.rb +66 -0
  43. data/lib/capybara/result.rb +75 -52
  44. data/lib/capybara/rspec/features.rb +7 -7
  45. data/lib/capybara/rspec/matcher_proxies.rb +39 -18
  46. data/lib/capybara/rspec/matchers/base.rb +113 -0
  47. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  48. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  49. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  50. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  51. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  52. data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
  53. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  54. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  55. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  56. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  57. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  58. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  59. data/lib/capybara/rspec/matchers.rb +141 -339
  60. data/lib/capybara/rspec.rb +2 -0
  61. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  62. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  63. data/lib/capybara/selector/css.rb +27 -25
  64. data/lib/capybara/selector/definition/button.rb +68 -0
  65. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  66. data/lib/capybara/selector/definition/css.rb +10 -0
  67. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  68. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  69. data/lib/capybara/selector/definition/element.rb +28 -0
  70. data/lib/capybara/selector/definition/field.rb +40 -0
  71. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  72. data/lib/capybara/selector/definition/file_field.rb +13 -0
  73. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  74. data/lib/capybara/selector/definition/frame.rb +17 -0
  75. data/lib/capybara/selector/definition/id.rb +6 -0
  76. data/lib/capybara/selector/definition/label.rb +62 -0
  77. data/lib/capybara/selector/definition/link.rb +55 -0
  78. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  79. data/lib/capybara/selector/definition/option.rb +27 -0
  80. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  81. data/lib/capybara/selector/definition/select.rb +81 -0
  82. data/lib/capybara/selector/definition/table.rb +109 -0
  83. data/lib/capybara/selector/definition/table_row.rb +21 -0
  84. data/lib/capybara/selector/definition/xpath.rb +5 -0
  85. data/lib/capybara/selector/definition.rb +280 -0
  86. data/lib/capybara/selector/filter.rb +1 -0
  87. data/lib/capybara/selector/filter_set.rb +73 -25
  88. data/lib/capybara/selector/filters/base.rb +24 -5
  89. data/lib/capybara/selector/filters/expression_filter.rb +3 -3
  90. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  91. data/lib/capybara/selector/filters/node_filter.rb +16 -2
  92. data/lib/capybara/selector/regexp_disassembler.rb +211 -0
  93. data/lib/capybara/selector/selector.rb +85 -348
  94. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  95. data/lib/capybara/selector.rb +474 -447
  96. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  98. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  99. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  100. data/lib/capybara/selenium/driver.rb +255 -143
  101. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
  102. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  103. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
  104. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  105. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  106. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  107. data/lib/capybara/selenium/extensions/find.rb +110 -0
  108. data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
  109. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  110. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  111. data/lib/capybara/selenium/node.rb +436 -134
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
  115. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  116. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  117. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  118. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  119. data/lib/capybara/selenium/patches/logs.rb +45 -0
  120. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  121. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  122. data/lib/capybara/server/animation_disabler.rb +56 -19
  123. data/lib/capybara/server/checker.rb +9 -3
  124. data/lib/capybara/server/middleware.rb +28 -12
  125. data/lib/capybara/server.rb +33 -10
  126. data/lib/capybara/session/config.rb +34 -10
  127. data/lib/capybara/session/matchers.rb +23 -16
  128. data/lib/capybara/session.rb +230 -170
  129. data/lib/capybara/spec/public/jquery.js +5 -5
  130. data/lib/capybara/spec/public/offset.js +6 -0
  131. data/lib/capybara/spec/public/test.js +121 -8
  132. data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
  133. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  134. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  135. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  136. data/lib/capybara/spec/session/all_spec.rb +127 -40
  137. data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
  138. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
  139. data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
  140. data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
  141. data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
  142. data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
  143. data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
  144. data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
  145. data/lib/capybara/spec/session/body_spec.rb +6 -6
  146. data/lib/capybara/spec/session/check_spec.rb +102 -47
  147. data/lib/capybara/spec/session/choose_spec.rb +58 -32
  148. data/lib/capybara/spec/session/click_button_spec.rb +219 -163
  149. data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
  150. data/lib/capybara/spec/session/click_link_spec.rb +77 -54
  151. data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
  152. data/lib/capybara/spec/session/current_url_spec.rb +38 -29
  153. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  154. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  155. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
  156. data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
  157. data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
  158. data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
  159. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  160. data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
  161. data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
  162. data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
  163. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  164. data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
  165. data/lib/capybara/spec/session/find_field_spec.rb +32 -30
  166. data/lib/capybara/spec/session/find_link_spec.rb +31 -21
  167. data/lib/capybara/spec/session/find_spec.rb +244 -141
  168. data/lib/capybara/spec/session/first_spec.rb +43 -43
  169. data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
  170. data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
  171. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
  172. data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
  173. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  174. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  175. data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
  176. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  177. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  178. data/lib/capybara/spec/session/has_button_spec.rb +94 -13
  179. data/lib/capybara/spec/session/has_css_spec.rb +272 -132
  180. data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
  181. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  182. data/lib/capybara/spec/session/has_field_spec.rb +137 -58
  183. data/lib/capybara/spec/session/has_link_spec.rb +44 -4
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
  185. data/lib/capybara/spec/session/has_select_spec.rb +84 -50
  186. data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +181 -4
  189. data/lib/capybara/spec/session/has_text_spec.rb +101 -53
  190. data/lib/capybara/spec/session/has_title_spec.rb +19 -14
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
  192. data/lib/capybara/spec/session/headers_spec.rb +1 -1
  193. data/lib/capybara/spec/session/html_spec.rb +13 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
  195. data/lib/capybara/spec/session/node_spec.rb +894 -142
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
  197. data/lib/capybara/spec/session/refresh_spec.rb +9 -7
  198. data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
  199. data/lib/capybara/spec/session/response_code_spec.rb +1 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  202. data/lib/capybara/spec/session/save_page_spec.rb +37 -37
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +119 -0
  206. data/lib/capybara/spec/session/select_spec.rb +85 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +49 -18
  208. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  209. data/lib/capybara/spec/session/text_spec.rb +25 -24
  210. data/lib/capybara/spec/session/title_spec.rb +7 -6
  211. data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
  212. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  213. data/lib/capybara/spec/session/visit_spec.rb +68 -49
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
  216. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
  217. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
  218. data/lib/capybara/spec/session/window/window_spec.rb +62 -63
  219. data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
  220. data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
  221. data/lib/capybara/spec/session/within_spec.rb +79 -42
  222. data/lib/capybara/spec/spec_helper.rb +41 -53
  223. data/lib/capybara/spec/test_app.rb +132 -43
  224. data/lib/capybara/spec/views/animated.erb +49 -0
  225. data/lib/capybara/spec/views/form.erb +139 -42
  226. data/lib/capybara/spec/views/frame_child.erb +4 -3
  227. data/lib/capybara/spec/views/frame_one.erb +2 -1
  228. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  229. data/lib/capybara/spec/views/frame_two.erb +1 -1
  230. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  231. data/lib/capybara/spec/views/layout.erb +10 -0
  232. data/lib/capybara/spec/views/obscured.erb +47 -0
  233. data/lib/capybara/spec/views/offset.erb +33 -0
  234. data/lib/capybara/spec/views/path.erb +2 -2
  235. data/lib/capybara/spec/views/popup_one.erb +1 -1
  236. data/lib/capybara/spec/views/popup_two.erb +1 -1
  237. data/lib/capybara/spec/views/react.erb +45 -0
  238. data/lib/capybara/spec/views/scroll.erb +21 -0
  239. data/lib/capybara/spec/views/spatial.erb +31 -0
  240. data/lib/capybara/spec/views/tables.erb +67 -0
  241. data/lib/capybara/spec/views/with_animation.erb +39 -4
  242. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  243. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  244. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  245. data/lib/capybara/spec/views/with_hover.erb +3 -2
  246. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  247. data/lib/capybara/spec/views/with_html.erb +37 -9
  248. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  249. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  250. data/lib/capybara/spec/views/with_js.erb +26 -5
  251. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  252. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  253. data/lib/capybara/spec/views/with_scope.erb +2 -2
  254. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  255. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  256. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  257. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  258. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  259. data/lib/capybara/spec/views/with_windows.erb +1 -1
  260. data/lib/capybara/spec/views/within_frames.erb +1 -1
  261. data/lib/capybara/version.rb +1 -1
  262. data/lib/capybara/window.rb +19 -25
  263. data/lib/capybara.rb +126 -111
  264. data/spec/basic_node_spec.rb +59 -34
  265. data/spec/capybara_spec.rb +56 -44
  266. data/spec/counter_spec.rb +35 -0
  267. data/spec/css_builder_spec.rb +101 -0
  268. data/spec/css_splitter_spec.rb +8 -8
  269. data/spec/dsl_spec.rb +79 -52
  270. data/spec/filter_set_spec.rb +9 -9
  271. data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
  272. data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
  273. data/spec/minitest_spec.rb +45 -7
  274. data/spec/minitest_spec_spec.rb +87 -64
  275. data/spec/per_session_config_spec.rb +6 -6
  276. data/spec/rack_test_spec.rb +172 -116
  277. data/spec/regexp_dissassembler_spec.rb +250 -0
  278. data/spec/result_spec.rb +80 -72
  279. data/spec/rspec/features_spec.rb +21 -16
  280. data/spec/rspec/scenarios_spec.rb +10 -6
  281. data/spec/rspec/shared_spec_matchers.rb +407 -365
  282. data/spec/rspec/views_spec.rb +3 -3
  283. data/spec/rspec_matchers_spec.rb +35 -10
  284. data/spec/rspec_spec.rb +63 -41
  285. data/spec/sauce_spec_chrome.rb +43 -0
  286. data/spec/selector_spec.rb +334 -89
  287. data/spec/selenium_spec_chrome.rb +176 -62
  288. data/spec/selenium_spec_chrome_remote.rb +54 -14
  289. data/spec/selenium_spec_edge.rb +41 -8
  290. data/spec/selenium_spec_firefox.rb +228 -0
  291. data/spec/selenium_spec_firefox_remote.rb +94 -0
  292. data/spec/selenium_spec_ie.rb +129 -11
  293. data/spec/selenium_spec_safari.rb +162 -0
  294. data/spec/server_spec.rb +171 -97
  295. data/spec/session_spec.rb +34 -18
  296. data/spec/shared_selenium_node.rb +79 -0
  297. data/spec/shared_selenium_session.rb +344 -80
  298. data/spec/spec_helper.rb +124 -2
  299. data/spec/whitespace_normalizer_spec.rb +54 -0
  300. data/spec/xpath_builder_spec.rb +93 -0
  301. metadata +326 -28
  302. data/lib/capybara/rspec/compound.rb +0 -94
  303. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
  304. data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
  305. data/lib/capybara/spec/session/has_style_spec.rb +0 -25
  306. data/lib/capybara/spec/session/source_spec.rb +0 -0
  307. data/lib/capybara/spec/views/with_title.erb +0 -5
  308. data/spec/selenium_spec_marionette.rb +0 -167
@@ -15,11 +15,11 @@ class Capybara::Driver::Base
15
15
  raise NotImplementedError
16
16
  end
17
17
 
18
- def find_xpath(query)
18
+ def find_xpath(query, **options)
19
19
  raise NotImplementedError
20
20
  end
21
21
 
22
- def find_css(query)
22
+ def find_css(query, **options)
23
23
  raise NotImplementedError
24
24
  end
25
25
 
@@ -59,6 +59,14 @@ class Capybara::Driver::Base
59
59
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#status_code'
60
60
  end
61
61
 
62
+ def send_keys(*)
63
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#send_keys'
64
+ end
65
+
66
+ def active_element
67
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#active_element'
68
+ end
69
+
62
70
  ##
63
71
  #
64
72
  # @param frame [Capybara::Node::Element, :parent, :top] The iframe element to switch to
@@ -159,6 +167,12 @@ class Capybara::Driver::Base
159
167
  end
160
168
 
161
169
  def session_options
162
- @session&.config || Capybara.session_options
170
+ session&.config || Capybara.session_options
171
+ end
172
+
173
+ private
174
+
175
+ def session
176
+ @session ||= nil
163
177
  end
164
178
  end
@@ -3,11 +3,12 @@
3
3
  module Capybara
4
4
  module Driver
5
5
  class Node
6
- attr_reader :driver, :native
6
+ attr_reader :driver, :native, :initial_cache
7
7
 
8
- def initialize(driver, native)
8
+ def initialize(driver, native, initial_cache = {})
9
9
  @driver = driver
10
10
  @native = native
11
+ @initial_cache = initial_cache
11
12
  end
12
13
 
13
14
  def all_text
@@ -30,8 +31,8 @@ module Capybara
30
31
  raise NotImplementedError
31
32
  end
32
33
 
33
- # @param value String or Array. Array is only allowed if node has 'multiple' attribute
34
- # @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
35
36
  def set(value, **options)
36
37
  raise NotImplementedError
37
38
  end
@@ -64,7 +65,19 @@ module Capybara
64
65
  raise NotImplementedError
65
66
  end
66
67
 
67
- def drag_to(element)
68
+ def drag_to(element, **options)
69
+ raise NotImplementedError
70
+ end
71
+
72
+ def drop(*args)
73
+ raise NotImplementedError
74
+ end
75
+
76
+ def scroll_by(x, y)
77
+ raise NotImplementedError
78
+ end
79
+
80
+ def scroll_to(element, alignment, position = nil)
68
81
  raise NotImplementedError
69
82
  end
70
83
 
@@ -76,6 +89,10 @@ module Capybara
76
89
  raise NotImplementedError
77
90
  end
78
91
 
92
+ def obscured?
93
+ raise NotImplementedError
94
+ end
95
+
79
96
  def checked?
80
97
  raise NotImplementedError
81
98
  end
@@ -96,6 +113,10 @@ module Capybara
96
113
  !!self[:multiple]
97
114
  end
98
115
 
116
+ def rect
117
+ raise NotSupportedByDriverError, 'Capybara::Driver::Node#rect'
118
+ end
119
+
99
120
  def path
100
121
  raise NotSupportedByDriverError, 'Capybara::Driver::Node#path'
101
122
  end
@@ -104,6 +125,10 @@ module Capybara
104
125
  raise NotSupportedByDriverError, 'Capybara::Driver::Node#trigger'
105
126
  end
106
127
 
128
+ def shadow_root
129
+ raise NotSupportedByDriverError, 'Capybara::Driver::Node#shadow_root'
130
+ end
131
+
107
132
  def inspect
108
133
  %(#<#{self.class} tag="#{tag_name}" path="#{path}">)
109
134
  rescue NotSupportedByDriverError
@@ -111,7 +136,7 @@ module Capybara
111
136
  end
112
137
 
113
138
  def ==(other)
114
- raise NotSupportedByDriverError, 'Capybara::Driver::Node#=='
139
+ eql?(other) || (other.respond_to?(:native) && native == other.native)
115
140
  end
116
141
  end
117
142
  end
data/lib/capybara/dsl.rb CHANGED
@@ -5,12 +5,12 @@ require 'capybara'
5
5
  module Capybara
6
6
  module DSL
7
7
  def self.included(base)
8
- warn "including Capybara::DSL in the global scope is not recommended!" if base == Object
8
+ warn 'including Capybara::DSL in the global scope is not recommended!' if base == Object
9
9
  super
10
10
  end
11
11
 
12
12
  def self.extended(base)
13
- warn "extending the main object with Capybara::DSL is not recommended!" if base == TOPLEVEL_BINDING.eval("self")
13
+ warn 'extending the main object with Capybara::DSL is not recommended!' if base == TOPLEVEL_BINDING.eval('self')
14
14
  super
15
15
  end
16
16
 
@@ -18,8 +18,8 @@ module Capybara
18
18
  #
19
19
  # Shortcut to working in a different session.
20
20
  #
21
- def using_session(name, &block)
22
- Capybara.using_session(name, &block)
21
+ def using_session(name_or_session, &block)
22
+ Capybara.using_session(name_or_session, &block)
23
23
  end
24
24
 
25
25
  # Shortcut to using a different wait time.
@@ -47,9 +47,11 @@ 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
52
- end
50
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
51
+ def #{method}(...)
52
+ page.method("#{method}").call(...)
53
+ end
54
+ METHOD
53
55
  end
54
56
  end
55
57
 
@@ -15,7 +15,7 @@ module Capybara
15
15
  # @return [String] Normalized text
16
16
  #
17
17
  def normalize_whitespace(text)
18
- warn "DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver"
18
+ Capybara::Helpers.warn 'DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver'
19
19
  text.to_s.gsub(/[[:space:]]+/, ' ').strip
20
20
  end
21
21
 
@@ -33,7 +33,7 @@ module Capybara
33
33
  return text if text.is_a?(Regexp)
34
34
 
35
35
  escaped = Regexp.escape(text)
36
- escaped = escaped.gsub("\\ ", "[[:blank:]]") if all_whitespace
36
+ escaped = escaped.gsub('\\ ', '[[:blank:]]') if all_whitespace
37
37
  escaped = "\\A#{escaped}\\z" if exact
38
38
  Regexp.new(escaped, options)
39
39
  end
@@ -41,16 +41,17 @@ 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
48
48
  # @return [String] The modified HTML code
49
49
  #
50
50
  def inject_asset_host(html, host: Capybara.asset_host)
51
- if host && Nokogiri::HTML(html).css("base").empty?
52
- match = html.match(/<head[^<]*?>/)
53
- return html.clone.insert match.end(0), "<base href='#{host}' />" if match
51
+ if host && Nokogiri::HTML(html).css('base').empty?
52
+ html.match(/<head[^<]*?>/) do |m|
53
+ return html.clone.insert m.end(0), "<base href='#{host}' />"
54
+ end
54
55
  end
55
56
  html
56
57
  end
@@ -69,7 +70,26 @@ module Capybara
69
70
  count == 1 ? singular : plural
70
71
  end
71
72
 
72
- if defined?(Process::CLOCK_MONOTONIC)
73
+ def filter_backtrace(trace)
74
+ return 'No backtrace' unless trace
75
+
76
+ filter = %r{lib/capybara/|lib/rspec/|lib/minitest/|delegate.rb}
77
+ new_trace = trace.take_while { |line| line !~ filter }
78
+ new_trace = trace.grep_v(filter) if new_trace.empty?
79
+ new_trace = trace.dup if new_trace.empty?
80
+
81
+ new_trace.first.split(':in ', 2).first
82
+ end
83
+
84
+ def warn(message, uplevel: 1)
85
+ Kernel.warn(message, uplevel: uplevel)
86
+ end
87
+
88
+ if defined?(Process::CLOCK_MONOTONIC_RAW)
89
+ def monotonic_time; Process.clock_gettime Process::CLOCK_MONOTONIC_RAW; end
90
+ elsif defined?(Process::CLOCK_MONOTONIC_PRECISE)
91
+ def monotonic_time; Process.clock_gettime Process::CLOCK_MONOTONIC_PRECISE; end
92
+ elsif defined?(Process::CLOCK_MONOTONIC)
73
93
  def monotonic_time; Process.clock_gettime Process::CLOCK_MONOTONIC; end
74
94
  else
75
95
  def monotonic_time; Time.now.to_f; end
@@ -86,6 +106,10 @@ module Capybara
86
106
  end
87
107
 
88
108
  def expired?
109
+ if stalled?
110
+ raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead'
111
+ end
112
+
89
113
  current - @start >= @expire_in
90
114
  end
91
115
 
@@ -5,183 +5,275 @@ require 'minitest/spec'
5
5
  module Capybara
6
6
  module Minitest
7
7
  module Expectations
8
- %w[text content title current_path].each do |assertion|
9
- infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
10
- infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
11
- end
8
+ ##
9
+ # Expectation that there is an ancestor
10
+ #
11
+ # @!method must_have_ancestor
12
+ # See {Capybara::Node::Matchers#has_ancestor?}
12
13
 
13
- # rubocop:disable Style/MultilineBlockChain
14
- (%w[selector xpath css link button field select table checked_field unchecked_field].flat_map do |assertion|
15
- [%W[assert_#{assertion} must_have_#{assertion}],
16
- %W[refute_#{assertion} wont_have_#{assertion}]]
17
- end + [%w[assert_all_of_selectors must_have_all_of_selectors],
18
- %w[assert_none_of_selectors must_have_none_of_selectors],
19
- %w[assert_style must_have_style]] +
20
- %w[selector xpath css].flat_map do |assertion|
21
- [%W[assert_matches_#{assertion} must_match_#{assertion}],
22
- %W[refute_matches_#{assertion} wont_match_#{assertion}]]
23
- end).each do |(meth, new_name)|
24
- class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
25
- def #{new_name} *args, &block
26
- ::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
27
- end
28
- ASSERTION
14
+ ##
15
+ # Expectation that there is button
16
+ #
17
+ # @!method must_have_button
18
+ # See {Capybara::Node::Matchers#has_button?}
29
19
 
30
- ::Minitest::Expectation.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
31
- def #{new_name} *args, &block
32
- ctx.#{meth}(target, *args, &block)
33
- end
34
- ASSERTION
35
- end
36
- # rubocop:enable Style/MultilineBlockChain
20
+ ##
21
+ # Expectation that there is no button
22
+ #
23
+ # @!method wont_have_button
24
+ # See {Capybara::Node::Matchers#has_no_button?}
37
25
 
38
26
  ##
39
- # Expectation that there is xpath
27
+ # Expectation that there is checked_field
40
28
  #
41
- # @!method must_have_xpath
42
- # see Capybara::Node::Matchers#has_xpath?
29
+ # @!method must_have_checked_field
30
+ # See {Capybara::Node::Matchers#has_checked_field?}
43
31
 
44
32
  ##
45
- # Expectation that there is no xpath
33
+ # Expectation that there is no checked_field
46
34
  #
47
- # @!method wont_have_xpath
48
- # see Capybara::Node::Matchers#has_no_xpath?
35
+ # @!method wont_have_checked_field
36
+ # See {Capybara::Node::Matchers#has_no_checked_field?}
49
37
 
50
38
  ##
51
- # Expectation that there is css
39
+ # Expectation that there is unchecked_field
52
40
  #
53
- # @!method must_have_css
54
- # see Capybara::Node::Matchers#has_css?
41
+ # @!method must_have_unchecked_field
42
+ # See {Capybara::Node::Matchers#has_unchecked_field?}
55
43
 
56
44
  ##
57
- # Expectation that there is no css
45
+ # Expectation that there is no unchecked_field
58
46
  #
59
- # @!method wont_have_css
60
- # see Capybara::Node::Matchers#has_no_css?
47
+ # @!method wont_have_unchecked_field
48
+ # See {Capybara::Node::Matchers#has_no_unchecked_field?}
61
49
 
62
50
  ##
63
- # Expectation that there is link
51
+ # Expectation that page content does match
64
52
  #
65
- # @!method must_have_link
66
- # see {Capybara::Node::Matchers#has_link?}
53
+ # @!method must_have_content
54
+ # See {Capybara::Node::Matchers#has_content?}
67
55
 
68
56
  ##
69
- # Expectation that there is no link
57
+ # Expectation that page content does not match
70
58
  #
71
- # @!method wont_have_link
72
- # see {Capybara::Node::Matchers#has_no_link?}
59
+ # @!method wont_have_content
60
+ # See {Capybara::Node::Matchers#has_no_content?}
73
61
 
74
62
  ##
75
- # Expectation that there is button
63
+ # Expectation that there is css
76
64
  #
77
- # @!method must_have_button
78
- # see {Capybara::Node::Matchers#has_button?}
65
+ # @!method must_have_css
66
+ # See {Capybara::Node::Matchers#has_css?}
79
67
 
80
68
  ##
81
- # Expectation that there is no button
69
+ # Expectation that there is no css
82
70
  #
83
- # @!method wont_have_button
84
- # see {Capybara::Node::Matchers#has_no_button?}
71
+ # @!method wont_have_css
72
+ # See {Capybara::Node::Matchers#has_no_css?}
73
+
74
+ ##
75
+ # Expectation that current path matches
76
+ #
77
+ # @!method must_have_current_path
78
+ # See {Capybara::SessionMatchers#has_current_path?}
79
+
80
+ ##
81
+ # Expectation that current page does not match
82
+ #
83
+ # @!method wont_have_current_path
84
+ # See {Capybara::SessionMatchers#has_no_current_path?}
85
85
 
86
86
  ##
87
87
  # Expectation that there is field
88
88
  #
89
89
  # @!method must_have_field
90
- # see {Capybara::Node::Matchers#has_field?}
90
+ # See {Capybara::Node::Matchers#has_field?}
91
91
 
92
92
  ##
93
93
  # Expectation that there is no field
94
94
  #
95
95
  # @!method wont_have_field
96
- # see {Capybara::Node::Matchers#has_no_field?}
96
+ # See {Capybara::Node::Matchers#has_no_field?}
97
97
 
98
98
  ##
99
- # Expectation that there is checked_field
99
+ # Expectation that there is element
100
100
  #
101
- # @!method must_have_checked_field
102
- # see {Capybara::Node::Matchers#has_checked_field?}
101
+ # @!method must_have_element
102
+ # See {Capybara::Node::Matchers#has_element?}
103
103
 
104
104
  ##
105
- # Expectation that there is no checked_field
105
+ # Expectation that there is no element
106
106
  #
107
- # @!method wont_have_chceked_field
107
+ # @!method wont_have_element
108
+ # See {Capybara::Node::Matchers#has_no_element?}
108
109
 
109
110
  ##
110
- # Expectation that there is unchecked_field
111
+ # Expectation that there is link
111
112
  #
112
- # @!method must_have_unchecked_field
113
- # see {Capybara::Node::Matchers#has_unchecked_field?}
113
+ # @!method must_have_link
114
+ # See {Capybara::Node::Matchers#has_link?}
114
115
 
115
116
  ##
116
- # Expectation that there is no unchecked_field
117
+ # Expectation that there is no link
117
118
  #
118
- # @!method wont_have_unchceked_field
119
+ # @!method wont_have_link
120
+ # See {Capybara::Node::Matchers#has_no_link?}
121
+
122
+ ##
123
+ # Expectation that page text does match
124
+ #
125
+ # @!method must_have_text
126
+ # See {Capybara::Node::Matchers#has_text?}
127
+
128
+ ##
129
+ # Expectation that page text does not match
130
+ #
131
+ # @!method wont_have_text
132
+ # See {Capybara::Node::Matchers#has_no_text?}
133
+
134
+ ##
135
+ # Expectation that page title does match
136
+ #
137
+ # @!method must_have_title
138
+ # See {Capybara::Node::DocumentMatchers#has_title?}
139
+
140
+ ##
141
+ # Expectation that page title does not match
142
+ #
143
+ # @!method wont_have_title
144
+ # See {Capybara::Node::DocumentMatchers#has_no_title?}
119
145
 
120
146
  ##
121
147
  # Expectation that there is select
122
148
  #
123
149
  # @!method must_have_select
124
- # see {Capybara::Node::Matchers#has_select?}
150
+ # See {Capybara::Node::Matchers#has_select?}
125
151
 
126
152
  ##
127
153
  # Expectation that there is no select
128
154
  #
129
155
  # @!method wont_have_select
130
- # see {Capybara::Node::Matchers#has_no_select?}
156
+ # See {Capybara::Node::Matchers#has_no_select?}
131
157
 
132
158
  ##
133
- # Expectation that there is table
159
+ # Expectation that there is a selector
134
160
  #
135
- # @!method must_have_table
136
- # see {Capybara::Node::Matchers#has_table?}
161
+ # @!method must_have_selector
162
+ # See {Capybara::Node::Matchers#has_selector?}
137
163
 
138
164
  ##
139
- # Expectation that there is no table
165
+ # Expectation that there is no selector
140
166
  #
141
- # @!method wont_have_table
142
- # see {Capybara::Node::Matchers#has_no_table?}
167
+ # @!method wont_have_selector
168
+ # See {Capybara::Node::Matchers#has_no_selector?}
143
169
 
144
170
  ##
145
- # Expectation that page title does match
171
+ # Expectation that all of the provided selectors are present
146
172
  #
147
- # @!method must_have_title
148
- # see {Capybara::Node::DocumentMatchers#assert_title}
173
+ # @!method must_have_all_of_selectors
174
+ # See {Capybara::Node::Matchers#assert_all_of_selectors}
149
175
 
150
176
  ##
151
- # Expectation that page title does not match
177
+ # Expectation that none of the provided selectors are present
152
178
  #
153
- # @!method wont_have_title
154
- # see {Capybara::Node::DocumentMatchers#assert_no_title}
179
+ # @!method must_have_none_of_selectors
180
+ # See {Capybara::Node::Matchers#assert_none_of_selectors}
155
181
 
156
182
  ##
157
- # Expectation that current path matches
183
+ # Expectation that any of the provided selectors are present
158
184
  #
159
- # @!method must_have_current_path
160
- # see {Capybara::SessionMatchers#assert_current_path}
185
+ # @!method must_have_any_of_selectors
186
+ # See {Capybara::Node::Matchers#assert_any_of_selectors}
161
187
 
162
188
  ##
163
- # Expectation that current page does not match
189
+ # Expectation that there is a sibling
164
190
  #
165
- # @!method wont_have_current_path
166
- # see {Capybara::SessionMatchers#assert_no_current_path}
191
+ # @!method must_have_sibling
192
+ # See {Capybara::Node::Matchers#has_sibling?}
167
193
 
168
194
  ##
169
195
  # Expectation that element has style
170
196
  #
171
- # @!method must_have_style
172
- # see {Capybara::SessionMatchers#assert_style}
197
+ # @!method must_match_style
198
+ # See {Capybara::Node::Matchers#matches_style?}
199
+
200
+ ##
201
+ # Expectation that there is table
202
+ #
203
+ # @!method must_have_table
204
+ # See {Capybara::Node::Matchers#has_table?}
205
+
206
+ ##
207
+ # Expectation that there is no table
208
+ #
209
+ # @!method wont_have_table
210
+ # See {Capybara::Node::Matchers#has_no_table?}
211
+
212
+ ##
213
+ # Expectation that there is xpath
214
+ #
215
+ # @!method must_have_xpath
216
+ # See {Capybara::Node::Matchers#has_xpath?}
217
+
218
+ ##
219
+ # Expectation that there is no xpath
220
+ #
221
+ # @!method wont_have_xpath
222
+ # See {Capybara::Node::Matchers#has_no_xpath?}
223
+
224
+ # This currently doesn't work for Ruby 2.8 due to Minitest not forwarding keyword args separately
225
+ # %w[text content title current_path].each do |assertion|
226
+ # infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
227
+ # infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
228
+ # end
229
+
230
+ # rubocop:disable Style/MultilineBlockChain
231
+ (%w[text content title current_path
232
+ selector xpath css link button field select table checked_field unchecked_field
233
+ ancestor sibling].flat_map do |assertion|
234
+ [%W[assert_#{assertion} must_have_#{assertion}],
235
+ %W[refute_#{assertion} wont_have_#{assertion}]]
236
+ end + [%w[assert_all_of_selectors must_have_all_of_selectors],
237
+ %w[assert_none_of_selectors must_have_none_of_selectors],
238
+ %w[assert_any_of_selectors must_have_any_of_selectors],
239
+ %w[assert_matches_style must_match_style]] +
240
+ %w[selector xpath css].flat_map do |assertion|
241
+ [%W[assert_matches_#{assertion} must_match_#{assertion}],
242
+ %W[refute_matches_#{assertion} wont_match_#{assertion}]]
243
+ end).each do |(meth, new_name)|
244
+ class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
245
+ def #{new_name}(...)
246
+ ::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(...)
247
+ end
248
+ ASSERTION
249
+
250
+ ::Minitest::Expectation.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
251
+ def #{new_name}(...)
252
+ raise "Calling ##{new_name} outside of test." unless ctx
253
+ ctx.#{meth}(target, ...)
254
+ end
255
+ ASSERTION
256
+ end
257
+ # rubocop:enable Style/MultilineBlockChain
258
+
259
+ ##
260
+ # @deprecated
261
+ def must_have_style(...)
262
+ warn 'must_have_style is deprecated, please use must_match_style'
263
+ must_match_style(...)
264
+ end
173
265
  end
174
266
  end
175
267
  end
176
268
 
177
269
  class Capybara::Session
178
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
270
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
179
271
  end
180
272
 
181
273
  class Capybara::Node::Base
182
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
274
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
183
275
  end
184
276
 
185
277
  class Capybara::Node::Simple
186
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
278
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
187
279
  end