capybara 2.7.0 → 3.35.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (318) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +1 -0
  3. data/History.md +1147 -11
  4. data/License.txt +1 -1
  5. data/README.md +252 -131
  6. data/lib/capybara/config.rb +92 -0
  7. data/lib/capybara/cucumber.rb +3 -3
  8. data/lib/capybara/driver/base.rb +52 -21
  9. data/lib/capybara/driver/node.rb +48 -14
  10. data/lib/capybara/dsl.rb +16 -9
  11. data/lib/capybara/helpers.rb +72 -81
  12. data/lib/capybara/minitest/spec.rb +267 -0
  13. data/lib/capybara/minitest.rb +385 -0
  14. data/lib/capybara/node/actions.rb +337 -89
  15. data/lib/capybara/node/base.rb +50 -32
  16. data/lib/capybara/node/document.rb +19 -3
  17. data/lib/capybara/node/document_matchers.rb +22 -24
  18. data/lib/capybara/node/element.rb +388 -125
  19. data/lib/capybara/node/finders.rb +231 -121
  20. data/lib/capybara/node/matchers.rb +503 -217
  21. data/lib/capybara/node/simple.rb +64 -27
  22. data/lib/capybara/queries/ancestor_query.rb +27 -0
  23. data/lib/capybara/queries/base_query.rb +87 -11
  24. data/lib/capybara/queries/current_path_query.rb +24 -24
  25. data/lib/capybara/queries/match_query.rb +15 -10
  26. data/lib/capybara/queries/selector_query.rb +675 -81
  27. data/lib/capybara/queries/sibling_query.rb +26 -0
  28. data/lib/capybara/queries/style_query.rb +45 -0
  29. data/lib/capybara/queries/text_query.rb +88 -20
  30. data/lib/capybara/queries/title_query.rb +9 -11
  31. data/lib/capybara/rack_test/browser.rb +63 -39
  32. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  33. data/lib/capybara/rack_test/driver.rb +26 -16
  34. data/lib/capybara/rack_test/errors.rb +6 -0
  35. data/lib/capybara/rack_test/form.rb +73 -58
  36. data/lib/capybara/rack_test/node.rb +187 -67
  37. data/lib/capybara/rails.rb +4 -8
  38. data/lib/capybara/registration_container.rb +44 -0
  39. data/lib/capybara/registrations/drivers.rb +42 -0
  40. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  41. data/lib/capybara/registrations/servers.rb +45 -0
  42. data/lib/capybara/result.rb +142 -14
  43. data/lib/capybara/rspec/features.rb +17 -42
  44. data/lib/capybara/rspec/matcher_proxies.rb +82 -0
  45. data/lib/capybara/rspec/matchers/base.rb +111 -0
  46. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  47. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  48. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  49. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  50. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  51. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  52. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  53. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  54. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  55. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  56. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  57. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  58. data/lib/capybara/rspec/matchers.rb +143 -244
  59. data/lib/capybara/rspec.rb +10 -12
  60. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  61. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  62. data/lib/capybara/selector/css.rb +102 -0
  63. data/lib/capybara/selector/definition/button.rb +63 -0
  64. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  65. data/lib/capybara/selector/definition/css.rb +10 -0
  66. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  67. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  68. data/lib/capybara/selector/definition/element.rb +28 -0
  69. data/lib/capybara/selector/definition/field.rb +40 -0
  70. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  71. data/lib/capybara/selector/definition/file_field.rb +13 -0
  72. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  73. data/lib/capybara/selector/definition/frame.rb +17 -0
  74. data/lib/capybara/selector/definition/id.rb +6 -0
  75. data/lib/capybara/selector/definition/label.rb +62 -0
  76. data/lib/capybara/selector/definition/link.rb +54 -0
  77. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  78. data/lib/capybara/selector/definition/option.rb +27 -0
  79. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  80. data/lib/capybara/selector/definition/select.rb +81 -0
  81. data/lib/capybara/selector/definition/table.rb +109 -0
  82. data/lib/capybara/selector/definition/table_row.rb +21 -0
  83. data/lib/capybara/selector/definition/xpath.rb +5 -0
  84. data/lib/capybara/selector/definition.rb +278 -0
  85. data/lib/capybara/selector/filter.rb +3 -46
  86. data/lib/capybara/selector/filter_set.rb +124 -0
  87. data/lib/capybara/selector/filters/base.rb +77 -0
  88. data/lib/capybara/selector/filters/expression_filter.rb +22 -0
  89. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  90. data/lib/capybara/selector/filters/node_filter.rb +31 -0
  91. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  92. data/lib/capybara/selector/selector.rb +155 -0
  93. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  94. data/lib/capybara/selector.rb +232 -369
  95. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  96. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  98. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  99. data/lib/capybara/selenium/driver.rb +380 -142
  100. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
  101. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
  102. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
  103. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  104. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  105. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  106. data/lib/capybara/selenium/extensions/find.rb +110 -0
  107. data/lib/capybara/selenium/extensions/html5_drag.rb +228 -0
  108. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  109. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  110. data/lib/capybara/selenium/logger_suppressor.rb +40 -0
  111. data/lib/capybara/selenium/node.rb +528 -97
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +104 -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/action_pauser.rb +26 -0
  118. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  119. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  120. data/lib/capybara/selenium/patches/logs.rb +45 -0
  121. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  122. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  123. data/lib/capybara/server/animation_disabler.rb +63 -0
  124. data/lib/capybara/server/checker.rb +44 -0
  125. data/lib/capybara/server/middleware.rb +71 -0
  126. data/lib/capybara/server.rb +74 -71
  127. data/lib/capybara/session/config.rb +126 -0
  128. data/lib/capybara/session/matchers.rb +44 -27
  129. data/lib/capybara/session.rb +500 -297
  130. data/lib/capybara/spec/fixtures/no_extension +1 -0
  131. data/lib/capybara/spec/public/jquery.js +5 -5
  132. data/lib/capybara/spec/public/offset.js +6 -0
  133. data/lib/capybara/spec/public/test.js +168 -14
  134. data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
  135. data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
  136. data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
  137. data/lib/capybara/spec/session/all_spec.rb +179 -59
  138. data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
  140. data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
  141. data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
  142. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  143. data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
  144. data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
  145. data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
  146. data/lib/capybara/spec/session/body_spec.rb +12 -13
  147. data/lib/capybara/spec/session/check_spec.rb +168 -41
  148. data/lib/capybara/spec/session/choose_spec.rb +75 -23
  149. data/lib/capybara/spec/session/click_button_spec.rb +243 -175
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
  151. data/lib/capybara/spec/session/click_link_spec.rb +100 -53
  152. data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
  153. data/lib/capybara/spec/session/current_url_spec.rb +61 -35
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
  162. data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
  163. data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
  164. data/lib/capybara/spec/session/find_button_spec.rb +37 -18
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
  166. data/lib/capybara/spec/session/find_field_spec.rb +57 -34
  167. data/lib/capybara/spec/session/find_link_spec.rb +47 -10
  168. data/lib/capybara/spec/session/find_spec.rb +290 -144
  169. data/lib/capybara/spec/session/first_spec.rb +91 -48
  170. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  171. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  172. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
  174. data/lib/capybara/spec/session/go_back_spec.rb +3 -2
  175. data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +76 -19
  180. data/lib/capybara/spec/session/has_css_spec.rb +277 -131
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
  182. data/lib/capybara/spec/session/has_field_spec.rb +177 -107
  183. data/lib/capybara/spec/session/has_link_spec.rb +13 -12
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
  185. data/lib/capybara/spec/session/has_select_spec.rb +191 -95
  186. data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +172 -5
  189. data/lib/capybara/spec/session/has_text_spec.rb +126 -60
  190. data/lib/capybara/spec/session/has_title_spec.rb +35 -12
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
  192. data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
  193. data/lib/capybara/spec/session/html_spec.rb +14 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  195. data/lib/capybara/spec/session/node_spec.rb +1028 -131
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  197. data/lib/capybara/spec/session/refresh_spec.rb +34 -0
  198. data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
  199. data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +11 -15
  202. data/lib/capybara/spec/session/save_page_spec.rb +42 -55
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  206. data/lib/capybara/spec/session/select_spec.rb +112 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +71 -8
  208. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  209. data/lib/capybara/spec/session/text_spec.rb +38 -23
  210. data/lib/capybara/spec/session/title_spec.rb +17 -5
  211. data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
  212. data/lib/capybara/spec/session/unselect_spec.rb +44 -43
  213. data/lib/capybara/spec/session/visit_spec.rb +99 -32
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
  216. data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
  217. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +39 -30
  218. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
  219. data/lib/capybara/spec/session/window/window_spec.rb +121 -73
  220. data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
  221. data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
  222. data/lib/capybara/spec/session/within_spec.rb +76 -43
  223. data/lib/capybara/spec/spec_helper.rb +67 -33
  224. data/lib/capybara/spec/test_app.rb +85 -36
  225. data/lib/capybara/spec/views/animated.erb +49 -0
  226. data/lib/capybara/spec/views/buttons.erb +1 -1
  227. data/lib/capybara/spec/views/fieldsets.erb +1 -1
  228. data/lib/capybara/spec/views/form.erb +227 -20
  229. data/lib/capybara/spec/views/frame_child.erb +10 -2
  230. data/lib/capybara/spec/views/frame_one.erb +2 -1
  231. data/lib/capybara/spec/views/frame_parent.erb +2 -2
  232. data/lib/capybara/spec/views/frame_two.erb +1 -1
  233. data/lib/capybara/spec/views/header_links.erb +1 -1
  234. data/lib/capybara/spec/views/host_links.erb +1 -1
  235. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  236. data/lib/capybara/spec/views/obscured.erb +47 -0
  237. data/lib/capybara/spec/views/offset.erb +32 -0
  238. data/lib/capybara/spec/views/path.erb +1 -1
  239. data/lib/capybara/spec/views/popup_one.erb +1 -1
  240. data/lib/capybara/spec/views/popup_two.erb +1 -1
  241. data/lib/capybara/spec/views/postback.erb +1 -1
  242. data/lib/capybara/spec/views/react.erb +45 -0
  243. data/lib/capybara/spec/views/scroll.erb +20 -0
  244. data/lib/capybara/spec/views/spatial.erb +31 -0
  245. data/lib/capybara/spec/views/tables.erb +69 -2
  246. data/lib/capybara/spec/views/with_animation.erb +82 -0
  247. data/lib/capybara/spec/views/with_base_tag.erb +1 -1
  248. data/lib/capybara/spec/views/with_count.erb +1 -1
  249. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  250. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  251. data/lib/capybara/spec/views/with_hover.erb +7 -1
  252. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  253. data/lib/capybara/spec/views/with_html.erb +100 -10
  254. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  255. data/lib/capybara/spec/views/with_html_entities.erb +1 -1
  256. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  257. data/lib/capybara/spec/views/with_js.erb +49 -3
  258. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  259. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  260. data/lib/capybara/spec/views/with_scope.erb +1 -1
  261. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  262. data/lib/capybara/spec/views/with_simple_html.erb +1 -1
  263. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  264. data/lib/capybara/spec/views/with_title.erb +1 -1
  265. data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
  266. data/lib/capybara/spec/views/with_windows.erb +7 -1
  267. data/lib/capybara/spec/views/within_frames.erb +6 -3
  268. data/lib/capybara/version.rb +2 -1
  269. data/lib/capybara/window.rb +39 -21
  270. data/lib/capybara.rb +208 -186
  271. data/spec/basic_node_spec.rb +52 -39
  272. data/spec/capybara_spec.rb +72 -50
  273. data/spec/css_builder_spec.rb +101 -0
  274. data/spec/css_splitter_spec.rb +38 -0
  275. data/spec/dsl_spec.rb +81 -61
  276. data/spec/filter_set_spec.rb +46 -0
  277. data/spec/fixtures/capybara.csv +1 -0
  278. data/spec/fixtures/certificate.pem +25 -0
  279. data/spec/fixtures/key.pem +27 -0
  280. data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
  281. data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
  282. data/spec/minitest_spec.rb +164 -0
  283. data/spec/minitest_spec_spec.rb +162 -0
  284. data/spec/per_session_config_spec.rb +68 -0
  285. data/spec/rack_test_spec.rb +189 -96
  286. data/spec/regexp_dissassembler_spec.rb +250 -0
  287. data/spec/result_spec.rb +143 -13
  288. data/spec/rspec/features_spec.rb +38 -32
  289. data/spec/rspec/scenarios_spec.rb +9 -7
  290. data/spec/rspec/shared_spec_matchers.rb +959 -0
  291. data/spec/rspec/views_spec.rb +9 -3
  292. data/spec/rspec_matchers_spec.rb +62 -0
  293. data/spec/rspec_spec.rb +127 -30
  294. data/spec/sauce_spec_chrome.rb +43 -0
  295. data/spec/selector_spec.rb +458 -37
  296. data/spec/selenium_spec_chrome.rb +196 -9
  297. data/spec/selenium_spec_chrome_remote.rb +100 -0
  298. data/spec/selenium_spec_edge.rb +47 -0
  299. data/spec/selenium_spec_firefox.rb +210 -0
  300. data/spec/selenium_spec_firefox_remote.rb +80 -0
  301. data/spec/selenium_spec_ie.rb +150 -0
  302. data/spec/selenium_spec_safari.rb +148 -0
  303. data/spec/server_spec.rb +200 -101
  304. data/spec/session_spec.rb +91 -0
  305. data/spec/shared_selenium_node.rb +83 -0
  306. data/spec/shared_selenium_session.rb +558 -0
  307. data/spec/spec_helper.rb +94 -2
  308. data/spec/xpath_builder_spec.rb +93 -0
  309. metadata +420 -60
  310. data/lib/capybara/query.rb +0 -7
  311. data/lib/capybara/spec/session/assert_current_path.rb +0 -60
  312. data/lib/capybara/spec/session/assert_selector.rb +0 -148
  313. data/lib/capybara/spec/session/assert_text.rb +0 -196
  314. data/lib/capybara/spec/session/assert_title.rb +0 -70
  315. data/lib/capybara/spec/session/source_spec.rb +0 -0
  316. data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
  317. data/spec/rspec/matchers_spec.rb +0 -827
  318. data/spec/selenium_spec.rb +0 -151
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,23 @@
1
1
  # Capybara
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/jnicklas/capybara.svg)](https://travis-ci.org/jnicklas/capybara)
4
- [![Dependency Status](https://gemnasium.com/jnicklas/capybara.svg)](https://gemnasium.com/jnicklas/capybara)
5
- [![Code Climate](https://codeclimate.com/github/jnicklas/capybara.svg)](https://codeclimate.com/github/jnicklas/capybara)
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)
5
+ [![Code Climate](https://codeclimate.com/github/teamcapybara/capybara.svg)](https://codeclimate.com/github/teamcapybara/capybara)
6
+ [![Coverage Status](https://coveralls.io/repos/github/teamcapybara/capybara/badge.svg?branch=master)](https://coveralls.io/github/teamcapybara/capybara?branch=master)
7
+ [![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)
8
+ [![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)
6
9
 
7
10
  Capybara helps you test web applications by simulating how a real user would
8
11
  interact with your app. It is agnostic about the driver running your tests and
9
12
  comes with Rack::Test and Selenium support built in. WebKit is supported
10
13
  through an external gem.
11
14
 
15
+ ## Support Capybara
16
+
17
+ If you and/or your company find value in Capybara and would like to contribute financially to its ongoing maintenance and development, please visit
18
+ <a href="https://www.patreon.com/capybara">Patreon</a>
19
+
20
+
12
21
  **Need help?** Ask on the mailing list (please do not open an issue on
13
22
  GitHub): http://groups.google.com/group/ruby-capybara
14
23
 
@@ -19,13 +28,13 @@ GitHub): http://groups.google.com/group/ruby-capybara
19
28
  - [Using Capybara with Cucumber](#using-capybara-with-cucumber)
20
29
  - [Using Capybara with RSpec](#using-capybara-with-rspec)
21
30
  - [Using Capybara with Test::Unit](#using-capybara-with-testunit)
22
- - [Using Capybara with MiniTest::Spec](#using-capybara-with-minitestspec)
31
+ - [Using Capybara with Minitest](#using-capybara-with-minitest)
32
+ - [Using Capybara with Minitest::Spec](#using-capybara-with-minitestspec)
23
33
  - [Drivers](#drivers)
24
34
  - [Selecting the Driver](#selecting-the-driver)
25
35
  - [RackTest](#racktest)
26
36
  - [Selenium](#selenium)
27
- - [Capybara-webkit](#capybara-webkit)
28
- - [Poltergeist](#poltergeist)
37
+ - [Apparition](#apparition)
29
38
  - [The DSL](#the-dsl)
30
39
  - [Navigating](#navigating)
31
40
  - [Clicking links and buttons](#clicking-links-and-buttons)
@@ -44,11 +53,14 @@ GitHub): http://groups.google.com/group/ruby-capybara
44
53
  - [Asynchronous JavaScript (Ajax and friends)](#asynchronous-javascript-ajax-and-friends)
45
54
  - [Using the DSL elsewhere](#using-the-dsl-elsewhere)
46
55
  - [Calling remote servers](#calling-remote-servers)
47
- - [Using the sessions manually](#using-the-sessions-manually)
56
+ - [Using sessions](#using-sessions)
57
+ - [Named sessions](#named-sessions)
58
+ - [Using sessions manually](#using-sessions-manually)
48
59
  - [XPath, CSS and selectors](#xpath-css-and-selectors)
49
60
  - [Beware the XPath // trap](#beware-the-xpath--trap)
50
61
  - [Configuring and adding drivers](#configuring-and-adding-drivers)
51
62
  - [Gotchas:](#gotchas)
63
+ - ["Threadsafe" mode](#threadsafe-mode)
52
64
  - [Development](#development)
53
65
 
54
66
  ## <a name="key-benefits"></a>Key benefits
@@ -62,24 +74,19 @@ GitHub): http://groups.google.com/group/ruby-capybara
62
74
 
63
75
  ## <a name="setup"></a>Setup
64
76
 
65
- Capybara requires Ruby 1.9.3 or later. To install, add this line to your
77
+ Capybara requires Ruby 2.5.0 or later. To install, add this line to your
66
78
  `Gemfile` and run `bundle install`:
67
79
 
68
80
  ```ruby
69
81
  gem 'capybara'
70
82
  ```
71
83
 
72
- **Note:** If using Ruby < 2.0 you will also need to limit the version of mime-types to < 3.0
73
-
74
84
  If the application that you are testing is a Rails app, add this line to your test helper file:
75
85
 
76
86
  ```ruby
77
87
  require 'capybara/rails'
78
88
  ```
79
89
 
80
- **Note:** In Rails 4.0/4.1 the default test environment (`config/environments/test.rb`) is [not threadsafe](https://github.com/rails/rails/issues/15089).
81
- If you experience random errors about missing constants, add `config.allow_concurrency = false` to `config/environments/test.rb`.
82
-
83
90
  If the application that you are testing is a Rack app, but not Rails, set Capybara.app to your Rack app:
84
91
 
85
92
  ```ruby
@@ -87,7 +94,13 @@ Capybara.app = MyRackApp
87
94
  ```
88
95
 
89
96
  If you need to test JavaScript, or if your app interacts with (or is located at)
90
- a remote URL, you'll need to [use a different driver](#drivers).
97
+ a remote URL, you'll need to [use a different driver](#drivers). If using Rails 5.0+, but not using the Rails system tests from 5.1, you'll probably also
98
+ want to swap the "server" used to launch your app to Puma in order to match Rails defaults.
99
+
100
+ ```ruby
101
+ Capybara.server = :puma # Until your setup is working
102
+ Capybara.server = :puma, { Silent: true } # To clean up your test output
103
+ ```
91
104
 
92
105
  ## <a name="using-capybara-with-cucumber"></a>Using Capybara with Cucumber
93
106
 
@@ -104,8 +117,8 @@ You can use the Capybara DSL in your steps, like so:
104
117
  ```ruby
105
118
  When /I sign in/ do
106
119
  within("#session") do
107
- fill_in 'Email', :with => 'user@example.com'
108
- fill_in 'Password', :with => 'password'
120
+ fill_in 'Email', with: 'user@example.com'
121
+ fill_in 'Password', with: 'password'
109
122
  end
110
123
  click_button 'Sign in'
111
124
  end
@@ -121,40 +134,39 @@ Scenario: do something Ajaxy
121
134
  ...
122
135
  ```
123
136
 
124
- There are also explicit `@selenium` and `@rack_test`
125
- tags set up for you.
137
+ There are also explicit tags for each registered driver set up for you (`@selenium`, `@rack_test`, etc).
126
138
 
127
139
  ## <a name="using-capybara-with-rspec"></a>Using Capybara with RSpec
128
140
 
129
- Load RSpec 2.x support by adding the following line (typically to your
141
+ Load RSpec 3.5+ support by adding the following line (typically to your
130
142
  `spec_helper.rb` file):
131
143
 
132
144
  ```ruby
133
145
  require 'capybara/rspec'
134
146
  ```
135
147
 
136
- If you are using Rails, put your Capybara specs in `spec/features` (only works
148
+ If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works
137
149
  if [you have it configured in
138
- RSpec](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#file-type-inference-disabled))
150
+ RSpec](https://relishapp.com/rspec/rspec-rails/v/4-0/docs/directory-structure))
139
151
  and if you have your Capybara specs in a different directory, then tag the
140
- example groups with `:type => :feature`.
152
+ example groups with `type: :feature` or `type: :system` depending on which type of test you're writing.
141
153
 
142
154
  If you are not using Rails, tag all the example groups in which you want to use
143
- Capybara with `:type => :feature`.
155
+ Capybara with `type: :feature`.
144
156
 
145
157
  You can now write your specs like so:
146
158
 
147
159
  ```ruby
148
- describe "the signin process", :type => :feature do
160
+ describe "the signin process", type: :feature do
149
161
  before :each do
150
- User.make(:email => 'user@example.com', :password => 'password')
162
+ User.make(email: 'user@example.com', password: 'password')
151
163
  end
152
164
 
153
165
  it "signs me in" do
154
166
  visit '/sessions/new'
155
167
  within("#session") do
156
- fill_in 'Email', :with => 'user@example.com'
157
- fill_in 'Password', :with => 'password'
168
+ fill_in 'Email', with: 'user@example.com'
169
+ fill_in 'Password', with: 'password'
158
170
  end
159
171
  click_button 'Sign in'
160
172
  expect(page).to have_content 'Success'
@@ -162,14 +174,14 @@ describe "the signin process", :type => :feature do
162
174
  end
163
175
  ```
164
176
 
165
- Use `:js => true` to switch to the `Capybara.javascript_driver`
177
+ Use `js: true` to switch to the `Capybara.javascript_driver`
166
178
  (`:selenium` by default), or provide a `:driver` option to switch
167
179
  to one specific driver. For example:
168
180
 
169
181
  ```ruby
170
- describe 'some stuff which requires js', :js => true do
182
+ describe 'some stuff which requires js', js: true do
171
183
  it 'will use the default js driver'
172
- it 'will switch to one specific driver', :driver => :webkit
184
+ it 'will switch to one specific driver', driver: :apparition
173
185
  end
174
186
  ```
175
187
 
@@ -178,26 +190,26 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
178
190
  ```ruby
179
191
  feature "Signing in" do
180
192
  background do
181
- User.make(:email => 'user@example.com', :password => 'caplin')
193
+ User.make(email: 'user@example.com', password: 'caplin')
182
194
  end
183
195
 
184
196
  scenario "Signing in with correct credentials" do
185
197
  visit '/sessions/new'
186
198
  within("#session") do
187
- fill_in 'Email', :with => 'user@example.com'
188
- fill_in 'Password', :with => 'caplin'
199
+ fill_in 'Email', with: 'user@example.com'
200
+ fill_in 'Password', with: 'caplin'
189
201
  end
190
202
  click_button 'Sign in'
191
203
  expect(page).to have_content 'Success'
192
204
  end
193
205
 
194
- given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') }
206
+ given(:other_user) { User.make(email: 'other@example.com', password: 'rous') }
195
207
 
196
208
  scenario "Signing in as another user" do
197
209
  visit '/sessions/new'
198
210
  within("#session") do
199
- fill_in 'Email', :with => other_user.email
200
- fill_in 'Password', :with => other_user.password
211
+ fill_in 'Email', with: other_user.email
212
+ fill_in 'Password', with: other_user.password
201
213
  end
202
214
  click_button 'Sign in'
203
215
  expect(page).to have_content 'Invalid email or password'
@@ -205,11 +217,11 @@ feature "Signing in" do
205
217
  end
206
218
  ```
207
219
 
208
- `feature` is in fact just an alias for `describe ..., :type => :feature`,
220
+ `feature` is in fact just an alias for `describe ..., type: :feature`,
209
221
  `background` is an alias for `before`, `scenario` for `it`, and
210
222
  `given`/`given!` aliases for `let`/`let!`, respectively.
211
223
 
212
- Finally, Capybara matchers are supported in view specs:
224
+ Finally, Capybara matchers are also supported in view specs:
213
225
 
214
226
  ```ruby
215
227
  RSpec.describe "todos/show.html.erb", type: :view do
@@ -223,20 +235,45 @@ RSpec.describe "todos/show.html.erb", type: :view do
223
235
  end
224
236
  ```
225
237
 
238
+ **Note: When you require 'capybara/rspec' proxy methods are installed to work around name collisions between Capybara::DSL methods
239
+ `all`/`within` and the identically named built-in RSpec matchers. If you opt not to require 'capybara/rspec' you can install the proxy methods by requiring 'capybara/rspec/matcher_proxies' after requiring RSpec and 'capybara/dsl'**
240
+
226
241
  ## <a name="using-capybara-with-testunit"></a>Using Capybara with Test::Unit
227
242
 
228
- * If you are using Rails, add the following code in your `test_helper.rb`
243
+ * If you are using `Test::Unit`, define a base class for your Capybara tests
244
+ like so:
245
+
246
+ ```ruby
247
+ require 'capybara/dsl'
248
+
249
+ class CapybaraTestCase < Test::Unit::TestCase
250
+ include Capybara::DSL
251
+
252
+ def teardown
253
+ Capybara.reset_sessions!
254
+ Capybara.use_default_driver
255
+ end
256
+ end
257
+ ```
258
+
259
+ ## <a name="using-capybara-with-minitest"></a>Using Capybara with Minitest
260
+
261
+ * If you are using Rails, but not using Rails system tests, add the following code in your `test_helper.rb`
229
262
  file to make Capybara available in all test cases deriving from
230
263
  `ActionDispatch::IntegrationTest`:
231
264
 
232
265
  ```ruby
266
+ require 'capybara/rails'
267
+ require 'capybara/minitest'
268
+
233
269
  class ActionDispatch::IntegrationTest
234
270
  # Make the Capybara DSL available in all integration tests
235
271
  include Capybara::DSL
272
+ # Make `assert_*` methods behave like Minitest assertions
273
+ include Capybara::Minitest::Assertions
236
274
 
237
275
  # Reset sessions and driver between tests
238
- # Use super wherever this method is redefined in your individual test classes
239
- def teardown
276
+ teardown do
240
277
  Capybara.reset_sessions!
241
278
  Capybara.use_default_driver
242
279
  end
@@ -247,8 +284,11 @@ end
247
284
  so:
248
285
 
249
286
  ```ruby
250
- class CapybaraTestCase < Test::Unit::TestCase
287
+ require 'capybara/minitest'
288
+
289
+ class CapybaraTestCase < Minitest::Test
251
290
  include Capybara::DSL
291
+ include Capybara::Minitest::Assertions
252
292
 
253
293
  def teardown
254
294
  Capybara.reset_sessions!
@@ -274,14 +314,9 @@ class BlogTest < ActionDispatch::IntegrationTest
274
314
  end
275
315
  ```
276
316
 
277
- ## <a name="using-capybara-with-minitestspec"></a>Using Capybara with MiniTest::Spec
317
+ ## <a name="using-capybara-with-minitestspec"></a>Using Capybara with Minitest::Spec
278
318
 
279
- Set up your base class as with Test::Unit. (On Rails, the right base class
280
- could be something other than ActionDispatch::IntegrationTest.)
281
-
282
- The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec),
283
- [rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
284
- expectations for Capybara. For example:
319
+ Follow the above instructions for Minitest and additionally require capybara/minitest/spec
285
320
 
286
321
  ```ruby
287
322
  page.must_have_content('Important!')
@@ -300,12 +335,12 @@ these limitations, you can set up a different default driver for your features.
300
335
  For example if you'd prefer to run everything in Selenium, you could do:
301
336
 
302
337
  ```ruby
303
- Capybara.default_driver = :selenium
338
+ Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
304
339
  ```
305
340
 
306
- However, if you are using RSpec or Cucumber, you may instead want to consider
307
- leaving the faster `:rack_test` as the __default_driver__, and marking only those
308
- tests that require a JavaScript-capable driver using `:js => true` or
341
+ However, if you are using RSpec or Cucumber (and your app runs correctly without JS),
342
+ you may instead want to consider leaving the faster `:rack_test` as the __default_driver__, and
343
+ marking only those tests that require a JavaScript-capable driver using `js: true` or
309
344
  `@javascript`, respectively. By default, JavaScript tests are run using the
310
345
  `:selenium` driver. You can change this by setting
311
346
  `Capybara.javascript_driver`.
@@ -314,7 +349,7 @@ You can also change the driver temporarily (typically in the Before/setup and
314
349
  After/teardown blocks):
315
350
 
316
351
  ```ruby
317
- Capybara.current_driver = :webkit # temporarily select different driver
352
+ Capybara.current_driver = :apparition # temporarily select different driver
318
353
  # tests here
319
354
  Capybara.use_default_driver # switch back to default driver
320
355
  ```
@@ -341,7 +376,7 @@ RackTest can be configured with a set of headers like this:
341
376
 
342
377
  ```ruby
343
378
  Capybara.register_driver :rack_test do |app|
344
- Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' })
379
+ Capybara::RackTest::Driver.new(app, headers: { 'HTTP_USER_AGENT' => 'Capybara' })
345
380
  end
346
381
  ```
347
382
 
@@ -349,47 +384,40 @@ See the section on adding and configuring drivers.
349
384
 
350
385
  ### <a name="selenium"></a>Selenium
351
386
 
352
- At the moment, Capybara supports [Selenium 2.0
353
- (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
354
- *not* Selenium RC. In order to use Selenium, you'll need to install the
355
- `selenium-webdriver` gem, and add it to your Gemfile if you're using bundler.
356
- Provided Firefox is installed, everything is set up for you, and you should be
357
- able to start using Selenium right away.
387
+ Capybara supports [Selenium 3.5+
388
+ (Webdriver)](https://www.seleniumhq.org/projects/webdriver/).
389
+ In order to use Selenium, you'll need to install the `selenium-webdriver` gem,
390
+ and add it to your Gemfile if you're using bundler.
358
391
 
359
- **Note**: drivers which run the server in a different thread may not share the
360
- same transaction as your tests, causing data not to be shared between your test
361
- and test server, see "Transactions and database setup" below.
392
+ Capybara pre-registers a number of named drivers that use Selenium - they are:
362
393
 
363
- ### <a name="capybara-webkit"></a>Capybara-webkit
394
+ * :selenium => Selenium driving Firefox
395
+ * :selenium_headless => Selenium driving Firefox in a headless configuration
396
+ * :selenium_chrome => Selenium driving Chrome
397
+ * :selenium_chrome_headless => Selenium driving Chrome in a headless configuration
364
398
 
365
- The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
366
- testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
367
- It is significantly faster than drivers like Selenium since it does not load an entire browser.
399
+ These should work (with relevant software installation) in a local desktop configuration but you may
400
+ need to customize them if using in a CI environment where additional options may need to be passed
401
+ to the browsers. See the section on adding and configuring drivers.
368
402
 
369
- You can install it with:
370
403
 
371
- ```bash
372
- gem install capybara-webkit
373
- ```
374
-
375
- And you can use it by:
376
-
377
- ```ruby
378
- Capybara.javascript_driver = :webkit
379
- ```
404
+ **Note**: drivers which run the server in a different thread may not share the
405
+ same transaction as your tests, causing data not to be shared between your test
406
+ and test server, see [Transactions and database setup](#transactions-and-database-setup) below.
380
407
 
381
- ### <a name="poltergeist"></a>Poltergeist
408
+ ### <a name="apparition"></a>Apparition
382
409
 
383
- [Poltergeist](https://github.com/teampoltergeist/poltergeist) is another
384
- headless driver which integrates Capybara with
385
- [PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
386
- require Xvfb to run on your CI server. It will also detect and report
387
- any Javascript errors that happen within the page.
410
+ The [apparition driver](https://github.com/twalpole/apparition) is a new driver that allows you to run tests using Chrome in a headless
411
+ or headed configuration. It attempts to provide backwards compatibility with the [Poltergeist driver API](https://github.com/teampoltergeist/poltergeist)
412
+ and [capybara-webkit API](https://github.com/thoughtbot/capybara-webkit) while allowing for the use of modern JS/CSS. It
413
+ uses CDP to communicate with Chrome, thereby obviating the need for chromedriver. This driver is being developed by the
414
+ current developer of Capybara and will attempt to keep up to date with new Capybara releases. It will probably be moved into the
415
+ teamcapybara repo once it reaches v1.0.
388
416
 
389
417
  ## <a name="the-dsl"></a>The DSL
390
418
 
391
419
  *A complete reference is available at
392
- [rubydoc.info](http://rubydoc.info/github/jnicklas/capybara/master)*.
420
+ [rubydoc.info](http://rubydoc.info/github/teamcapybara/capybara/master)*.
393
421
 
394
422
  **Note: By default Capybara will only locate visible elements. This is because
395
423
  a real user would not be able to interact with non-visible elements.**
@@ -400,7 +428,7 @@ Capybara heavily uses XPath, which doesn't support case insensitivity.
400
428
  ### <a name="navigating"></a>Navigating
401
429
 
402
430
  You can use the
403
- <tt>[visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method)</tt>
431
+ <tt>[visit](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#visit-instance_method)</tt>
404
432
  method to navigate to other pages:
405
433
 
406
434
  ```ruby
@@ -411,8 +439,8 @@ visit(post_comments_path(post))
411
439
  The visit method only takes a single parameter, the request method is **always**
412
440
  GET.
413
441
 
414
- You can get the [current path](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#current_path-instance_method)
415
- of the browsing session, and test it using the [`have_current_path`](http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/RSpecMatchers#have_current_path-instance_method) matcher:
442
+ You can get the [current path](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#current_path-instance_method)
443
+ of the browsing session, and test it using the [`have_current_path`](http://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/RSpecMatchers#have_current_path-instance_method) matcher:
416
444
 
417
445
  ```ruby
418
446
  expect(page).to have_current_path(post_comments_path(post))
@@ -425,7 +453,7 @@ to ensure that preceding actions (such as a `click_link`) have completed.
425
453
 
426
454
  ### <a name="clicking-links-and-buttons"></a>Clicking links and buttons
427
455
 
428
- *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
456
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
429
457
 
430
458
  You can interact with the webapp by following links and buttons. Capybara
431
459
  automatically follows any redirects, and submits forms associated with buttons.
@@ -440,33 +468,33 @@ click_on('Button Value')
440
468
 
441
469
  ### <a name="interacting-with-forms"></a>Interacting with forms
442
470
 
443
- *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
471
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
444
472
 
445
473
  There are a number of tools for interacting with form elements:
446
474
 
447
475
  ```ruby
448
- fill_in('First Name', :with => 'John')
449
- fill_in('Password', :with => 'Seekrit')
450
- fill_in('Description', :with => 'Really Long Text...')
476
+ fill_in('First Name', with: 'John')
477
+ fill_in('Password', with: 'Seekrit')
478
+ fill_in('Description', with: 'Really Long Text...')
451
479
  choose('A Radio Button')
452
480
  check('A Checkbox')
453
481
  uncheck('A Checkbox')
454
482
  attach_file('Image', '/path/to/image.jpg')
455
- select('Option', :from => 'Select Box')
483
+ select('Option', from: 'Select Box')
456
484
  ```
457
485
 
458
486
  ### <a name="querying"></a>Querying
459
487
 
460
- *Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers)*
488
+ *Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers)*
461
489
 
462
490
  Capybara has a rich set of options for querying the page for the existence of
463
491
  certain elements, and working with and manipulating those elements.
464
492
 
465
493
  ```ruby
466
494
  page.has_selector?('table tr')
467
- page.has_selector?(:xpath, '//table/tr')
495
+ page.has_selector?(:xpath, './/table/tr')
468
496
 
469
- page.has_xpath?('//table/tr')
497
+ page.has_xpath?('.//table/tr')
470
498
  page.has_css?('table tr.foo')
471
499
  page.has_content?('foo')
472
500
  ```
@@ -478,29 +506,41 @@ You can use these with RSpec's magic matchers:
478
506
 
479
507
  ```ruby
480
508
  expect(page).to have_selector('table tr')
481
- expect(page).to have_selector(:xpath, '//table/tr')
509
+ expect(page).to have_selector(:xpath, './/table/tr')
482
510
 
483
- expect(page).to have_xpath('//table/tr')
511
+ expect(page).to have_xpath('.//table/tr')
484
512
  expect(page).to have_css('table tr.foo')
485
513
  expect(page).to have_content('foo')
486
514
  ```
487
515
 
488
516
  ### <a name="finding"></a>Finding
489
517
 
490
- _Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders)_
518
+ _Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders)_
491
519
 
492
520
  You can also find specific elements, in order to manipulate them:
493
521
 
494
522
  ```ruby
495
523
  find_field('First Name').value
524
+ find_field(id: 'my_field').value
496
525
  find_link('Hello', :visible => :all).visible?
526
+ find_link(class: ['some_class', 'some_other_class'], :visible => :all).visible?
527
+
497
528
  find_button('Send').click
529
+ find_button(value: '1234').click
498
530
 
499
- find(:xpath, "//table/tr").click
531
+ find(:xpath, ".//table/tr").click
500
532
  find("#overlay").find("h1").click
501
533
  all('a').each { |a| a[:href] }
502
534
  ```
503
535
 
536
+ If you need to find elements by additional attributes/properties you can also pass a filter block, which will be checked inside the normal waiting behavior.
537
+ If you find yourself needing to use this a lot you may be better off adding a [custom selector](http://www.rubydoc.info/github/teamcapybara/capybara/Capybara#add_selector-class_method) or [adding a filter to an existing selector](http://www.rubydoc.info/github/teamcapybara/capybara/Capybara#modify_selector-class_method).
538
+
539
+ ```ruby
540
+ find_field('First Name'){ |el| el['data-xyz'] == '123' }
541
+ find("#img_loading"){ |img| img['complete'] == true }
542
+ ```
543
+
504
544
  **Note**: `find` will wait for an element to appear on the page, as explained in the
505
545
  Ajax section. If the element does not appear it will raise an error.
506
546
 
@@ -517,16 +557,16 @@ expect(find('#navigation')).to have_button('Sign out')
517
557
  Capybara makes it possible to restrict certain actions, such as interacting with
518
558
  forms or clicking links and buttons, to within a specific area of the page. For
519
559
  this purpose you can use the generic
520
- <tt>[within](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#within-instance_method)</tt>
560
+ <tt>[within](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#within-instance_method)</tt>
521
561
  method. Optionally you can specify which kind of selector to use.
522
562
 
523
563
  ```ruby
524
564
  within("li#employee") do
525
- fill_in 'Name', :with => 'Jimmy'
565
+ fill_in 'Name', with: 'Jimmy'
526
566
  end
527
567
 
528
- within(:xpath, "//li[@id='employee']") do
529
- fill_in 'Name', :with => 'Jimmy'
568
+ within(:xpath, ".//li[@id='employee']") do
569
+ fill_in 'Name', with: 'Jimmy'
530
570
  end
531
571
  ```
532
572
 
@@ -536,11 +576,11 @@ specific table, identified by either id or text of the table's caption tag.
536
576
 
537
577
  ```ruby
538
578
  within_fieldset('Employee') do
539
- fill_in 'Name', :with => 'Jimmy'
579
+ fill_in 'Name', with: 'Jimmy'
540
580
  end
541
581
 
542
582
  within_table('Employee') do
543
- fill_in 'Name', :with => 'Jimmy'
583
+ fill_in 'Name', with: 'Jimmy'
544
584
  end
545
585
  ```
546
586
 
@@ -567,13 +607,23 @@ In drivers which support it, you can easily execute JavaScript:
567
607
  page.execute_script("$('body').empty()")
568
608
  ```
569
609
 
570
- For simple expressions, you can return the result of the script. Note
571
- that this may break with more complicated expressions:
610
+ For simple expressions, you can return the result of the script.
572
611
 
573
612
  ```ruby
574
613
  result = page.evaluate_script('4 + 4');
575
614
  ```
576
615
 
616
+ For more complicated scripts you'll need to write them as one expression.
617
+
618
+ ```ruby
619
+ result = page.evaluate_script(<<~JS, 3, element)
620
+ (function(n, el){
621
+ var val = parseInt(el.value, 10);
622
+ return n+val;
623
+ })(arguments[0], arguments[1])
624
+ JS
625
+ ```
626
+
577
627
  ### <a name="modals"></a>Modals
578
628
 
579
629
  In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
@@ -622,7 +672,7 @@ save_and_open_page
622
672
  ```
623
673
 
624
674
  You can also retrieve the current state of the DOM as a string using
625
- <tt>[page.html](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#html-instance_method)</tt>.
675
+ <tt>[page.html](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#html-instance_method)</tt>.
626
676
 
627
677
  ```ruby
628
678
  print page.html
@@ -643,6 +693,10 @@ Or have it save and automatically open:
643
693
  save_and_open_screenshot
644
694
  ```
645
695
 
696
+ Screenshots are saved to `Capybara.save_path`, relative to the app directory.
697
+ If you have required `capybara/rails`, `Capybara.save_path` will default to
698
+ `tmp/capybara`.
699
+
646
700
  ## <a name="matching"></a>Matching
647
701
 
648
702
  It is possible to customize how Capybara finds elements. At your disposal
@@ -688,6 +742,9 @@ Capybara 1.x, set `Capybara.match` to `:prefer_exact`.
688
742
 
689
743
  ## <a name="transactions-and-database-setup"></a>Transactions and database setup
690
744
 
745
+ **Note:** Rails 5.1+ "safely" shares the database connection between the app and test threads. Therefore,
746
+ if using Rails 5.1+ you SHOULD be able to ignore this section.
747
+
691
748
  Some Capybara drivers need to run against an actual HTTP server. Capybara takes
692
749
  care of this and starts one for you in the same process as your test, but on
693
750
  another thread. Selenium is one of those drivers, whereas RackTest is not.
@@ -778,9 +835,9 @@ module MyModule
778
835
  include Capybara::DSL
779
836
 
780
837
  def login!
781
- within("//form[@id='session']") do
782
- fill_in 'Email', :with => 'user@example.com'
783
- fill_in 'Password', :with => 'password'
838
+ within(:xpath, ".//form[@id='session']") do
839
+ fill_in 'Email', with: 'user@example.com'
840
+ fill_in 'Password', with: 'password'
784
841
  end
785
842
  click_button 'Sign in'
786
843
  end
@@ -818,19 +875,40 @@ remote application:
818
875
  Capybara.run_server = false
819
876
  ```
820
877
 
821
- ## <a name="using-the-sessions-manually"></a>Using the sessions manually
878
+ ## <a name="using-sessions"></a>Using sessions
879
+
880
+ Capybara manages named sessions (:default if not specified) allowing multiple sessions using the same driver and test app instance to be interacted with.
881
+ A new session will be created using the current driver if a session with the given name using the current driver and test app instance is not found.
882
+
883
+ ### Named sessions
884
+ To perform operations in a different session and then revert to the previous session
885
+
886
+ ```ruby
887
+ Capybara.using_session("Bob's session") do
888
+ #do something in Bob's browser session
889
+ end
890
+ #reverts to previous session
891
+ ```
892
+
893
+ To permanently switch the current session to a different session
894
+
895
+ ```ruby
896
+ Capybara.session_name = "some other session"
897
+ ```
898
+
899
+ ### <a name="using-sessions-manually"></a>Using sessions manually
822
900
 
823
901
  For ultimate control, you can instantiate and use a
824
- [Session](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session)
902
+ [Session](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session)
825
903
  manually.
826
904
 
827
905
  ```ruby
828
906
  require 'capybara'
829
907
 
830
908
  session = Capybara::Session.new(:webkit, my_rack_app)
831
- session.within("//form[@id='session']") do
832
- session.fill_in 'Email', :with => 'user@example.com'
833
- session.fill_in 'Password', :with => 'password'
909
+ session.within("form#session") do
910
+ session.fill_in 'Email', with: 'user@example.com'
911
+ session.fill_in 'Password', with: 'password'
834
912
  end
835
913
  session.click_button 'Sign in'
836
914
  ```
@@ -842,24 +920,29 @@ and will always use CSS by default. If you want to use XPath, you'll need to
842
920
  do:
843
921
 
844
922
  ```ruby
845
- within(:xpath, '//ul/li') { ... }
846
- find(:xpath, '//ul/li').text
847
- find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value
923
+ within(:xpath, './/ul/li') { ... }
924
+ find(:xpath, './/ul/li').text
925
+ find(:xpath, './/li[contains(.//a[@href = "#"]/text(), "foo")]').value
848
926
  ```
849
927
 
850
928
  Alternatively you can set the default selector to XPath:
851
929
 
852
930
  ```ruby
853
931
  Capybara.default_selector = :xpath
854
- find('//ul/li').text
932
+ find('.//ul/li').text
855
933
  ```
856
934
 
857
- Capybara allows you to add custom selectors, which can be very useful if you
858
- find yourself using the same kinds of selectors very often:
935
+ Capybara provides a number of other built-in selector types. The full list, along
936
+ with applicable filters, can be seen at [built-in selectors](https://www.rubydoc.info/github/teamcapybara/capybara/Capybara/Selector)
937
+
938
+ Capybara also allows you to add custom selectors, which can be very useful if you
939
+ find yourself using the same kinds of selectors very often. The examples below are very
940
+ simple, and there are many available features not demonstrated. For more in-depth examples
941
+ please see Capybaras built-in selector definitions.
859
942
 
860
943
  ```ruby
861
- Capybara.add_selector(:id) do
862
- xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
944
+ Capybara.add_selector(:my_attribute) do
945
+ xpath { |id| XPath.descendant[XPath.attr(:my_attribute) == id.to_s] }
863
946
  end
864
947
 
865
948
  Capybara.add_selector(:row) do
@@ -876,9 +959,9 @@ an XPath expression generated through the XPath gem. You can now use these
876
959
  selectors like this:
877
960
 
878
961
  ```ruby
879
- find(:id, 'post_123')
880
- find(:row, 3)
881
- find(:flash_type, :notice)
962
+ find(:my_attribute, 'post_123') # find element with matching attribute
963
+ find(:row, 3) # find 3rd row in table body
964
+ find(:flash_type, :notice) # find element with id of 'flash' and class of 'notice'
882
965
  ```
883
966
 
884
967
  ## <a name="beware-the-xpath--trap"></a>Beware the XPath // trap
@@ -924,6 +1007,7 @@ end
924
1007
  However, it's also possible to give this configuration a different name.
925
1008
 
926
1009
  ```ruby
1010
+ # Note: Capybara registers this by default
927
1011
  Capybara.register_driver :selenium_chrome do |app|
928
1012
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
929
1013
  end
@@ -969,15 +1053,52 @@ additional info about how the underlying driver can be configured.
969
1053
  are testing for specific server errors and using multiple sessions make sure to test for the
970
1054
  errors using the initial session (usually :default)
971
1055
 
1056
+ * If WebMock is enabled, you may encounter a "Too many open files"
1057
+ error. A simple `page.find` call may cause thousands of HTTP requests
1058
+ until the timeout occurs. By default, WebMock will cause each of these
1059
+ requests to spawn a new connection. To work around this problem, you
1060
+ may need to [enable WebMock's `net_http_connect_on_start: true`
1061
+ parameter](https://github.com/bblimke/webmock/blob/master/README.md#connecting-on-nethttpstart).
1062
+
1063
+ ## <a name="threadsafe"></a>"Threadsafe" mode
1064
+
1065
+ In normal mode most of Capybara's configuration options are global settings which can cause issues
1066
+ if using multiple sessions and wanting to change a setting for only one of the sessions. To provide
1067
+ support for this type of usage Capybara now provides a "threadsafe" mode which can be enabled by setting
1068
+
1069
+ ```ruby
1070
+ Capybara.threadsafe = true
1071
+ ```
1072
+
1073
+ This setting can only be changed before any sessions have been created. In "threadsafe" mode the following
1074
+ behaviors of Capybara change
1075
+
1076
+ * Most options can now be set on a session. These can either be set at session creation time or after, and
1077
+ default to the global options at the time of session creation. Options which are NOT session specific are
1078
+ `app`, `reuse_server`, `default_driver`, `javascript_driver`, and (obviously) `threadsafe`. Any drivers and servers
1079
+ registered through `register_driver` and `register_server` are also global.
1080
+
1081
+ ```ruby
1082
+ my_session = Capybara::Session.new(:driver, some_app) do |config|
1083
+ config.automatic_label_click = true # only set for my_session
1084
+ end
1085
+ my_session.config.default_max_wait_time = 10 # only set for my_session
1086
+ Capybara.default_max_wait_time = 2 # will not change the default_max_wait in my_session
1087
+ ```
1088
+
1089
+ * `current_driver` and `session_name` are thread specific. This means that `using_session` and
1090
+ `using_driver` also only affect the current thread.
1091
+
972
1092
  ## <a name="development"></a>Development
973
1093
 
974
1094
  To set up a development environment, simply do:
975
1095
 
976
1096
  ```bash
977
1097
  bundle install
978
- bundle exec rake # run the test suite
1098
+ bundle exec rake # run the test suite with Firefox - requires `geckodriver` to be installed
1099
+ bundle exec rake spec_chrome # run the test suite with Chrome - require `chromedriver` to be installed
979
1100
  ```
980
1101
 
981
1102
  See
982
- [CONTRIBUTING.md](https://github.com/jnicklas/capybara/blob/master/CONTRIBUTING.md)
1103
+ [CONTRIBUTING.md](https://github.com/teamcapybara/capybara/blob/master/CONTRIBUTING.md)
983
1104
  for how to send issues and pull requests.