capybara 3.3.0 → 3.40.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/License.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2009-2016 Jonas Nicklas
3
+ Copyright (c) 2009-2018 Thomas Walpole, Jonas Nicklas
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,14 +1,8 @@
1
1
  # Capybara
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/teamcapybara/capybara.svg)](https://travis-ci.org/teamcapybara/capybara)
4
- [![Build Status](https://ci.appveyor.com/api/projects/status/github/teamcapybara/capybara?svg=true)](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
3
+ [![Build Status](https://github.com/teamcapybara/capybara/actions/workflows/build.yml/badge.svg)](https://github.com/teamcapybara/capybara/actions/workflows/build.yml)
5
4
  [![Code Climate](https://codeclimate.com/github/teamcapybara/capybara.svg)](https://codeclimate.com/github/teamcapybara/capybara)
6
- [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
- [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
8
-
9
- **Note** You are viewing the README for the development version of Capybara. If you are using the current release version
10
- you can find the README at https://github.com/teamcapybara/capybara/blob/3.2_stable/README.md
11
-
5
+ [![Coverage Status](https://coveralls.io/repos/github/teamcapybara/capybara/badge.svg?branch=master)](https://coveralls.io/github/teamcapybara/capybara?branch=master)
12
6
 
13
7
  Capybara helps you test web applications by simulating how a real user would
14
8
  interact with your app. It is agnostic about the driver running your tests and
@@ -21,8 +15,7 @@ If you and/or your company find value in Capybara and would like to contribute f
21
15
  <a href="https://www.patreon.com/capybara">Patreon</a>
22
16
 
23
17
 
24
- **Need help?** Ask on the mailing list (please do not open an issue on
25
- GitHub): http://groups.google.com/group/ruby-capybara
18
+ **Need help?** Ask on the discussions (please do not open an issue): https://github.com/orgs/teamcapybara/discussions/categories/q-a
26
19
 
27
20
  ## Table of contents
28
21
 
@@ -37,8 +30,6 @@ GitHub): http://groups.google.com/group/ruby-capybara
37
30
  - [Selecting the Driver](#selecting-the-driver)
38
31
  - [RackTest](#racktest)
39
32
  - [Selenium](#selenium)
40
- - [Capybara-webkit](#capybara-webkit)
41
- - [Poltergeist](#poltergeist)
42
33
  - [The DSL](#the-dsl)
43
34
  - [Navigating](#navigating)
44
35
  - [Clicking links and buttons](#clicking-links-and-buttons)
@@ -50,6 +41,10 @@ GitHub): http://groups.google.com/group/ruby-capybara
50
41
  - [Scripting](#scripting)
51
42
  - [Modals](#modals)
52
43
  - [Debugging](#debugging)
44
+ - [Selectors](#selectors)
45
+ - [Name](#selectors-name)
46
+ - [Locator](#selectors-locator)
47
+ - [Filters](#selectors-filters)
53
48
  - [Matching](#matching)
54
49
  - [Exactness](#exactness)
55
50
  - [Strategy](#strategy)
@@ -58,11 +53,13 @@ GitHub): http://groups.google.com/group/ruby-capybara
58
53
  - [Using the DSL elsewhere](#using-the-dsl-elsewhere)
59
54
  - [Calling remote servers](#calling-remote-servers)
60
55
  - [Using sessions](#using-sessions)
56
+ - [Named sessions](#named-sessions)
57
+ - [Using sessions manually](#using-sessions-manually)
61
58
  - [XPath, CSS and selectors](#xpath-css-and-selectors)
62
59
  - [Beware the XPath // trap](#beware-the-xpath--trap)
63
60
  - [Configuring and adding drivers](#configuring-and-adding-drivers)
64
61
  - [Gotchas:](#gotchas)
65
- - ["Threadsafe" mode](#threadsafe)
62
+ - ["Threadsafe" mode](#threadsafe-mode)
66
63
  - [Development](#development)
67
64
 
68
65
  ## <a name="key-benefits"></a>Key benefits
@@ -76,7 +73,7 @@ GitHub): http://groups.google.com/group/ruby-capybara
76
73
 
77
74
  ## <a name="setup"></a>Setup
78
75
 
79
- Capybara requires Ruby 2.2.2 or later. To install, add this line to your
76
+ Capybara requires Ruby 3.0.0 or later. To install, add this line to your
80
77
  `Gemfile` and run `bundle install`:
81
78
 
82
79
  ```ruby
@@ -140,18 +137,20 @@ There are also explicit tags for each registered driver set up for you (`@seleni
140
137
 
141
138
  ## <a name="using-capybara-with-rspec"></a>Using Capybara with RSpec
142
139
 
143
- Load RSpec 3.x support by adding the following line (typically to your
140
+ Load RSpec 3.5+ support by adding the following line (typically to your
144
141
  `spec_helper.rb` file):
145
142
 
146
143
  ```ruby
147
144
  require 'capybara/rspec'
148
145
  ```
149
146
 
150
- If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works
151
- if [you have it configured in
152
- RSpec](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#file-type-inference-disabled))
153
- and if you have your Capybara specs in a different directory, then tag the
154
- example groups with `type: :feature` or `type: :system` depending on which type of test you're writing.
147
+ If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works if
148
+ [you have it configured in RSpec](https://rspec.info/features/6-0/rspec-rails/directory-structure/))
149
+ and if you have your Capybara specs in a different directory, then tag the example groups with
150
+ `type: :feature` or `type: :system` depending on which type of test you're writing.
151
+
152
+ If you are using Rails system specs please see [their documentation](https://rspec.info/features/6-0/rspec-rails/system-specs/system-specs)
153
+ for selecting the driver you wish to use.
155
154
 
156
155
  If you are not using Rails, tag all the example groups in which you want to use
157
156
  Capybara with `type: :feature`.
@@ -161,7 +160,7 @@ You can now write your specs like so:
161
160
  ```ruby
162
161
  describe "the signin process", type: :feature do
163
162
  before :each do
164
- User.make(email: 'user@example.com', password: 'password')
163
+ User.create(email: 'user@example.com', password: 'password')
165
164
  end
166
165
 
167
166
  it "signs me in" do
@@ -183,7 +182,7 @@ to one specific driver. For example:
183
182
  ```ruby
184
183
  describe 'some stuff which requires js', js: true do
185
184
  it 'will use the default js driver'
186
- it 'will switch to one specific driver', driver: :webkit
185
+ it 'will switch to one specific driver', driver: :selenium
187
186
  end
188
187
  ```
189
188
 
@@ -192,7 +191,7 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
192
191
  ```ruby
193
192
  feature "Signing in" do
194
193
  background do
195
- User.make(email: 'user@example.com', password: 'caplin')
194
+ User.create(email: 'user@example.com', password: 'caplin')
196
195
  end
197
196
 
198
197
  scenario "Signing in with correct credentials" do
@@ -205,7 +204,7 @@ feature "Signing in" do
205
204
  expect(page).to have_content 'Success'
206
205
  end
207
206
 
208
- given(:other_user) { User.make(email: 'other@example.com', password: 'rous') }
207
+ given(:other_user) { User.create(email: 'other@example.com', password: 'rous') }
209
208
 
210
209
  scenario "Signing in as another user" do
211
210
  visit '/sessions/new'
@@ -219,7 +218,7 @@ feature "Signing in" do
219
218
  end
220
219
  ```
221
220
 
222
- `feature` is in fact just an alias for `describe ..., type:> :feature`,
221
+ `feature` is in fact just an alias for `describe ..., type: :feature`,
223
222
  `background` is an alias for `before`, `scenario` for `it`, and
224
223
  `given`/`given!` aliases for `let`/`let!`, respectively.
225
224
 
@@ -260,7 +259,9 @@ end
260
259
 
261
260
  ## <a name="using-capybara-with-minitest"></a>Using Capybara with Minitest
262
261
 
263
- * If you are using Rails, add the following code in your `test_helper.rb`
262
+ * If you are using Rails system tests please see their documentation for information on selecting the driver you wish to use.
263
+
264
+ * If you are using Rails, but not using Rails system tests, add the following code in your `test_helper.rb`
264
265
  file to make Capybara available in all test cases deriving from
265
266
  `ActionDispatch::IntegrationTest`:
266
267
 
@@ -275,8 +276,7 @@ end
275
276
  include Capybara::Minitest::Assertions
276
277
 
277
278
  # Reset sessions and driver between tests
278
- # Use super wherever this method is redefined in your individual test classes
279
- def teardown
279
+ teardown do
280
280
  Capybara.reset_sessions!
281
281
  Capybara.use_default_driver
282
282
  end
@@ -335,15 +335,15 @@ By default, Capybara uses the `:rack_test` driver, which is fast but limited: it
335
335
  does not support JavaScript, nor is it able to access HTTP resources outside of
336
336
  your Rack application, such as remote APIs and OAuth services. To get around
337
337
  these limitations, you can set up a different default driver for your features.
338
- For example if you'd prefer to run everything in Selenium, you could do:
338
+ For example, if you'd prefer to run everything in Selenium, you could do:
339
339
 
340
340
  ```ruby
341
341
  Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
342
342
  ```
343
343
 
344
- However, if you are using RSpec or Cucumber, you may instead want to consider
345
- leaving the faster `:rack_test` as the __default_driver__, and marking only those
346
- tests that require a JavaScript-capable driver using `js: true` or
344
+ However, if you are using RSpec or Cucumber (and your app runs correctly without JS),
345
+ you may instead want to consider leaving the faster `:rack_test` as the __default_driver__, and
346
+ marking only those tests that require a JavaScript-capable driver using `js: true` or
347
347
  `@javascript`, respectively. By default, JavaScript tests are run using the
348
348
  `:selenium` driver. You can change this by setting
349
349
  `Capybara.javascript_driver`.
@@ -352,7 +352,7 @@ You can also change the driver temporarily (typically in the Before/setup and
352
352
  After/teardown blocks):
353
353
 
354
354
  ```ruby
355
- Capybara.current_driver = :webkit # temporarily select different driver
355
+ Capybara.current_driver = :selenium # temporarily select different driver
356
356
  # tests here
357
357
  Capybara.use_default_driver # switch back to default driver
358
358
  ```
@@ -387,42 +387,26 @@ See the section on adding and configuring drivers.
387
387
 
388
388
  ### <a name="selenium"></a>Selenium
389
389
 
390
- At the moment, Capybara supports [Selenium 2.0+
391
- (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
392
- *not* Selenium RC. In order to use Selenium, you'll need to install the
393
- `selenium-webdriver` gem, and add it to your Gemfile if you're using bundler.
394
- Provided Firefox is installed, everything is set up for you, and you should be
395
- able to start using Selenium right away.
396
-
397
- **Note**: drivers which run the server in a different thread may not share the
398
- same transaction as your tests, causing data not to be shared between your test
399
- and test server, see "Transactions and database setup" below.
400
-
401
- ### <a name="capybara-webkit"></a>Capybara-webkit
390
+ Capybara supports [Selenium 3.5+
391
+ (Webdriver)](https://www.seleniumhq.org/projects/webdriver/).
392
+ In order to use Selenium, you'll need to install the `selenium-webdriver` gem,
393
+ and add it to your Gemfile if you're using bundler.
402
394
 
403
- The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
404
- testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
405
- It is significantly faster than drivers like Selenium since it does not load an entire browser.
395
+ Capybara pre-registers a number of named drivers that use Selenium - they are:
406
396
 
407
- You can install it with:
397
+ * :selenium => Selenium driving Firefox
398
+ * :selenium_headless => Selenium driving Firefox in a headless configuration
399
+ * :selenium_chrome => Selenium driving Chrome
400
+ * :selenium_chrome_headless => Selenium driving Chrome in a headless configuration
408
401
 
409
- ```bash
410
- gem install capybara-webkit
411
- ```
402
+ These should work (with relevant software installation) in a local desktop configuration but you may
403
+ need to customize them if using in a CI environment where additional options may need to be passed
404
+ to the browsers. See the section on adding and configuring drivers.
412
405
 
413
- And you can use it by:
414
406
 
415
- ```ruby
416
- Capybara.javascript_driver = :webkit
417
- ```
418
-
419
- ### <a name="poltergeist"></a>Poltergeist
420
-
421
- [Poltergeist](https://github.com/teampoltergeist/poltergeist) is another
422
- headless driver which integrates Capybara with
423
- [PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
424
- require Xvfb to run on your CI server. It will also detect and report
425
- any Javascript errors that happen within the page.
407
+ **Note**: drivers which run the server in a different thread may not share the
408
+ same transaction as your tests, causing data not to be shared between your test
409
+ and test server, see [Transactions and database setup](#transactions-and-database-setup) below.
426
410
 
427
411
  ## <a name="the-dsl"></a>The DSL
428
412
 
@@ -617,21 +601,31 @@ In drivers which support it, you can easily execute JavaScript:
617
601
  page.execute_script("$('body').empty()")
618
602
  ```
619
603
 
620
- For simple expressions, you can return the result of the script. Note
621
- that this may break with more complicated expressions:
604
+ For simple expressions, you can return the result of the script.
622
605
 
623
606
  ```ruby
624
607
  result = page.evaluate_script('4 + 4');
625
608
  ```
626
609
 
610
+ For more complicated scripts you'll need to write them as one expression.
611
+
612
+ ```ruby
613
+ result = page.evaluate_script(<<~JS, 3, element)
614
+ (function(n, el){
615
+ var val = parseInt(el.value, 10);
616
+ return n+val;
617
+ })(arguments[0], arguments[1])
618
+ JS
619
+ ```
620
+
627
621
  ### <a name="modals"></a>Modals
628
622
 
629
- In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
623
+ In drivers which support it, you can accept, dismiss and respond to alerts, confirms, and prompts.
630
624
 
631
- You can accept or dismiss alert messages by wrapping the code that produces an alert in a block:
625
+ You can accept alert messages by wrapping the code that produces an alert in a block:
632
626
 
633
627
  ```ruby
634
- accept_alert do
628
+ accept_alert 'optional text or regex' do
635
629
  click_link('Show Alert')
636
630
  end
637
631
  ```
@@ -639,7 +633,13 @@ end
639
633
  You can accept or dismiss a confirmation by wrapping it in a block, as well:
640
634
 
641
635
  ```ruby
642
- dismiss_confirm do
636
+ accept_confirm 'optional text' do
637
+ click_link('Show Confirm')
638
+ end
639
+ ```
640
+
641
+ ```ruby
642
+ dismiss_confirm 'optional text' do
643
643
  click_link('Show Confirm')
644
644
  end
645
645
  ```
@@ -647,7 +647,13 @@ end
647
647
  You can accept or dismiss prompts as well, and also provide text to fill in for the response:
648
648
 
649
649
  ```ruby
650
- accept_prompt(with: 'Linus Torvalds') do
650
+ accept_prompt('optional text', with: 'Linus Torvalds') do
651
+ click_link('Show Prompt About Linux')
652
+ end
653
+ ```
654
+
655
+ ```ruby
656
+ dismiss_prompt('optional text') do
651
657
  click_link('Show Prompt About Linux')
652
658
  end
653
659
  ```
@@ -697,6 +703,148 @@ Screenshots are saved to `Capybara.save_path`, relative to the app directory.
697
703
  If you have required `capybara/rails`, `Capybara.save_path` will default to
698
704
  `tmp/capybara`.
699
705
 
706
+ ## <a name="selectors"></a>Selectors
707
+
708
+ Helpers and matchers that accept Selectors share a common method signature that
709
+ includes:
710
+
711
+ 1. a positional Name argument
712
+ 2. a positional Locator argument
713
+ 3. keyword Filter arguments
714
+ 4. a predicate Filter block argument
715
+
716
+ These arguments are usually optional in one way or another.
717
+
718
+ ### <a name="selectors-name"></a>Name
719
+
720
+ The name argument determines the Selector to use. The argument is optional when
721
+ a helper explicitly conveys the selector name (for example, [`find_field`][]
722
+ uses `:field`, [`find_link`][] uses `:link`, etc):
723
+
724
+ ```ruby
725
+ page.html # => '<a href="/">Home</a>'
726
+
727
+ page.find(:link) == page.find_link
728
+
729
+ page.html # => '<input>'
730
+
731
+ page.find(:field) == page.find_field
732
+ ```
733
+
734
+ ### <a name="selectors-locator"></a>Locator
735
+
736
+ The locator argument usually represents information that can most meaningfully
737
+ distinguish an element that matches the selector from an element that does not:
738
+
739
+ ```ruby
740
+ page.html # => '<div id="greeting">Hello world</div>'
741
+
742
+ page.find(:css, 'div').text # => 'Hello world'
743
+ page.find(:xpath, './/div').text # => 'Hello world'
744
+ ```
745
+
746
+ General purpose finder methods like [`find`][] and [`all`][] can accept the
747
+ locator as their first positional argument when the method can infer the default
748
+ value from the [`Capybara.default_selector`][] configuration:
749
+
750
+ ```ruby
751
+ page.html # => '<div id="greeting">Hello world</div>'
752
+
753
+ Capybara.default_selector = :css
754
+
755
+ page.find('div').text # => 'Hello world'
756
+
757
+ Capybara.default_selector = :xpath
758
+
759
+ page.find('.//div').text # => 'Hello world'
760
+ ```
761
+
762
+ The locator argument's semantics are context-specific, and depend on the
763
+ selector. The types of arguments are varied. Some selectors support `String` or
764
+ `Regexp` arguments, while others like `:table_row` support `Array<String>` and
765
+ `Hash<String, String>`:
766
+
767
+ ```ruby
768
+ page.html # => '<label for="greeting">Greeting</label>
769
+ <input id="greeting" name="content">'
770
+
771
+ # find by the <input> element's [id] attribute
772
+ page.find(:id, 'greeting') == page.find_by_id('greeting') # => true
773
+
774
+ # find by the <input> element's [id] attribute
775
+ page.find(:field, 'greeting') == page.find_field('greeting') # => true
776
+
777
+ # find by the <input> element's [name] attribute
778
+ page.find(:field, 'content') == page.find_field('content') # => true
779
+
780
+ # find by the <label> element's text
781
+ page.find(:field, 'Greeting') == page.find_field('Greeting') # => true
782
+
783
+ page.html # => '<table>
784
+ <tr>
785
+ <th>A</th>
786
+ <th>B</th>
787
+ </tr>
788
+ <tr>
789
+ <td>1</td>
790
+ <td>2</td>
791
+ </tr>
792
+ </table>'
793
+
794
+ # find by <td> content
795
+ page.find(:table_row, ['1', '2']) == page.find(:css, 'tr:last-of-type') # => true
796
+
797
+ # find by <th> content paired with corresponding <td> content
798
+ page.find(:table_row, 'A' => '1') == page.find(:table_row, 'B' => '2') # => true
799
+ ```
800
+
801
+ ### <a name="selectors-filters"></a> Filters
802
+
803
+ All filters are optional. The supported set of keys is a mixture of both global
804
+ and context-specific filters.The supported types of values depend on the
805
+ context:
806
+
807
+ ```ruby
808
+ page.html # => '<a href="/">Home</a>'
809
+
810
+ # find by the [href] attribute
811
+ page.find_link(href: '/') == page.find_link(text: 'Home') # => true
812
+
813
+ page.html # => '<div id="element" data-attribute="value">Content</div>'
814
+
815
+ # find by the [id] attribute
816
+ page.find(id: 'element') == page.find(text: 'Content') # => true
817
+
818
+ # find by the [data-attribute] attribute
819
+ page.find(:element, 'data-attribute': /value/) == page.find(text: 'Content') # => true
820
+
821
+ page.html # => '<input type="checkbox">'
822
+
823
+ # find by the absence of the [checked] attribute
824
+ page.find_field(checked: false) == page.find_field(unchecked: true) # => true
825
+ ```
826
+
827
+ The predicate block is always optional. When there are results for a selector
828
+ query, the block is called with each item in the result set. When the block
829
+ evaluates to true, the item is included from the result set. Otherwise, the item
830
+ is excluded:
831
+
832
+ ```ruby
833
+ page.html # => '<input role="switch" type="checkbox" checked>'
834
+
835
+ switch = page.find_field { |input| input["role"] == "switch" }
836
+ field = page.find_field(checked: true)
837
+
838
+ switch == field # => true
839
+ ```
840
+
841
+ [`find`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find
842
+ [`all`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:all
843
+ [`Capybara.default_selector`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2Econfigure
844
+ [`find_by_id`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_by_id
845
+ [`find_field`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_field
846
+ [`find_link`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_link
847
+
700
848
  ## <a name="matching"></a>Matching
701
849
 
702
850
  It is possible to customize how Capybara finds elements. At your disposal
@@ -777,7 +925,7 @@ expect(page).to have_content('baz')
777
925
  If clicking on the *foo* link triggers an asynchronous process, such as
778
926
  an Ajax request, which, when complete will add the *bar* link to the page,
779
927
  clicking on the *bar* link would be expected to fail, since that link doesn't
780
- exist yet. However Capybara is smart enough to retry finding the link for a
928
+ exist yet. However, Capybara is smart enough to retry finding the link for a
781
929
  brief period of time before giving up and throwing an error. The same is true of
782
930
  the next line, which looks for the content *baz* on the page; it will retry
783
931
  looking for that content for a brief time. You can adjust how long this period
@@ -791,13 +939,25 @@ Be aware that because of this behaviour, the following two statements are **not*
791
939
  equivalent, and you should **always** use the latter!
792
940
 
793
941
  ```ruby
794
- !page.has_xpath?('a')
795
- page.has_no_xpath?('a')
942
+ # Given use of a driver where the page is loaded when visit returns
943
+ # and that Capybara.predicates_wait is `true`
944
+ # consider a page where the `a` tag is removed through AJAX after 1s
945
+ visit(some_path)
946
+ !page.has_xpath?('a') # is false
947
+ page.has_no_xpath?('a') # is true
796
948
  ```
797
949
 
798
- The former would immediately fail because the content has not yet been removed.
799
- Only the latter would wait for the asynchronous process to remove the content
800
- from the page.
950
+ First expression:
951
+ - `has_xpath?('a')` is called right after `visit` returns. It is `true` because the link has not yet been removed
952
+ - Capybara does not wait upon successful predicates/assertions, therefore **has_xpath? returns `true` immediately**
953
+ - The expression returns `false` (because it is negated with the leading `!`)
954
+
955
+ Second expression:
956
+ - `has_no_xpath?('a')` is called right after `visit` returns. It is `false` because the link has not yet been removed.
957
+ - Capybara waits upon failed predicates/assertions, therefore **has_no_xpath? does not return `false` immediately**
958
+ - Capybara will periodically re-check the predicate/assertion up to the `default_max_wait_time` defined
959
+ - after 1s, the predicate becomes `true` (because the link has been removed)
960
+ - The expression returns `true`
801
961
 
802
962
  Capybara's RSpec matchers, however, are smart enough to handle either form.
803
963
  The two following statements are functionally equivalent:
@@ -932,12 +1092,17 @@ Capybara.default_selector = :xpath
932
1092
  find('.//ul/li').text
933
1093
  ```
934
1094
 
935
- Capybara allows you to add custom selectors, which can be very useful if you
936
- find yourself using the same kinds of selectors very often:
1095
+ Capybara provides a number of other built-in selector types. The full list, along
1096
+ with applicable filters, can be seen at [built-in selectors](https://www.rubydoc.info/github/teamcapybara/capybara/Capybara/Selector)
1097
+
1098
+ Capybara also allows you to add custom selectors, which can be very useful if you
1099
+ find yourself using the same kinds of selectors very often. The examples below are very
1100
+ simple, and there are many available features not demonstrated. For more in-depth examples
1101
+ please see Capybaras built-in selector definitions.
937
1102
 
938
1103
  ```ruby
939
- Capybara.add_selector(:id) do
940
- xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
1104
+ Capybara.add_selector(:my_attribute) do
1105
+ xpath { |id| XPath.descendant[XPath.attr(:my_attribute) == id.to_s] }
941
1106
  end
942
1107
 
943
1108
  Capybara.add_selector(:row) do
@@ -954,9 +1119,9 @@ an XPath expression generated through the XPath gem. You can now use these
954
1119
  selectors like this:
955
1120
 
956
1121
  ```ruby
957
- find(:id, 'post_123')
958
- find(:row, 3)
959
- find(:flash_type, :notice)
1122
+ find(:my_attribute, 'post_123') # find element with matching attribute
1123
+ find(:row, 3) # find 3rd row in table body
1124
+ find(:flash_type, :notice) # find element with id of 'flash' and class of 'notice'
960
1125
  ```
961
1126
 
962
1127
  ## <a name="beware-the-xpath--trap"></a>Beware the XPath // trap
@@ -1002,6 +1167,7 @@ end
1002
1167
  However, it's also possible to give this configuration a different name.
1003
1168
 
1004
1169
  ```ruby
1170
+ # Note: Capybara registers this by default
1005
1171
  Capybara.register_driver :selenium_chrome do |app|
1006
1172
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
1007
1173
  end
@@ -1047,6 +1213,13 @@ additional info about how the underlying driver can be configured.
1047
1213
  are testing for specific server errors and using multiple sessions make sure to test for the
1048
1214
  errors using the initial session (usually :default)
1049
1215
 
1216
+ * If WebMock is enabled, you may encounter a "Too many open files"
1217
+ error. A simple `page.find` call may cause thousands of HTTP requests
1218
+ until the timeout occurs. By default, WebMock will cause each of these
1219
+ requests to spawn a new connection. To work around this problem, you
1220
+ may need to [enable WebMock's `net_http_connect_on_start: true`
1221
+ parameter](https://github.com/bblimke/webmock/blob/master/README.md#connecting-on-nethttpstart).
1222
+
1050
1223
  ## <a name="threadsafe"></a>"Threadsafe" mode
1051
1224
 
1052
1225
  In normal mode most of Capybara's configuration options are global settings which can cause issues
@@ -7,11 +7,12 @@ module Capybara
7
7
  class Config
8
8
  extend Forwardable
9
9
 
10
- OPTIONS = %i[app reuse_server threadsafe default_wait_time server default_driver javascript_driver].freeze
10
+ OPTIONS = %i[
11
+ app reuse_server threadsafe server default_driver javascript_driver use_html5_parsing allow_gumbo
12
+ ].freeze
11
13
 
12
- attr_accessor :app
13
- attr_reader :reuse_server, :threadsafe
14
- attr_reader :session_options
14
+ attr_accessor :app, :use_html5_parsing
15
+ attr_reader :reuse_server, :threadsafe, :session_options # rubocop:disable Style/BisectedAttrAccessor
15
16
  attr_writer :default_driver, :javascript_driver
16
17
 
17
18
  SessionConfig::OPTIONS.each do |method|
@@ -23,10 +24,13 @@ module Capybara
23
24
  @javascript_driver = nil
24
25
  end
25
26
 
26
- attr_writer :reuse_server
27
+ attr_writer :reuse_server # rubocop:disable Style/BisectedAttrAccessor
27
28
 
28
29
  def threadsafe=(bool)
29
- 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
33
+
30
34
  @threadsafe = bool
31
35
  end
32
36
 
@@ -57,7 +61,7 @@ module Capybara
57
61
  @server = if name.respond_to? :call
58
62
  name
59
63
  elsif options
60
- 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) }
61
65
  else
62
66
  Capybara.servers[name.to_sym]
63
67
  end
@@ -79,10 +83,22 @@ module Capybara
79
83
  @javascript_driver || :selenium
80
84
  end
81
85
 
82
- def deprecate(method, alternate_method, once = false)
86
+ def deprecate(method, alternate_method, once: false)
83
87
  @deprecation_notified ||= {}
84
- warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once && @deprecation_notified[method]
88
+ unless once && @deprecation_notified[method]
89
+ Capybara::Helpers.warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead: #{Capybara::Helpers.filter_backtrace(caller)}"
90
+ end
85
91
  @deprecation_notified[method] = true
86
92
  end
93
+
94
+ def allow_gumbo=(val)
95
+ deprecate('allow_gumbo=', 'use_html5_parsing=')
96
+ self.use_html5_parsing = val
97
+ end
98
+
99
+ def allow_gumbo
100
+ deprecate('allow_gumbo', 'use_html5_parsing')
101
+ use_html5_parsing
102
+ end
87
103
  end
88
104
  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