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,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+ require 'shared_selenium_session'
6
+ require 'shared_selenium_node'
7
+ require 'rspec/shared_spec_matchers'
8
+
9
+ CHROME_DRIVER = :selenium_chrome
10
+
11
+ Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV['CI'] && ENV['CHROME_BETA']
12
+
13
+ browser_options = ::Selenium::WebDriver::Chrome::Options.new
14
+ browser_options.headless! if ENV['HEADLESS']
15
+ browser_options.add_option(:w3c, ENV['W3C'] != 'false')
16
+ # Chromedriver 77 requires setting this for headless mode on linux
17
+ # Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
18
+ browser_options.add_preference('download.default_directory', Capybara.save_path)
19
+ browser_options.add_preference(:download, default_directory: Capybara.save_path)
20
+
21
+ Capybara.register_driver :selenium_chrome do |app|
22
+ Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options, timeout: 30).tap do |driver|
23
+ # Set download dir for Chrome < 77
24
+ driver.browser.download_path = Capybara.save_path
25
+ end
26
+ end
27
+
28
+ Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
29
+ chrome_options = {
30
+ browser: :chrome,
31
+ options: browser_options
32
+ }
33
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
34
+ end
35
+
36
+ Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
37
+ chrome_options = {
38
+ browser: :chrome,
39
+ options: browser_options
40
+ }
41
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_session_storage: false))
42
+ end
43
+
44
+ Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
45
+ chrome_options = {
46
+ browser: :chrome,
47
+ options: browser_options
48
+ }
49
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false))
50
+ end
51
+
52
+ Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
53
+ subclass = Class.new(Capybara::Selenium::Driver)
54
+ subclass.new(app, browser: :chrome, options: browser_options, timeout: 30)
55
+ end
56
+
57
+ module TestSessions
58
+ Chrome = Capybara::Session.new(CHROME_DRIVER, TestApp)
59
+ end
60
+
61
+ skipped_tests = %i[response_headers status_code trigger]
62
+
63
+ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Chrome) if ENV['CI']
64
+
65
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybara_skip: skipped_tests do |example|
66
+ case example.metadata[:full_description]
67
+ when /#click_link can download a file$/
68
+ skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
69
+ when /Capybara::Session selenium_chrome Capybara::Window#maximize/
70
+ pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
71
+ when /Capybara::Window#fullscreen should be able to fullscreen the window/
72
+ skip 'Chromedriver hangs on attempts to fullscreen in headless mode' if ENV['HEADLESS']
73
+ when /details non-summary descendants should be non-visible/
74
+ pending 'Chromedriver built-in is_displayed is currently broken' if ENV['W3C'] == 'false'
75
+ when /node #right_click delay should delay the mouse up/
76
+ skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
77
+ end
78
+ end
79
+
80
+ RSpec.describe 'Capybara::Session with chrome' do
81
+ include Capybara::SpecHelper
82
+ ['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
83
+ include_examples examples, TestSessions::Chrome, CHROME_DRIVER
84
+ end
85
+
86
+ context 'storage' do
87
+ describe '#reset!' do
88
+ it 'clears storage by default' do
89
+ session = TestSessions::Chrome
90
+ session.visit('/with_js')
91
+ session.find(:css, '#set-storage').click
92
+ session.reset!
93
+ session.visit('/with_js')
94
+ expect(session.evaluate_script('Object.keys(localStorage)')).to be_empty
95
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).to be_empty
96
+ end
97
+
98
+ it 'does not clear storage when false' do
99
+ session = Capybara::Session.new(:selenium_chrome_not_clear_storage, TestApp)
100
+ session.visit('/with_js')
101
+ session.find(:css, '#set-storage').click
102
+ session.reset!
103
+ session.visit('/with_js')
104
+ expect(session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
105
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
106
+ end
107
+
108
+ it 'can not clear session storage' do
109
+ session = Capybara::Session.new(:selenium_chrome_not_clear_session_storage, TestApp)
110
+ session.visit('/with_js')
111
+ session.find(:css, '#set-storage').click
112
+ session.reset!
113
+ session.visit('/with_js')
114
+ expect(session.evaluate_script('Object.keys(localStorage)')).to be_empty
115
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
116
+ end
117
+
118
+ it 'can not clear local storage' do
119
+ session = Capybara::Session.new(:selenium_chrome_not_clear_local_storage, TestApp)
120
+ session.visit('/with_js')
121
+ session.find(:css, '#set-storage').click
122
+ session.reset!
123
+ session.visit('/with_js')
124
+ expect(session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
125
+ expect(session.evaluate_script('Object.keys(sessionStorage)')).to be_empty
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'timeout' do
131
+ it 'sets the http client read timeout' do
132
+ expect(TestSessions::Chrome.driver.browser.send(:bridge).http.read_timeout).to eq 30
133
+ end
134
+ end
135
+
136
+ describe 'filling in Chrome-specific date and time fields with keystrokes' do
137
+ let(:datetime) { Time.new(1983, 6, 19, 6, 30) }
138
+ let(:session) { TestSessions::Chrome }
139
+
140
+ before do
141
+ session.visit('/form')
142
+ end
143
+
144
+ it 'should fill in a date input with a String' do
145
+ session.fill_in('form_date', with: '06/19/1983')
146
+ session.click_button('awesome')
147
+ expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
148
+ end
149
+
150
+ it 'should fill in a time input with a String' do
151
+ session.fill_in('form_time', with: '06:30A')
152
+ session.click_button('awesome')
153
+ results = extract_results(session)['time']
154
+ expect(Time.parse(results).strftime('%r')).to eq datetime.strftime('%r')
155
+ end
156
+
157
+ it 'should fill in a datetime input with a String' do
158
+ session.fill_in('form_datetime', with: "06/19/1983\t06:30A")
159
+ session.click_button('awesome')
160
+ expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
161
+ end
162
+ end
163
+
164
+ describe 'using subclass of selenium driver' do
165
+ it 'works' do
166
+ session = Capybara::Session.new(:selenium_driver_subclass_with_chrome, TestApp)
167
+ session.visit('/form')
168
+ expect(session).to have_current_path('/form')
169
+ end
170
+ end
171
+
172
+ describe 'log access' do
173
+ before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
174
+
175
+ it 'does not error getting log types' do
176
+ skip if Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0]) < Gem::Version.new('75.0.3770.90')
177
+ expect do
178
+ session.driver.browser.manage.logs.available_types
179
+ end.not_to raise_error
180
+ end
181
+
182
+ it 'does not error when getting logs' do
183
+ expect do
184
+ session.driver.browser.manage.logs.get(:browser)
185
+ end.not_to raise_error
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+ require 'shared_selenium_session'
6
+ require 'shared_selenium_node'
7
+ require 'rspec/shared_spec_matchers'
8
+
9
+ def selenium_host
10
+ ENV.fetch('SELENIUM_HOST', '0.0.0.0')
11
+ end
12
+
13
+ def selenium_port
14
+ ENV.fetch('SELENIUM_PORT', 4444)
15
+ end
16
+
17
+ def ensure_selenium_running!
18
+ timer = Capybara::Helpers.timer(expire_in: 20)
19
+ begin
20
+ TCPSocket.open(selenium_host, selenium_port)
21
+ rescue StandardError
22
+ if timer.expired?
23
+ raise 'Selenium is not running. ' \
24
+ "You can run a selenium server easily with: \n" \
25
+ ' $ docker-compose up -d selenium_chrome'
26
+ else
27
+ puts 'Waiting for Selenium docker instance...'
28
+ sleep 1
29
+ retry
30
+ end
31
+ end
32
+ end
33
+
34
+ def selenium_gte?(version)
35
+ defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION.to_f >= version)
36
+ end
37
+
38
+ Capybara.register_driver :selenium_chrome_remote do |app|
39
+ ensure_selenium_running!
40
+
41
+ url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
42
+ browser_options = ::Selenium::WebDriver::Chrome::Options.new
43
+
44
+ Capybara::Selenium::Driver.new app,
45
+ browser: :remote,
46
+ desired_capabilities: :chrome,
47
+ options: browser_options,
48
+ url: url
49
+ end
50
+
51
+ CHROME_REMOTE_DRIVER = :selenium_chrome_remote
52
+
53
+ module TestSessions
54
+ Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
55
+ end
56
+
57
+ skipped_tests = %i[response_headers status_code trigger download]
58
+
59
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
60
+ case example.metadata[:full_description]
61
+ when 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files',
62
+ 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded',
63
+ 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty'
64
+ pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14)
65
+ when /node #right_click delay should delay the mouse up/
66
+ skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
67
+ end
68
+ end
69
+
70
+ RSpec.describe 'Capybara::Session with remote Chrome' do
71
+ include Capybara::SpecHelper
72
+ ['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
73
+ include_examples examples, TestSessions::Chrome, CHROME_REMOTE_DRIVER
74
+ end
75
+
76
+ it 'is considered to be chrome' do
77
+ expect(session.driver.browser.browser).to eq :chrome
78
+ end
79
+
80
+ describe 'log access' do
81
+ before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
82
+
83
+ it 'does not error when getting log types' do
84
+ skip if Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0]) < Gem::Version.new('75.0.3770.90')
85
+ expect do
86
+ session.driver.browser.manage.logs.available_types
87
+ end.not_to raise_error
88
+ end
89
+
90
+ it 'does not error when getting logs' do
91
+ expect do
92
+ session.driver.browser.manage.logs.get(:browser)
93
+ end.not_to raise_error
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+ require 'shared_selenium_session'
6
+ require 'shared_selenium_node'
7
+ require 'rspec/shared_spec_matchers'
8
+
9
+ # unless ENV['CI']
10
+ # Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
11
+ # end
12
+
13
+ if ::Selenium::WebDriver::Platform.mac?
14
+ Selenium::WebDriver::EdgeChrome.path = '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev'
15
+ end
16
+
17
+ Capybara.register_driver :selenium_edge do |app|
18
+ # ::Selenium::WebDriver.logger.level = "debug"
19
+ # If we don't create an options object the path set above won't be used
20
+ browser_options = ::Selenium::WebDriver::EdgeChrome::Options.new
21
+ Capybara::Selenium::Driver.new(app, browser: :edge_chrome, options: browser_options).tap do |driver|
22
+ driver.browser
23
+ driver.download_path = Capybara.save_path
24
+ end
25
+ end
26
+
27
+ module TestSessions
28
+ SeleniumEdge = Capybara::Session.new(:selenium_edge, TestApp)
29
+ end
30
+
31
+ skipped_tests = %i[response_headers status_code trigger]
32
+
33
+ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::EdgeChrome) if ENV['CI']
34
+
35
+ Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
36
+ case example.metadata[:full_description]
37
+ when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
38
+ pending "EdgeChrome doesn't allow clicking on file inputs"
39
+ end
40
+ end
41
+
42
+ RSpec.describe 'Capybara::Session with Edge', capybara_skip: skipped_tests do
43
+ include Capybara::SpecHelper
44
+ ['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
45
+ include_examples examples, TestSessions::SeleniumEdge, :selenium_edge
46
+ end
47
+ end
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+ require 'shared_selenium_session'
6
+ require 'shared_selenium_node'
7
+ require 'rspec/shared_spec_matchers'
8
+
9
+ browser_options = ::Selenium::WebDriver::Firefox::Options.new
10
+ browser_options.headless! if ENV['HEADLESS']
11
+ # browser_options.add_option("log", {"level": "trace"})
12
+
13
+ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |profile|
14
+ profile['browser.download.dir'] = Capybara.save_path
15
+ profile['browser.download.folderList'] = 2
16
+ profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
17
+ end
18
+
19
+ Capybara.register_driver :selenium_firefox do |app|
20
+ # ::Selenium::WebDriver.logger.level = "debug"
21
+ Capybara::Selenium::Driver.new(
22
+ app,
23
+ browser: :firefox,
24
+ options: browser_options,
25
+ timeout: 31
26
+ # Get a trace level log from geckodriver
27
+ # :driver_opts => { args: ['-vv'] }
28
+ )
29
+ end
30
+
31
+ Capybara.register_driver :selenium_firefox_not_clear_storage do |app|
32
+ Capybara::Selenium::Driver.new(
33
+ app,
34
+ browser: :firefox,
35
+ clear_local_storage: false,
36
+ clear_session_storage: false,
37
+ options: browser_options
38
+ )
39
+ end
40
+
41
+ module TestSessions
42
+ SeleniumFirefox = Capybara::Session.new(:selenium_firefox, TestApp)
43
+ end
44
+
45
+ skipped_tests = %i[response_headers status_code trigger]
46
+
47
+ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Firefox) if ENV['CI']
48
+
49
+ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capybara_skip: skipped_tests do |example|
50
+ case example.metadata[:full_description]
51
+ when 'Capybara::Session selenium node #click should allow multiple modifiers'
52
+ pending "Firefox on OSX doesn't generate an event for shift+control+click" if firefox_gte?(62, @session) && Selenium::WebDriver::Platform.mac?
53
+ when /^Capybara::Session selenium node #double_click/
54
+ pending "selenium-webdriver/geckodriver doesn't generate double click event" if firefox_lt?(59, @session)
55
+ when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default'
56
+ pending "Geckodriver doesn't set a blank response in FF < 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1486485" if firefox_lt?(63, @session)
57
+ when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty'
58
+ pending "FF < 62 doesn't support setting all files at once" if firefox_lt?(62, @session)
59
+ when 'Capybara::Session selenium #accept_confirm should work with nested modals'
60
+ skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
61
+ skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
62
+ skip 'Broken again intermittently in FF 71 - jus skip it'
63
+ when 'Capybara::Session selenium #click_link can download a file'
64
+ skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
65
+ when 'Capybara::Session selenium #reset_session! removes ALL cookies'
66
+ pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
67
+ when /drag_to.*HTML5/
68
+ pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
69
+ when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
70
+ 'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
71
+ skip 'No clue what Firefox is doing here - works fine on MacOS locally'
72
+ end
73
+ end
74
+
75
+ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/MultipleDescribes
76
+ include Capybara::SpecHelper
77
+ ['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
78
+ include_examples examples, TestSessions::SeleniumFirefox, :selenium_firefox
79
+ end
80
+
81
+ describe 'filling in Firefox-specific date and time fields with keystrokes' do
82
+ let(:datetime) { Time.new(1983, 6, 19, 6, 30) }
83
+ let(:session) { TestSessions::SeleniumFirefox }
84
+
85
+ before do
86
+ session.visit('/form')
87
+ end
88
+
89
+ it 'should fill in a date input with a String' do
90
+ session.fill_in('form_date', with: datetime.to_date.iso8601)
91
+ session.click_button('awesome')
92
+ expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
93
+ end
94
+
95
+ it 'should fill in a time input with a String' do
96
+ session.fill_in('form_time', with: datetime.to_time.strftime('%T'))
97
+ session.click_button('awesome')
98
+ results = extract_results(session)['time']
99
+ expect(Time.parse(results).strftime('%r')).to eq datetime.strftime('%r')
100
+ end
101
+
102
+ it 'should fill in a datetime input with a String' do
103
+ # FF doesn't currently support datetime-local so this is really just a text input
104
+ session.fill_in('form_datetime', with: datetime.iso8601)
105
+ session.click_button('awesome')
106
+ expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
107
+ end
108
+ end
109
+ end
110
+
111
+ RSpec.describe Capybara::Selenium::Driver do
112
+ let(:driver) { described_class.new(TestApp, browser: :firefox, options: browser_options) }
113
+
114
+ describe '#quit' do
115
+ it 'should reset browser when quit' do
116
+ expect(driver.browser).to be_truthy
117
+ driver.quit
118
+ # access instance variable directly so we don't create a new browser instance
119
+ expect(driver.instance_variable_get(:@browser)).to be_nil
120
+ end
121
+
122
+ context 'with errors' do
123
+ let!(:original_browser) { driver.browser }
124
+
125
+ after do
126
+ # Ensure browser is actually quit so we don't leave hanging processe
127
+ RSpec::Mocks.space.proxy_for(original_browser).reset
128
+ original_browser.quit
129
+ end
130
+
131
+ it 'warns UnknownError returned during quit because the browser is probably already gone' do
132
+ allow(driver).to receive(:warn)
133
+ allow(driver.browser).to(
134
+ receive(:quit)
135
+ .and_raise(Selenium::WebDriver::Error::UnknownError, 'random message')
136
+ )
137
+
138
+ expect { driver.quit }.not_to raise_error
139
+ expect(driver.instance_variable_get(:@browser)).to be_nil
140
+ expect(driver).to have_received(:warn).with(/random message/)
141
+ end
142
+
143
+ it 'ignores silenced UnknownError returned during quit because the browser is almost definitely already gone' do
144
+ allow(driver).to receive(:warn)
145
+ allow(driver.browser).to(
146
+ receive(:quit)
147
+ .and_raise(Selenium::WebDriver::Error::UnknownError, 'Error communicating with the remote browser')
148
+ )
149
+
150
+ expect { driver.quit }.not_to raise_error
151
+ expect(driver.instance_variable_get(:@browser)).to be_nil
152
+ expect(driver).not_to have_received(:warn)
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'storage' do
158
+ describe '#reset!' do
159
+ it 'clears storage by default' do
160
+ session = TestSessions::SeleniumFirefox
161
+ session.visit('/with_js')
162
+ session.find(:css, '#set-storage').click
163
+ session.reset!
164
+ session.visit('/with_js')
165
+ expect(session.driver.browser.local_storage.keys).to be_empty
166
+ expect(session.driver.browser.session_storage.keys).to be_empty
167
+ end
168
+
169
+ it 'does not clear storage when false' do
170
+ session = Capybara::Session.new(:selenium_firefox_not_clear_storage, TestApp)
171
+ session.visit('/with_js')
172
+ session.find(:css, '#set-storage').click
173
+ session.reset!
174
+ session.visit('/with_js')
175
+ expect(session.driver.browser.local_storage.keys).not_to be_empty
176
+ expect(session.driver.browser.session_storage.keys).not_to be_empty
177
+ end
178
+ end
179
+ end
180
+
181
+ context 'timeout' do
182
+ it 'sets the http client read timeout' do
183
+ expect(TestSessions::SeleniumFirefox.driver.browser.send(:bridge).http.read_timeout).to eq 31
184
+ end
185
+ end
186
+ end
187
+
188
+ RSpec.describe Capybara::Selenium::Node do
189
+ describe '#click' do
190
+ it 'warns when attempting on a table row' do
191
+ session = TestSessions::SeleniumFirefox
192
+ session.visit('/tables')
193
+ tr = session.find(:css, '#agent_table tr:first-child')
194
+ allow(tr.base).to receive(:warn)
195
+ tr.click
196
+ expect(tr.base).to have_received(:warn).with(/Clicking the first cell in the row instead/)
197
+ end
198
+
199
+ it 'should allow multiple modifiers', requires: [:js] do
200
+ session = TestSessions::SeleniumFirefox
201
+ session.visit('with_js')
202
+ # Firefox v62+ doesn't generate an event for control+shift+click
203
+ session.find(:css, '#click-test').click(:alt, :ctrl, :meta)
204
+ # it also triggers a contextmenu event when control is held so don't check click type
205
+ expect(session).to have_link('Has been alt control meta')
206
+ end
207
+ end
208
+ end