capybara 2.7.0 → 3.35.3

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