capybara 3.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/History.md +1813 -0
  4. data/License.txt +22 -0
  5. data/README.md +1099 -0
  6. data/lib/capybara.rb +511 -0
  7. data/lib/capybara/config.rb +94 -0
  8. data/lib/capybara/cucumber.rb +27 -0
  9. data/lib/capybara/driver/base.rb +170 -0
  10. data/lib/capybara/driver/node.rb +139 -0
  11. data/lib/capybara/dsl.rb +65 -0
  12. data/lib/capybara/helpers.rb +108 -0
  13. data/lib/capybara/minitest.rb +386 -0
  14. data/lib/capybara/minitest/spec.rb +264 -0
  15. data/lib/capybara/node/actions.rb +420 -0
  16. data/lib/capybara/node/base.rb +143 -0
  17. data/lib/capybara/node/document.rb +48 -0
  18. data/lib/capybara/node/document_matchers.rb +67 -0
  19. data/lib/capybara/node/element.rb +606 -0
  20. data/lib/capybara/node/finders.rb +325 -0
  21. data/lib/capybara/node/matchers.rb +883 -0
  22. data/lib/capybara/node/simple.rb +208 -0
  23. data/lib/capybara/queries/ancestor_query.rb +27 -0
  24. data/lib/capybara/queries/base_query.rb +106 -0
  25. data/lib/capybara/queries/current_path_query.rb +51 -0
  26. data/lib/capybara/queries/match_query.rb +26 -0
  27. data/lib/capybara/queries/selector_query.rb +710 -0
  28. data/lib/capybara/queries/sibling_query.rb +26 -0
  29. data/lib/capybara/queries/style_query.rb +45 -0
  30. data/lib/capybara/queries/text_query.rb +110 -0
  31. data/lib/capybara/queries/title_query.rb +39 -0
  32. data/lib/capybara/rack_test/browser.rb +140 -0
  33. data/lib/capybara/rack_test/css_handlers.rb +13 -0
  34. data/lib/capybara/rack_test/driver.rb +109 -0
  35. data/lib/capybara/rack_test/errors.rb +6 -0
  36. data/lib/capybara/rack_test/form.rb +127 -0
  37. data/lib/capybara/rack_test/node.rb +325 -0
  38. data/lib/capybara/rails.rb +16 -0
  39. data/lib/capybara/registrations/drivers.rb +36 -0
  40. data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
  41. data/lib/capybara/registrations/servers.rb +44 -0
  42. data/lib/capybara/result.rb +190 -0
  43. data/lib/capybara/rspec.rb +29 -0
  44. data/lib/capybara/rspec/features.rb +23 -0
  45. data/lib/capybara/rspec/matcher_proxies.rb +82 -0
  46. data/lib/capybara/rspec/matchers.rb +201 -0
  47. data/lib/capybara/rspec/matchers/base.rb +111 -0
  48. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  49. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  50. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  51. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  52. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  53. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  54. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  55. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  56. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  57. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  58. data/lib/capybara/rspec/matchers/match_style.rb +38 -0
  59. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  60. data/lib/capybara/selector.rb +233 -0
  61. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  62. data/lib/capybara/selector/builders/xpath_builder.rb +69 -0
  63. data/lib/capybara/selector/css.rb +102 -0
  64. data/lib/capybara/selector/definition.rb +276 -0
  65. data/lib/capybara/selector/definition/button.rb +51 -0
  66. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  67. data/lib/capybara/selector/definition/css.rb +10 -0
  68. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  69. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  70. data/lib/capybara/selector/definition/element.rb +27 -0
  71. data/lib/capybara/selector/definition/field.rb +40 -0
  72. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  73. data/lib/capybara/selector/definition/file_field.rb +13 -0
  74. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  75. data/lib/capybara/selector/definition/frame.rb +17 -0
  76. data/lib/capybara/selector/definition/id.rb +6 -0
  77. data/lib/capybara/selector/definition/label.rb +62 -0
  78. data/lib/capybara/selector/definition/link.rb +46 -0
  79. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  80. data/lib/capybara/selector/definition/option.rb +27 -0
  81. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  82. data/lib/capybara/selector/definition/select.rb +81 -0
  83. data/lib/capybara/selector/definition/table.rb +109 -0
  84. data/lib/capybara/selector/definition/table_row.rb +21 -0
  85. data/lib/capybara/selector/definition/xpath.rb +5 -0
  86. data/lib/capybara/selector/filter.rb +5 -0
  87. data/lib/capybara/selector/filter_set.rb +124 -0
  88. data/lib/capybara/selector/filters/base.rb +77 -0
  89. data/lib/capybara/selector/filters/expression_filter.rb +22 -0
  90. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  91. data/lib/capybara/selector/filters/node_filter.rb +31 -0
  92. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  93. data/lib/capybara/selector/selector.rb +147 -0
  94. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  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 +496 -0
  100. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +119 -0
  101. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +126 -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 +78 -0
  110. data/lib/capybara/selenium/logger_suppressor.rb +34 -0
  111. data/lib/capybara/selenium/node.rb +610 -0
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +119 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +131 -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 +47 -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.rb +126 -0
  124. data/lib/capybara/server/animation_disabler.rb +58 -0
  125. data/lib/capybara/server/checker.rb +44 -0
  126. data/lib/capybara/server/middleware.rb +69 -0
  127. data/lib/capybara/session.rb +942 -0
  128. data/lib/capybara/session/config.rb +124 -0
  129. data/lib/capybara/session/matchers.rb +87 -0
  130. data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
  131. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  132. data/lib/capybara/spec/fixtures/no_extension +1 -0
  133. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  134. data/lib/capybara/spec/public/jquery-ui.js +13 -0
  135. data/lib/capybara/spec/public/jquery.js +5 -0
  136. data/lib/capybara/spec/public/offset.js +6 -0
  137. data/lib/capybara/spec/public/test.js +268 -0
  138. data/lib/capybara/spec/session/accept_alert_spec.rb +81 -0
  139. data/lib/capybara/spec/session/accept_confirm_spec.rb +32 -0
  140. data/lib/capybara/spec/session/accept_prompt_spec.rb +78 -0
  141. data/lib/capybara/spec/session/all_spec.rb +278 -0
  142. data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
  143. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
  144. data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
  145. data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
  146. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  147. data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
  148. data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
  149. data/lib/capybara/spec/session/attach_file_spec.rb +216 -0
  150. data/lib/capybara/spec/session/body_spec.rb +23 -0
  151. data/lib/capybara/spec/session/check_spec.rb +235 -0
  152. data/lib/capybara/spec/session/choose_spec.rb +121 -0
  153. data/lib/capybara/spec/session/click_button_spec.rb +506 -0
  154. data/lib/capybara/spec/session/click_link_or_button_spec.rb +129 -0
  155. data/lib/capybara/spec/session/click_link_spec.rb +229 -0
  156. data/lib/capybara/spec/session/current_scope_spec.rb +31 -0
  157. data/lib/capybara/spec/session/current_url_spec.rb +115 -0
  158. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +36 -0
  159. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +21 -0
  160. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +38 -0
  161. data/lib/capybara/spec/session/element/match_css_spec.rb +31 -0
  162. data/lib/capybara/spec/session/element/match_xpath_spec.rb +25 -0
  163. data/lib/capybara/spec/session/element/matches_selector_spec.rb +120 -0
  164. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  165. data/lib/capybara/spec/session/evaluate_script_spec.rb +49 -0
  166. data/lib/capybara/spec/session/execute_script_spec.rb +28 -0
  167. data/lib/capybara/spec/session/fill_in_spec.rb +286 -0
  168. data/lib/capybara/spec/session/find_button_spec.rb +74 -0
  169. data/lib/capybara/spec/session/find_by_id_spec.rb +33 -0
  170. data/lib/capybara/spec/session/find_field_spec.rb +113 -0
  171. data/lib/capybara/spec/session/find_link_spec.rb +70 -0
  172. data/lib/capybara/spec/session/find_spec.rb +531 -0
  173. data/lib/capybara/spec/session/first_spec.rb +156 -0
  174. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  175. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  176. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
  177. data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
  178. data/lib/capybara/spec/session/go_back_spec.rb +12 -0
  179. data/lib/capybara/spec/session/go_forward_spec.rb +14 -0
  180. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  181. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  182. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  183. data/lib/capybara/spec/session/has_button_spec.rb +69 -0
  184. data/lib/capybara/spec/session/has_css_spec.rb +374 -0
  185. data/lib/capybara/spec/session/has_current_path_spec.rb +138 -0
  186. data/lib/capybara/spec/session/has_field_spec.rb +349 -0
  187. data/lib/capybara/spec/session/has_link_spec.rb +39 -0
  188. data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
  189. data/lib/capybara/spec/session/has_select_spec.rb +310 -0
  190. data/lib/capybara/spec/session/has_selector_spec.rb +202 -0
  191. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  192. data/lib/capybara/spec/session/has_table_spec.rb +198 -0
  193. data/lib/capybara/spec/session/has_text_spec.rb +394 -0
  194. data/lib/capybara/spec/session/has_title_spec.rb +71 -0
  195. data/lib/capybara/spec/session/has_xpath_spec.rb +149 -0
  196. data/lib/capybara/spec/session/headers_spec.rb +8 -0
  197. data/lib/capybara/spec/session/html_spec.rb +47 -0
  198. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  199. data/lib/capybara/spec/session/node_spec.rb +1292 -0
  200. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  201. data/lib/capybara/spec/session/refresh_spec.rb +33 -0
  202. data/lib/capybara/spec/session/reset_session_spec.rb +148 -0
  203. data/lib/capybara/spec/session/response_code_spec.rb +8 -0
  204. data/lib/capybara/spec/session/save_and_open_page_spec.rb +21 -0
  205. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +43 -0
  206. data/lib/capybara/spec/session/save_page_spec.rb +110 -0
  207. data/lib/capybara/spec/session/save_screenshot_spec.rb +55 -0
  208. data/lib/capybara/spec/session/screenshot_spec.rb +18 -0
  209. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  210. data/lib/capybara/spec/session/select_spec.rb +229 -0
  211. data/lib/capybara/spec/session/selectors_spec.rb +98 -0
  212. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  213. data/lib/capybara/spec/session/source_spec.rb +0 -0
  214. data/lib/capybara/spec/session/text_spec.rb +74 -0
  215. data/lib/capybara/spec/session/title_spec.rb +29 -0
  216. data/lib/capybara/spec/session/uncheck_spec.rb +100 -0
  217. data/lib/capybara/spec/session/unselect_spec.rb +116 -0
  218. data/lib/capybara/spec/session/visit_spec.rb +204 -0
  219. data/lib/capybara/spec/session/window/become_closed_spec.rb +89 -0
  220. data/lib/capybara/spec/session/window/current_window_spec.rb +28 -0
  221. data/lib/capybara/spec/session/window/open_new_window_spec.rb +31 -0
  222. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +132 -0
  223. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +99 -0
  224. data/lib/capybara/spec/session/window/window_spec.rb +203 -0
  225. data/lib/capybara/spec/session/window/windows_spec.rb +34 -0
  226. data/lib/capybara/spec/session/window/within_window_spec.rb +157 -0
  227. data/lib/capybara/spec/session/within_spec.rb +199 -0
  228. data/lib/capybara/spec/spec_helper.rb +134 -0
  229. data/lib/capybara/spec/test_app.rb +226 -0
  230. data/lib/capybara/spec/views/animated.erb +49 -0
  231. data/lib/capybara/spec/views/buttons.erb +5 -0
  232. data/lib/capybara/spec/views/fieldsets.erb +30 -0
  233. data/lib/capybara/spec/views/form.erb +685 -0
  234. data/lib/capybara/spec/views/frame_child.erb +18 -0
  235. data/lib/capybara/spec/views/frame_one.erb +10 -0
  236. data/lib/capybara/spec/views/frame_parent.erb +9 -0
  237. data/lib/capybara/spec/views/frame_two.erb +9 -0
  238. data/lib/capybara/spec/views/header_links.erb +8 -0
  239. data/lib/capybara/spec/views/host_links.erb +13 -0
  240. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  241. data/lib/capybara/spec/views/obscured.erb +47 -0
  242. data/lib/capybara/spec/views/offset.erb +32 -0
  243. data/lib/capybara/spec/views/path.erb +13 -0
  244. data/lib/capybara/spec/views/popup_one.erb +9 -0
  245. data/lib/capybara/spec/views/popup_two.erb +9 -0
  246. data/lib/capybara/spec/views/postback.erb +14 -0
  247. data/lib/capybara/spec/views/react.erb +45 -0
  248. data/lib/capybara/spec/views/scroll.erb +20 -0
  249. data/lib/capybara/spec/views/spatial.erb +31 -0
  250. data/lib/capybara/spec/views/tables.erb +130 -0
  251. data/lib/capybara/spec/views/with_animation.erb +74 -0
  252. data/lib/capybara/spec/views/with_base_tag.erb +11 -0
  253. data/lib/capybara/spec/views/with_count.erb +8 -0
  254. data/lib/capybara/spec/views/with_dragula.erb +22 -0
  255. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  256. data/lib/capybara/spec/views/with_hover.erb +24 -0
  257. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  258. data/lib/capybara/spec/views/with_html.erb +208 -0
  259. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  260. data/lib/capybara/spec/views/with_html_entities.erb +2 -0
  261. data/lib/capybara/spec/views/with_js.erb +160 -0
  262. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  263. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  264. data/lib/capybara/spec/views/with_scope.erb +42 -0
  265. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  266. data/lib/capybara/spec/views/with_simple_html.erb +2 -0
  267. data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
  268. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  269. data/lib/capybara/spec/views/with_title.erb +5 -0
  270. data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
  271. data/lib/capybara/spec/views/with_windows.erb +54 -0
  272. data/lib/capybara/spec/views/within_frames.erb +15 -0
  273. data/lib/capybara/version.rb +5 -0
  274. data/lib/capybara/window.rb +146 -0
  275. data/spec/basic_node_spec.rb +154 -0
  276. data/spec/capybara_spec.rb +112 -0
  277. data/spec/css_builder_spec.rb +101 -0
  278. data/spec/css_splitter_spec.rb +38 -0
  279. data/spec/dsl_spec.rb +276 -0
  280. data/spec/filter_set_spec.rb +46 -0
  281. data/spec/fixtures/capybara.csv +1 -0
  282. data/spec/fixtures/certificate.pem +25 -0
  283. data/spec/fixtures/key.pem +27 -0
  284. data/spec/fixtures/selenium_driver_rspec_failure.rb +13 -0
  285. data/spec/fixtures/selenium_driver_rspec_success.rb +13 -0
  286. data/spec/minitest_spec.rb +163 -0
  287. data/spec/minitest_spec_spec.rb +162 -0
  288. data/spec/per_session_config_spec.rb +68 -0
  289. data/spec/rack_test_spec.rb +268 -0
  290. data/spec/regexp_dissassembler_spec.rb +250 -0
  291. data/spec/result_spec.rb +196 -0
  292. data/spec/rspec/features_spec.rb +99 -0
  293. data/spec/rspec/scenarios_spec.rb +19 -0
  294. data/spec/rspec/shared_spec_matchers.rb +947 -0
  295. data/spec/rspec/views_spec.rb +14 -0
  296. data/spec/rspec_matchers_spec.rb +62 -0
  297. data/spec/rspec_spec.rb +145 -0
  298. data/spec/sauce_spec_chrome.rb +43 -0
  299. data/spec/selector_spec.rb +513 -0
  300. data/spec/selenium_spec_chrome.rb +188 -0
  301. data/spec/selenium_spec_chrome_remote.rb +96 -0
  302. data/spec/selenium_spec_edge.rb +47 -0
  303. data/spec/selenium_spec_firefox.rb +208 -0
  304. data/spec/selenium_spec_firefox_remote.rb +80 -0
  305. data/spec/selenium_spec_ie.rb +150 -0
  306. data/spec/selenium_spec_safari.rb +148 -0
  307. data/spec/server_spec.rb +292 -0
  308. data/spec/session_spec.rb +91 -0
  309. data/spec/shared_selenium_node.rb +83 -0
  310. data/spec/shared_selenium_session.rb +476 -0
  311. data/spec/spec_helper.rb +100 -0
  312. data/spec/xpath_builder_spec.rb +93 -0
  313. metadata +753 -0
