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,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Capybara::Session do
6
+ describe '#new' do
7
+ it 'should raise an error if passed non-existent driver' do
8
+ expect do
9
+ described_class.new(:quox, TestApp).driver
10
+ end.to raise_error(Capybara::DriverNotFoundError)
11
+ end
12
+
13
+ it 'verifies a passed app is a rack app' do
14
+ expect do
15
+ described_class.new(:unknown, random: 'hash')
16
+ end.to raise_error TypeError, 'The second parameter to Session::new should be a rack app if passed.'
17
+ end
18
+ end
19
+
20
+ context 'current_driver' do
21
+ around do |example|
22
+ orig_driver = Capybara.current_driver
23
+ example.run
24
+ Capybara.current_driver = orig_driver
25
+ end
26
+
27
+ it 'is global when threadsafe false' do
28
+ Capybara.threadsafe = false
29
+ Capybara.current_driver = :selenium
30
+ thread = Thread.new do
31
+ Capybara.current_driver = :random
32
+ end
33
+ thread.join
34
+ expect(Capybara.current_driver).to eq :random
35
+ end
36
+
37
+ it 'is thread specific threadsafe true' do
38
+ Capybara.threadsafe = true
39
+ Capybara.current_driver = :selenium
40
+ thread = Thread.new do
41
+ Capybara.current_driver = :random
42
+ end
43
+ thread.join
44
+ expect(Capybara.current_driver).to eq :selenium
45
+ end
46
+ end
47
+
48
+ context 'session_name' do
49
+ around do |example|
50
+ orig_name = Capybara.session_name
51
+ example.run
52
+ Capybara.session_name = orig_name
53
+ end
54
+
55
+ it 'is global when threadsafe false' do
56
+ Capybara.threadsafe = false
57
+ Capybara.session_name = 'sess1'
58
+ thread = Thread.new do
59
+ Capybara.session_name = 'sess2'
60
+ end
61
+ thread.join
62
+ expect(Capybara.session_name).to eq 'sess2'
63
+ end
64
+
65
+ it 'is thread specific when threadsafe true' do
66
+ Capybara.threadsafe = true
67
+ Capybara.session_name = 'sess1'
68
+ thread = Thread.new do
69
+ Capybara.session_name = 'sess2'
70
+ end
71
+ thread.join
72
+ expect(Capybara.session_name).to eq 'sess1'
73
+ end
74
+ end
75
+
76
+ context 'quit' do
77
+ it 'will reset the driver' do
78
+ session = described_class.new(:rack_test, TestApp)
79
+ driver = session.driver
80
+ session.quit
81
+ expect(session.driver).not_to eql driver
82
+ end
83
+
84
+ it 'resets the document' do
85
+ session = described_class.new(:rack_test, TestApp)
86
+ document = session.document
87
+ session.quit
88
+ expect(session.document.base).not_to eql document.base
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+
6
+ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
7
+ let(:session) { session }
8
+
9
+ describe '#content_editable?' do
10
+ it 'returns true when the element is content editable' do
11
+ session.visit('/with_js')
12
+ expect(session.find(:css, '#existing_content_editable').base.content_editable?).to be true
13
+ expect(session.find(:css, '#existing_content_editable_child').base.content_editable?).to be true
14
+ end
15
+
16
+ it 'returns false when the element is not content editable' do
17
+ session.visit('/with_js')
18
+ expect(session.find(:css, '#drag').base.content_editable?).to be false
19
+ end
20
+ end
21
+
22
+ describe '#send_keys' do
23
+ it 'should process space' do
24
+ session.visit('/form')
25
+ session.find(:css, '#address1_city').send_keys('ocean', [:shift, :space, 'side'])
26
+ expect(session.find(:css, '#address1_city').value).to eq 'ocean SIDE'
27
+ end
28
+ end
29
+
30
+ describe '#[]' do
31
+ it 'should work for spellcheck' do
32
+ session.visit('/with_html')
33
+ expect(session.find('//input[@spellcheck="TRUE"]')[:spellcheck]).to eq('true')
34
+ expect(session.find('//input[@spellcheck="FALSE"]')[:spellcheck]).to eq('false')
35
+ end
36
+ end
37
+
38
+ describe '#set' do
39
+ it 'respects maxlength when using rapid set' do
40
+ session.visit('/form')
41
+ inp = session.find(:css, '#long_length')
42
+ value = (0...50).map { |i| ((i % 26) + 65).chr }.join
43
+ inp.set(value, rapid: true)
44
+ expect(inp.value).to eq value[0...35]
45
+ end
46
+ end
47
+
48
+ describe '#visible?' do
49
+ let(:bridge) do
50
+ session.driver.browser.send(:bridge)
51
+ end
52
+
53
+ around do |example|
54
+ native_displayed = session.driver.options[:native_displayed]
55
+ example.run
56
+ session.driver.options[:native_displayed] = native_displayed
57
+ end
58
+
59
+ before do
60
+ allow(bridge).to receive(:execute_atom).and_call_original
61
+ end
62
+
63
+ it 'will use native displayed if told to' do
64
+ pending "Chromedriver < 76.0.3809.25 doesn't support native displayed in W3C mode" if chrome_lt?(76, session) && (ENV['W3C'] != 'false')
65
+
66
+ session.driver.options[:native_displayed] = true
67
+ session.visit('/form')
68
+ session.find(:css, '#address1_city', visible: true)
69
+
70
+ expect(bridge).not_to have_received(:execute_atom)
71
+ end
72
+
73
+ it "won't use native displayed if told not to" do
74
+ skip 'Non-W3C uses native' if chrome?(session) && (ENV['W3C'] == 'false')
75
+
76
+ session.driver.options[:native_displayed] = false
77
+ session.visit('/form')
78
+ session.find(:css, '#address1_city', visible: true)
79
+
80
+ expect(bridge).to have_received(:execute_atom).with(:isDisplayed, any_args)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,476 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+
6
+ RSpec.shared_examples 'Capybara::Session' do |session, mode|
7
+ let(:session) { session }
8
+
9
+ context 'with selenium driver' do
10
+ describe '#driver' do
11
+ it 'should be a selenium driver' do
12
+ expect(session.driver).to be_an_instance_of(Capybara::Selenium::Driver)
13
+ end
14
+ end
15
+
16
+ describe '#mode' do
17
+ it 'should remember the mode' do
18
+ expect(session.mode).to eq(mode)
19
+ end
20
+ end
21
+
22
+ describe '#reset!' do
23
+ it 'freshly reset session should not be touched' do
24
+ session.instance_variable_set(:@touched, true)
25
+ session.reset!
26
+ expect(session.instance_variable_get(:@touched)).to eq false
27
+ end
28
+ end
29
+
30
+ describe 'exit codes' do
31
+ let(:env) { { 'SELENIUM_BROWSER' => session.driver.options[:browser].to_s } }
32
+ let!(:orig_dir) { Dir.getwd }
33
+
34
+ before do
35
+ Dir.chdir(File.join(File.dirname(__FILE__), '..'))
36
+ end
37
+
38
+ after do
39
+ Dir.chdir(orig_dir)
40
+ end
41
+
42
+ it 'should have return code 1 when running selenium_driver_rspec_failure.rb' do
43
+ skip 'only setup for local non-headless' if headless_or_remote?
44
+ skip 'Not setup for edge' if edge?(session)
45
+
46
+ system(env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
47
+ expect($CHILD_STATUS.exitstatus).to eq(1)
48
+ end
49
+
50
+ it 'should have return code 0 when running selenium_driver_rspec_success.rb' do
51
+ skip 'only setup for local non-headless' if headless_or_remote?
52
+ skip 'Not setup for edge' if edge?(session)
53
+
54
+ system(env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
55
+ expect($CHILD_STATUS.exitstatus).to eq(0)
56
+ end
57
+ end
58
+
59
+ describe '#accept_alert', requires: [:modals] do
60
+ it 'supports a blockless mode' do
61
+ session.visit('/with_js')
62
+ session.click_link('Open alert')
63
+ session.accept_alert
64
+ expect { session.driver.browser.switch_to.alert }.to raise_error(session.driver.send(:modal_error))
65
+ end
66
+
67
+ it 'can be called before visiting' do
68
+ session.accept_alert 'Initial alert' do
69
+ session.visit('/initial_alert')
70
+ end
71
+ expect(session).to have_text('Initial alert page')
72
+ end
73
+ end
74
+
75
+ describe '#fill_in_with empty string and no options' do
76
+ it 'should trigger change when clearing a field' do
77
+ pending "safaridriver doesn't trigger change for clear" if safari?(session)
78
+ session.visit('/with_js')
79
+ session.fill_in('with_change_event', with: '')
80
+ # click outside the field to trigger the change event
81
+ session.find(:css, 'body').click
82
+ expect(session).to have_selector(:css, '.change_event_triggered', match: :one)
83
+ end
84
+ end
85
+
86
+ describe '#fill_in with { :clear => :backspace } fill_option', requires: [:js] do
87
+ before do
88
+ # Firefox has an issue with change events if the main window doesn't think it's focused
89
+ session.execute_script('window.focus()')
90
+ end
91
+
92
+ it 'should fill in a field, replacing an existing value' do
93
+ session.visit('/form')
94
+ session.fill_in('form_first_name',
95
+ with: 'Harry',
96
+ fill_options: { clear: :backspace })
97
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
98
+ end
99
+
100
+ it 'should fill in a field, replacing an existing value, even with caret position' do
101
+ session.visit('/form')
102
+ session.find(:css, '#form_first_name').execute_script <<-JS
103
+ this.focus();
104
+ this.setSelectionRange(0, 0);
105
+ JS
106
+
107
+ session.fill_in('form_first_name',
108
+ with: 'Harry',
109
+ fill_options: { clear: :backspace })
110
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
111
+ end
112
+
113
+ it 'should fill in if the option is set via global option' do
114
+ Capybara.default_set_options = { clear: :backspace }
115
+ session.visit('/form')
116
+ session.fill_in('form_first_name', with: 'Thomas')
117
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('Thomas')
118
+ end
119
+
120
+ it 'should only trigger onchange once' do
121
+ session.visit('/with_js')
122
+ sleep 2 if safari?(session) # Safari needs a delay (to load event handlers maybe ???)
123
+ session.fill_in('with_change_event',
124
+ with: 'some value',
125
+ fill_options: { clear: :backspace })
126
+ # click outside the field to trigger the change event
127
+ session.find(:css, '#with_focus_event').click
128
+ expect(session.find(:css, '.change_event_triggered', match: :one, wait: 5)).to have_text 'some value'
129
+ end
130
+
131
+ it 'should trigger change when clearing field' do
132
+ session.visit('/with_js')
133
+ session.fill_in('with_change_event',
134
+ with: '',
135
+ fill_options: { clear: :backspace })
136
+ # click outside the field to trigger the change event
137
+ session.find(:css, '#with_focus_event').click
138
+ expect(session).to have_selector(:css, '.change_event_triggered', match: :one, wait: 5)
139
+ end
140
+
141
+ it 'should trigger input event field_value.length times' do
142
+ session.visit('/with_js')
143
+ session.fill_in('with_change_event',
144
+ with: '',
145
+ fill_options: { clear: :backspace })
146
+ # click outside the field to trigger the change event
147
+ # session.find(:css, 'body').click
148
+ session.find(:css, 'h1', text: 'FooBar').click
149
+ expect(session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
150
+ end
151
+ end
152
+
153
+ describe '#fill_in with { clear: :none } fill_options' do
154
+ it 'should append to content in a field' do
155
+ pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
156
+
157
+ session.visit('/form')
158
+ session.fill_in('form_first_name',
159
+ with: 'Harry',
160
+ fill_options: { clear: :none })
161
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
162
+ end
163
+ end
164
+
165
+ describe '#fill_in with Date' do
166
+ before do
167
+ session.visit('/form')
168
+ session.find(:css, '#form_date').execute_script <<-JS
169
+ window.capybara_formDateFiredEvents = [];
170
+ var fd = this;
171
+ ['focus', 'input', 'change'].forEach(function(eventType) {
172
+ fd.addEventListener(eventType, function() { window.capybara_formDateFiredEvents.push(eventType); });
173
+ });
174
+ JS
175
+ # work around weird FF issue where it would create an extra focus issue in some cases
176
+ session.find(:css, 'h1', text: 'Form').click
177
+ # session.find(:css, 'body').click
178
+ end
179
+
180
+ it 'should generate standard events on changing value' do
181
+ pending "IE 11 doesn't support date input type" if ie?(session)
182
+ pending "Safari doesn't support date input type" if safari?(session)
183
+ session.fill_in('form_date', with: Date.today)
184
+ expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
185
+ end
186
+
187
+ it 'should not generate input and change events if the value is not changed' do
188
+ pending "IE 11 doesn't support date input type" if ie?(session)
189
+ pending "Safari doesn't support date input type" if safari?(session)
190
+ session.fill_in('form_date', with: Date.today)
191
+ session.fill_in('form_date', with: Date.today)
192
+ # Chrome adds an extra focus for some reason - ok for now
193
+ expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq(%w[focus input change])
194
+ end
195
+ end
196
+
197
+ describe '#fill_in with { clear: Array } fill_options' do
198
+ it 'should pass the array through to the element' do
199
+ # this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
200
+ session.visit('/form')
201
+ session.fill_in('form_first_name',
202
+ with: 'Harry',
203
+ fill_options: { clear: [[:shift, 'abc'], :backspace] })
204
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnABHarry')
205
+ end
206
+ end
207
+
208
+ describe '#path' do
209
+ it 'returns xpath' do
210
+ # this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver
211
+ session.visit('/path')
212
+ element = session.find(:link, 'Second Link')
213
+ expect(element.path).to eq('/HTML/BODY[1]/DIV[2]/A[1]')
214
+ end
215
+
216
+ it 'handles namespaces in xhtml' do
217
+ pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
218
+ session.visit '/with_namespace'
219
+ rect = session.find(:css, 'div svg rect:first-of-type')
220
+ expect(rect.path).to eq("/HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1]")
221
+ expect(session.find(:xpath, rect.path)).to eq rect
222
+ end
223
+
224
+ it 'handles default namespaces in html5' do
225
+ pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
226
+ session.visit '/with_html5_svg'
227
+ rect = session.find(:css, 'div svg rect:first-of-type')
228
+ expect(rect.path).to eq("/HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1]")
229
+ expect(session.find(:xpath, rect.path)).to eq rect
230
+ end
231
+
232
+ it 'handles case sensitive element names' do
233
+ pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
234
+ session.visit '/with_namespace'
235
+ els = session.all(:css, 'div *', visible: :all)
236
+ expect { els.map(&:path) }.not_to raise_error
237
+ lg = session.find(:css, 'div linearGradient', visible: :all)
238
+ expect(session.find(:xpath, lg.path, visible: :all)).to eq lg
239
+ end
240
+ end
241
+
242
+ describe 'all with disappearing elements' do
243
+ it 'ignores stale elements in results' do
244
+ session.visit('/path')
245
+ elements = session.all(:link) { |_node| raise Selenium::WebDriver::Error::StaleElementReferenceError }
246
+ expect(elements.size).to eq 0
247
+ end
248
+ end
249
+
250
+ describe '#evaluate_script' do
251
+ it 'can return an element' do
252
+ session.visit('/form')
253
+ element = session.evaluate_script("document.getElementById('form_title')")
254
+ expect(element).to eq session.find(:id, 'form_title')
255
+ end
256
+
257
+ it 'can return arrays of nested elements' do
258
+ session.visit('/form')
259
+ elements = session.evaluate_script('document.querySelectorAll("#form_city option")')
260
+ expect(elements).to all(be_instance_of Capybara::Node::Element)
261
+ expect(elements).to eq session.find(:css, '#form_city').all(:css, 'option').to_a
262
+ end
263
+
264
+ it 'can return hashes with elements' do
265
+ session.visit('/form')
266
+ result = session.evaluate_script("{ a: document.getElementById('form_title'), b: {c: document.querySelectorAll('#form_city option')}}")
267
+ expect(result).to eq(
268
+ 'a' => session.find(:id, 'form_title'),
269
+ 'b' => {
270
+ 'c' => session.find(:css, '#form_city').all(:css, 'option').to_a
271
+ }
272
+ )
273
+ end
274
+
275
+ describe '#evaluate_async_script' do
276
+ it 'will timeout if the script takes too long' do
277
+ skip 'safaridriver returns the wrong error type' if safari?(session)
278
+ session.visit('/with_js')
279
+ expect do
280
+ session.using_wait_time(1) do
281
+ session.evaluate_async_script('var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)')
282
+ end
283
+ end.to raise_error Selenium::WebDriver::Error::ScriptTimeoutError
284
+ end
285
+ end
286
+ end
287
+
288
+ describe 'Element#inspect' do
289
+ it 'outputs obsolete elements' do
290
+ session.visit('/form')
291
+ el = session.find(:button, 'Click me!').click
292
+ expect(session).to have_no_button('Click me!')
293
+ allow(el).to receive(:synchronize)
294
+ expect(el.inspect).to eq 'Obsolete #<Capybara::Node::Element>'
295
+ expect(el).not_to have_received(:synchronize)
296
+ end
297
+ end
298
+
299
+ describe 'Element#click' do
300
+ it 'should handle fixed headers/footers' do
301
+ session.visit('/with_fixed_header_footer')
302
+ session.using_wait_time(2) do
303
+ session.find(:link, 'Go to root').click
304
+ end
305
+ expect(session).to have_current_path('/')
306
+ end
307
+ end
308
+
309
+ describe 'Capybara#Node#attach_file' do
310
+ it 'can attach a directory' do
311
+ pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
312
+ pending "Selenium remote doesn't support transferring a directory" if remote?(session)
313
+ pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && ENV['HEADLESS']
314
+ pending "IE doesn't support uploading a directory" if ie?(session)
315
+ pending 'Chrome/chromedriver 73 breaks this' if chrome?(session) && chrome_gte?(73, session) && chrome_lt?(75, session)
316
+ pending "Safari doesn't support uploading a directory" if safari?(session)
317
+ # pending "Edge/msedgedriver doesn't support directory upload" if edge?(session) && edge_gte?(75, session)
318
+
319
+ session.visit('/form')
320
+ test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
321
+ session.attach_file('Directory Upload', test_file_dir)
322
+ session.click_button('Upload Multiple')
323
+ expect(session.body).to include('5 | ') # number of files
324
+ end
325
+
326
+ it 'can attach a relative file' do
327
+ pending 'Geckdoriver on windows requires alternate file separator which path expansion replaces' if Gem.win_platform? && firefox?(session)
328
+
329
+ session.visit('/form')
330
+ session.attach_file('Single Document', 'spec/fixtures/capybara.csv')
331
+ session.click_button('Upload Single')
332
+ expect(session.body).to include('Content-type: text/csv')
333
+ end
334
+ end
335
+
336
+ context 'Windows' do
337
+ it "can't close the primary window" do
338
+ expect do
339
+ session.current_window.close
340
+ end.to raise_error(ArgumentError, 'Not allowed to close the primary window')
341
+ end
342
+ end
343
+
344
+ # rubocop:disable RSpec/InstanceVariable
345
+ describe 'Capybara#disable_animation' do
346
+ context 'when set to `true`' do
347
+ before(:context) do # rubocop:disable RSpec/BeforeAfterAll
348
+ skip "Safari doesn't support multiple sessions" if safari?(session)
349
+ # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
350
+ # it doesn't affect any of these tests because the settings are applied per-session
351
+ Capybara.disable_animation = true
352
+ @animation_session = Capybara::Session.new(session.mode, TestApp.new)
353
+ end
354
+
355
+ it 'should disable CSS transitions' do
356
+ @animation_session.visit('with_animation')
357
+ @animation_session.click_link('transition me away')
358
+ expect(@animation_session).to have_no_link('transition me away', wait: 0.5)
359
+ end
360
+
361
+ it 'should disable CSS animations (set to 0s)' do
362
+ @animation_session.visit('with_animation')
363
+ @animation_session.click_link('animate me away')
364
+ expect(@animation_session).to have_no_link('animate me away', wait: 0.5)
365
+ end
366
+
367
+ it 'should disable CSS animations on pseudo elements (set to 0s)' do
368
+ @animation_session.visit('with_animation')
369
+ @animation_session.find_link('animate me away').right_click
370
+ expect(@animation_session).to have_content('Animation Ended', wait: 0.1)
371
+ end
372
+ end
373
+
374
+ context 'if we pass in css that matches elements' do
375
+ before(:context) do # rubocop:disable RSpec/BeforeAfterAll
376
+ skip "safaridriver doesn't support multiple sessions" if safari?(session)
377
+ # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
378
+ # it doesn't affect any of these tests because the settings are applied per-session
379
+ Capybara.disable_animation = '#with_animation a'
380
+ @animation_session_with_matching_css = Capybara::Session.new(session.mode, TestApp.new)
381
+ end
382
+
383
+ it 'should disable CSS transitions' do
384
+ @animation_session_with_matching_css.visit('with_animation')
385
+ @animation_session_with_matching_css.click_link('transition me away')
386
+ expect(@animation_session_with_matching_css).to have_no_link('transition me away', wait: 0.5)
387
+ end
388
+
389
+ it 'should disable CSS animations' do
390
+ @animation_session_with_matching_css.visit('with_animation')
391
+ @animation_session_with_matching_css.click_link('animate me away')
392
+ expect(@animation_session_with_matching_css).to have_no_link('animate me away', wait: 0.5)
393
+ end
394
+ end
395
+
396
+ context 'if we pass in css that does not match elements' do
397
+ before(:context) do # rubocop:disable RSpec/BeforeAfterAll
398
+ skip "Safari doesn't support multiple sessions" if safari?(session)
399
+ # NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
400
+ # it doesn't affect any of these tests because the settings are applied per-session
401
+ Capybara.disable_animation = '.this-class-matches-nothing'
402
+ @animation_session_without_matching_css = Capybara::Session.new(session.mode, TestApp.new)
403
+ end
404
+
405
+ it 'should not disable CSS transitions' do
406
+ @animation_session_without_matching_css.visit('with_animation')
407
+ @animation_session_without_matching_css.click_link('transition me away')
408
+ sleep 0.5 # Wait long enough for click to have been processed
409
+ expect(@animation_session_without_matching_css).to have_link('transition me away', wait: false)
410
+ expect(@animation_session_without_matching_css).to have_no_link('transition me away', wait: 5)
411
+ end
412
+
413
+ it 'should not disable CSS animations' do
414
+ @animation_session_without_matching_css.visit('with_animation')
415
+ @animation_session_without_matching_css.click_link('animate me away')
416
+ sleep 0.5 # Wait long enough for click to have been processed
417
+ expect(@animation_session_without_matching_css).to have_link('animate me away', wait: false)
418
+ expect(@animation_session_without_matching_css).to have_no_link('animate me away', wait: 5)
419
+ end
420
+ end
421
+ end
422
+ # rubocop:enable RSpec/InstanceVariable
423
+
424
+ describe ':element selector' do
425
+ it 'can find html5 svg elements' do
426
+ session.visit('with_html5_svg')
427
+ expect(session).to have_selector(:element, :svg)
428
+ expect(session).to have_selector(:element, :rect, visible: true)
429
+ expect(session).to have_selector(:element, :circle)
430
+ expect(session).to have_selector(:element, :linearGradient, visible: :all)
431
+ end
432
+
433
+ it 'can query attributes with strange characters' do
434
+ session.visit('/form')
435
+ expect(session).to have_selector(:element, "{custom}": true)
436
+ expect(session).to have_selector(:element, "{custom}": 'abcdef')
437
+ end
438
+ end
439
+
440
+ describe 'with react' do
441
+ context 'controlled components' do
442
+ it 'can set and clear a text field' do
443
+ skip "This test doesn't support older browsers" if ie?(session)
444
+
445
+ session.visit 'react'
446
+
447
+ session.fill_in('Name:', with: 'abc')
448
+ session.accept_prompt 'A name was submitted: abc' do
449
+ session.click_button('Submit')
450
+ end
451
+
452
+ session.fill_in('Name:', with: '')
453
+ session.accept_prompt(/A name was submitted: $/) do
454
+ session.click_button('Submit')
455
+ end
456
+ end
457
+
458
+ it 'works with rapid fill' do
459
+ skip "This test doesn't support older browsers" if ie?(session)
460
+
461
+ session.visit 'react'
462
+ long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
463
+
464
+ session.fill_in('Name:', with: long_string)
465
+ session.accept_prompt "A name was submitted: #{long_string}" do
466
+ session.click_button('Submit')
467
+ end
468
+ end
469
+ end
470
+ end
471
+ end
472
+
473
+ def headless_or_remote?
474
+ !ENV['HEADLESS'].nil? || session.driver.options[:browser] == :remote
475
+ end
476
+ end