@@ -0,0 +1,511 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'timeout'
4
+ require 'nokogiri'
5
+ require 'xpath'
6
+ require 'forwardable'
7
+ require 'capybara/config'
8
+
9
+ module Capybara
10
+ class CapybaraError < StandardError; end
11
+ class DriverNotFoundError < CapybaraError; end
12
+ class FrozenInTime < CapybaraError; end
13
+ class ElementNotFound < CapybaraError; end
14
+ class ModalNotFound < CapybaraError; end
15
+ class Ambiguous < ElementNotFound; end
16
+ class ExpectationNotMet < ElementNotFound; end
17
+ class FileNotFound < CapybaraError; end
18
+ class UnselectNotAllowed < CapybaraError; end
19
+ class NotSupportedByDriverError < CapybaraError; end
20
+ class InfiniteRedirectError < CapybaraError; end
21
+ class ScopeError < CapybaraError; end
22
+ class WindowError < CapybaraError; end
23
+ class ReadOnlyElementError < CapybaraError; end
24
+
25
+ class << self
26
+ extend Forwardable
27
+
28
+ # DelegateCapybara global configurations
29
+ # @!method app
30
+ # See {Capybara.configure}
31
+ # @!method reuse_server
32
+ # See {Capybara.configure}
33
+ # @!method threadsafe
34
+ # See {Capybara.configure}
35
+ # @!method server
36
+ # See {Capybara.configure}
37
+ # @!method default_driver
38
+ # See {Capybara.configure}
39
+ # @!method javascript_driver
40
+ # See {Capybara.configure}
41
+ # @!method allow_gumbo
42
+ # See {Capybara.configure}
43
+ Config::OPTIONS.each do |method|
44
+ def_delegators :config, method, "#{method}="
45
+ end
46
+
47
+ # Delegate Capybara global configurations
48
+ # @!method default_selector
49
+ # See {Capybara.configure}
50
+ # @!method default_max_wait_time
51
+ # See {Capybara.configure}
52
+ # @!method app_host
53
+ # See {Capybara.configure}
54
+ # @!method always_include_port
55
+ # See {Capybara.configure}
56
+ SessionConfig::OPTIONS.each do |method|
57
+ def_delegators :config, method, "#{method}="
58
+ end
59
+
60
+ ##
61
+ #
62
+ # Configure Capybara to suit your needs.
63
+ #
64
+ # Capybara.configure do |config|
65
+ # config.run_server = false
66
+ # config.app_host = 'http://www.google.com'
67
+ # end
68
+ #
69
+ # #### Configurable options
70
+ #
71
+ # - **allow_gumbo** (Boolean = `false`) - When `nokogumbo` is available, whether it will be used to parse HTML strings.
72
+ # - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
73
+ # unless another port is explicitly specified.
74
+ # - **app_host** (String, `nil`) - The default host to use when giving a relative URL to visit, must be a valid URL e.g. `http://www.example.com`.
75
+ # - **asset_host** (String = `nil`) - Where dynamic assets are hosted - will be prepended to relative asset locations if present.
76
+ # - **automatic_label_click** (Boolean = `false`) - Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check},
77
+ # {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated `<label>` element if the checkbox/radio button are non-visible.
78
+ # - **automatic_reload** (Boolean = `true`) - Whether to automatically reload elements as Capybara is waiting.
79
+ # - **default_max_wait_time** (Numeric = `2`) - The maximum number of seconds to wait for asynchronous processes to finish.
80
+ # - **default_normalize_ws** (Boolean = `false`) - Whether text predicates and matchers use normalize whitespace behavior.
81
+ # - **default_selector** (`:css`, `:xpath` = `:css`) - Methods which take a selector use the given type by default. See also {Capybara::Selector}.
82
+ # - **default_set_options** (Hash = `{}`) - The default options passed to {Capybara::Node::Element#set Element#set}.
83
+ # - **enable_aria_label** (Boolean = `false`) - Whether fields, links, and buttons will match against `aria-label` attribute.
84
+ # - **exact** (Boolean = `false`) - Whether locators are matched exactly or with substrings. Only affects selector conditions
85
+ # written using the `XPath#is` method.
86
+ # - **exact_text** (Boolean = `false`) - Whether the text matchers and `:text` filter match exactly or on substrings.
87
+ # - **ignore_hidden_elements** (Boolean = `true`) - Whether to ignore hidden elements on the page.
88
+ # - **match** (`:one`, `:first`, `:prefer_exact`, `:smart` = `:smart`) - The matching strategy to find nodes.
89
+ # - **predicates_wait** (Boolean = `true`) - Whether Capybara's predicate matchers use waiting behavior by default.
90
+ # - **raise_server_errors** (Boolean = `true`) - Should errors raised in the server be raised in the tests?
91
+ # - **reuse_server** (Boolean = `true`) - Whether to reuse the server thread between multiple sessions using the same app object.
92
+ # - **run_server** (Boolean = `true`) - Whether to start a Rack server for the given Rack app.
93
+ # - **save_path** (String = `Dir.pwd`) - Where to put pages saved through {Capybara::Session#save_page save_page}, {Capybara::Session#save_screenshot save_screenshot},
94
+ # {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
95
+ # - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
96
+ # - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
97
+ # and {configure raise_server_errors} is `true`.
98
+ # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
99
+ # - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually.
100
+ # - **w3c_click_offset** (Boolean = 'false') - Whether click offsets should be from element center (true) or top left (false)
101
+ #
102
+ # #### DSL Options
103
+ #
104
+ # When using `capybara/dsl`, the following options are also available:
105
+ #
106
+ # - **default_driver** (Symbol = `:rack_test`) - The name of the driver to use by default.
107
+ # - **javascript_driver** (Symbol = `:selenium`) - The name of a driver to use for JavaScript enabled tests.
108
+ #
109
+ def configure
110
+ yield config
111
+ end
112
+
113
+ ##
114
+ #
115
+ # Register a new driver for Capybara.
116
+ #
117
+ # Capybara.register_driver :rack_test do |app|
118
+ # Capybara::RackTest::Driver.new(app)
119
+ # end
120
+ #
121
+ # @param [Symbol] name The name of the new driver
122
+ # @yield [app] This block takes a rack app and returns a Capybara driver
123
+ # @yieldparam [<Rack>] app The rack application that this driver runs against. May be nil.
124
+ # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
125
+ #
126
+ def register_driver(name, &block)
127
+ drivers[name] = block
128
+ end
129
+
130
+ ##
131
+ #
132
+ # Register a new server for Capybara.
133
+ #
134
+ # Capybara.register_server :webrick do |app, port, host|
135
+ # require 'rack/handler/webrick'
136
+ # Rack::Handler::WEBrick.run(app, ...)
137
+ # end
138
+ #
139
+ # @param [Symbol] name The name of the new driver
140
+ # @yield [app, port, host] This block takes a rack app and a port and returns a rack server listening on that port
141
+ # @yieldparam [<Rack>] app The rack application that this server will contain.
142
+ # @yieldparam port The port number the server should listen on
143
+ # @yieldparam host The host/ip to bind to
144
+ #
145
+ def register_server(name, &block)
146
+ servers[name.to_sym] = block
147
+ end
148
+
149
+ ##
150
+ #
151
+ # Add a new selector to Capybara. Selectors can be used by various methods in Capybara
152
+ # to find certain elements on the page in a more convenient way. For example adding a
153
+ # selector to find certain table rows might look like this:
154
+ #
155
+ # Capybara.add_selector(:row) do
156
+ # xpath { |num| ".//tbody/tr[#{num}]" }
157
+ # end
158
+ #
159
+ # This makes it possible to use this selector in a variety of ways:
160
+ #
161
+ # find(:row, 3)
162
+ # page.find('table#myTable').find(:row, 3).text
163
+ # page.find('table#myTable').has_selector?(:row, 3)
164
+ # within(:row, 3) { expect(page).to have_content('$100.000') }
165
+ #
166
+ # Here is another example:
167
+ #
168
+ # Capybara.add_selector(:id) do
169
+ # xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
170
+ # end
171
+ #
172
+ # Note that this particular selector already ships with Capybara.
173
+ #
174
+ # @param [Symbol] name The name of the selector to add
175
+ # @yield A block executed in the context of the new {Capybara::Selector}
176
+ #
177
+ def add_selector(name, **options, &block)
178
+ Capybara::Selector.add(name, **options, &block)
179
+ end
180
+
181
+ ##
182
+ #
183
+ # Modify a selector previously created by {Capybara.add_selector}.
184
+ # For example, adding a new filter to the :button selector to filter based on
185
+ # button style (a class) might look like this
186
+ #
187
+ # Capybara.modify_selector(:button) do
188
+ # filter (:btn_style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
189
+ # end
190
+ #
191
+ #
192
+ # @param [Symbol] name The name of the selector to modify
193
+ # @yield A block executed in the context of the existing {Capybara::Selector}
194
+ #
195
+ def modify_selector(name, &block)
196
+ Capybara::Selector.update(name, &block)
197
+ end
198
+
199
+ def drivers
200
+ @drivers ||= {}
201
+ end
202
+
203
+ def servers
204
+ @servers ||= {}
205
+ end
206
+
207
+ # Wraps the given string, which should contain an HTML document or fragment
208
+ # in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers},
209
+ # {Capybara::Node::Finders} and {Capybara::Node::DocumentMatchers}. This allows you to query
210
+ # any string containing HTML in the exact same way you would query the current document in a Capybara
211
+ # session.
212
+ #
213
+ # @example A single element
214
+ # node = Capybara.string('<a href="foo">bar</a>')
215
+ # anchor = node.first('a')
216
+ # anchor[:href] #=> 'foo'
217
+ # anchor.text #=> 'bar'
218
+ #
219
+ # @example Multiple elements
220
+ # node = Capybara.string <<-HTML
221
+ # <ul>
222
+ # <li id="home">Home</li>
223
+ # <li id="projects">Projects</li>
224
+ # </ul>
225
+ # HTML
226
+ #
227
+ # node.find('#projects').text # => 'Projects'
228
+ # node.has_selector?('li#home', text: 'Home')
229
+ # node.has_selector?('#projects')
230
+ # node.find('ul').find('li:first-child').text # => 'Home'
231
+ #
232
+ # @param [String] html An html fragment or document
233
+ # @return [Capybara::Node::Simple] A node which has Capybara's finders and matchers
234
+ #
235
+ def string(html)
236
+ Capybara::Node::Simple.new(html)
237
+ end
238
+
239
+ ##
240
+ #
241
+ # Runs Capybara's default server for the given application and port
242
+ # under most circumstances you should not have to call this method
243
+ # manually.
244
+ #
245
+ # @param [Rack Application] app The rack application to run
246
+ # @param [Integer] port The port to run the application on
247
+ #
248
+ def run_default_server(app, port)
249
+ servers[:puma].call(app, port, server_host)
250
+ end
251
+
252
+ ##
253
+ #
254
+ # @return [Symbol] The name of the driver currently in use
255
+ #
256
+ def current_driver
257
+ if threadsafe
258
+ Thread.current['capybara_current_driver']
259
+ else
260
+ @current_driver
261
+ end || default_driver
262
+ end
263
+ alias_method :mode, :current_driver
264
+
265
+ def current_driver=(name)
266
+ if threadsafe
267
+ Thread.current['capybara_current_driver'] = name
268
+ else
269
+ @current_driver = name
270
+ end
271
+ end
272
+
273
+ ##
274
+ #
275
+ # Use the default driver as the current driver
276
+ #
277
+ def use_default_driver
278
+ self.current_driver = nil
279
+ end
280
+
281
+ ##
282
+ #
283
+ # Yield a block using a specific driver
284
+ #
285
+ def using_driver(driver)
286
+ previous_driver = Capybara.current_driver
287
+ Capybara.current_driver = driver
288
+ yield
289
+ ensure
290
+ self.current_driver = previous_driver
291
+ end
292
+
293
+ ##
294
+ #
295
+ # Yield a block using a specific wait time
296
+ #
297
+ def using_wait_time(seconds)
298
+ previous_wait_time = Capybara.default_max_wait_time
299
+ Capybara.default_max_wait_time = seconds
300
+ yield
301
+ ensure
302
+ Capybara.default_max_wait_time = previous_wait_time
303
+ end
304
+
305
+ ##
306
+ #
307
+ # The current {Capybara::Session} based on what is set as {app} and {current_driver}.
308
+ #
309
+ # @return [Capybara::Session] The currently used session
310
+ #
311
+ def current_session
312
+ specified_session || session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
313
+ end
314
+
315
+ ##
316
+ #
317
+ # Reset sessions, cleaning out the pool of sessions. This will remove any session information such
318
+ # as cookies.
319
+ #
320
+ def reset_sessions!
321
+ # reset in reverse so sessions that started servers are reset last
322
+ session_pool.reverse_each { |_mode, session| session.reset! }
323
+ end
324
+ alias_method :reset!, :reset_sessions!
325
+
326
+ ##
327
+ #
328
+ # The current session name.
329
+ #
330
+ # @return [Symbol] The name of the currently used session.
331
+ #
332
+ def session_name
333
+ if threadsafe
334
+ Thread.current['capybara_session_name'] ||= :default
335
+ else
336
+ @session_name ||= :default
337
+ end
338
+ end
339
+
340
+ def session_name=(name)
341
+ if threadsafe
342
+ Thread.current['capybara_session_name'] = name
343
+ else
344
+ @session_name = name
345
+ end
346
+ end
347
+
348
+ ##
349
+ #
350
+ # Yield a block using a specific session name or {Capybara::Session} instance.
351
+ #
352
+ def using_session(name_or_session)
353
+ previous_session_info = {
354
+ specified_session: specified_session,
355
+ session_name: session_name,
356
+ current_driver: current_driver,
357
+ app: app
358
+ }
359
+ self.specified_session = self.session_name = nil
360
+ if name_or_session.is_a? Capybara::Session
361
+ self.specified_session = name_or_session
362
+ else
363
+ self.session_name = name_or_session
364
+ end
365
+ yield
366
+ ensure
367
+ self.session_name, self.specified_session = previous_session_info.values_at(:session_name, :specified_session)
368
+ self.current_driver, self.app = previous_session_info.values_at(:current_driver, :app) if threadsafe
369
+ end
370
+
371
+ ##
372
+ #
373
+ # Parse raw html into a document using Nokogiri, and adjust textarea contents as defined by the spec.
374
+ #
375
+ # @param [String] html The raw html
376
+ # @return [Nokogiri::HTML::Document] HTML document
377
+ #
378
+ def HTML(html) # rubocop:disable Naming/MethodName
379
+ if Nokogiri.respond_to?(:HTML5) && Capybara.allow_gumbo # Nokogumbo installed and allowed for use
380
+ Nokogiri::HTML5(html).tap do |document|
381
+ document.xpath('//template').each do |template|
382
+ # template elements content is not part of the document
383
+ template.inner_html = ''
384
+ end
385
+ document.xpath('//textarea').each do |textarea|
386
+ # The Nokogumbo HTML5 parser already returns spec compliant contents
387
+ textarea['_capybara_raw_value'] = textarea.content
388
+ end
389
+ end
390
+ else
391
+ Nokogiri::HTML(html).tap do |document|
392
+ document.xpath('//template').each do |template|
393
+ # template elements content is not part of the document
394
+ template.inner_html = ''
395
+ end
396
+ document.xpath('//textarea').each do |textarea|
397
+ textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/, '')
398
+ end
399
+ end
400
+ end
401
+ end
402
+
403
+ def session_options
404
+ config.session_options
405
+ end
406
+
407
+ private
408
+
409
+ def config
410
+ @config ||= Capybara::Config.new
411
+ end
412
+
413
+ def session_pool
414
+ @session_pool ||= Hash.new do |hash, name|
415
+ hash[name] = Capybara::Session.new(current_driver, app)
416
+ end
417
+ end
418
+
419
+ def specified_session
420
+ if threadsafe
421
+ Thread.current['capybara_specified_session']
422
+ else
423
+ @specified_session ||= nil
424
+ end
425
+ end
426
+
427
+ def specified_session=(session)
428
+ if threadsafe
429
+ Thread.current['capybara_specified_session'] = session
430
+ else
431
+ @specified_session = session
432
+ end
433
+ end
434
+ end
435
+
436
+ self.default_driver = nil
437
+ self.current_driver = nil
438
+ self.server_host = nil
439
+
440
+ module Driver; end
441
+ module RackTest; end
442
+ module Selenium; end
443
+
444
+ require 'capybara/helpers'
445
+ require 'capybara/session'
446
+ require 'capybara/window'
447
+ require 'capybara/server'
448
+ require 'capybara/selector'
449
+ require 'capybara/result'
450
+ require 'capybara/version'
451
+
452
+ require 'capybara/queries/base_query'
453
+ require 'capybara/queries/selector_query'
454
+ require 'capybara/queries/text_query'
455
+ require 'capybara/queries/title_query'
456
+ require 'capybara/queries/current_path_query'
457
+ require 'capybara/queries/match_query'
458
+ require 'capybara/queries/ancestor_query'
459
+ require 'capybara/queries/sibling_query'
460
+ require 'capybara/queries/style_query'
461
+
462
+ require 'capybara/node/finders'
463
+ require 'capybara/node/matchers'
464
+ require 'capybara/node/actions'
465
+ require 'capybara/node/document_matchers'
466
+ require 'capybara/node/simple'
467
+ require 'capybara/node/base'
468
+ require 'capybara/node/element'
469
+ require 'capybara/node/document'
470
+
471
+ require 'capybara/driver/base'
472
+ require 'capybara/driver/node'
473
+
474
+ require 'capybara/rack_test/driver'
475
+ require 'capybara/rack_test/node'
476
+ require 'capybara/rack_test/form'
477
+ require 'capybara/rack_test/browser'
478
+ require 'capybara/rack_test/css_handlers.rb'
479
+
480
+ require 'capybara/selenium/node'
481
+ require 'capybara/selenium/driver'
482
+ end
483
+
484
+ require 'capybara/registrations/servers'
485
+ require 'capybara/registrations/drivers'
486
+
487
+ Capybara.configure do |config|
488
+ config.always_include_port = false
489
+ config.run_server = true
490
+ config.server = :default
491
+ config.default_selector = :css
492
+ config.default_max_wait_time = 2
493
+ config.ignore_hidden_elements = true
494
+ config.default_host = 'http://www.example.com'
495
+ config.automatic_reload = true
496
+ config.match = :smart
497
+ config.exact = false
498
+ config.exact_text = false
499
+ config.raise_server_errors = true
500
+ config.server_errors = [Exception]
501
+ config.visible_text_only = false
502
+ config.automatic_label_click = false
503
+ config.enable_aria_label = false
504
+ config.reuse_server = true
505
+ config.default_set_options = {}
506
+ config.test_id = nil
507
+ config.predicates_wait = true
508
+ config.default_normalize_ws = false
509
+ config.allow_gumbo = false
510
+ config.w3c_click_offset = false
511
+ end