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,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#click_link_or_button' do
4
+ it 'should click on a link' do
5
+ @session.visit('/with_html')
6
+ @session.click_link_or_button('labore')
7
+ expect(@session).to have_content('Bar')
8
+ end
9
+
10
+ it 'should click on a button' do
11
+ @session.visit('/form')
12
+ @session.click_link_or_button('awe123')
13
+ expect(extract_results(@session)['first_name']).to eq('John')
14
+ end
15
+
16
+ it 'should click on a button with no type attribute' do
17
+ @session.visit('/form')
18
+ @session.click_link_or_button('no_type')
19
+ expect(extract_results(@session)['first_name']).to eq('John')
20
+ end
21
+
22
+ it 'should be aliased as click_on' do
23
+ @session.visit('/form')
24
+ @session.click_on('awe123')
25
+ expect(extract_results(@session)['first_name']).to eq('John')
26
+ end
27
+
28
+ it 'should wait for asynchronous load', requires: [:js] do
29
+ Capybara.default_max_wait_time = 2
30
+ @session.visit('/with_js')
31
+ @session.click_link('Click me')
32
+ @session.click_link_or_button('Has been clicked')
33
+ end
34
+
35
+ it 'casts to string' do
36
+ @session.visit('/form')
37
+ @session.click_link_or_button(:awe123)
38
+ expect(extract_results(@session)['first_name']).to eq('John')
39
+ end
40
+
41
+ context 'with :exact option' do
42
+ context 'when `false`' do
43
+ it 'clicks on approximately matching link' do
44
+ @session.visit('/with_html')
45
+ @session.click_link_or_button('abore', exact: false)
46
+ expect(@session).to have_content('Bar')
47
+ end
48
+
49
+ it 'clicks on approximately matching button' do
50
+ @session.visit('/form')
51
+ @session.click_link_or_button('awe', exact: false)
52
+ expect(extract_results(@session)['first_name']).to eq('John')
53
+ end
54
+ end
55
+
56
+ context 'when `true`' do
57
+ it 'does not click on link which matches approximately' do
58
+ @session.visit('/with_html')
59
+ msg = 'Unable to find link or button "abore"'
60
+ expect do
61
+ @session.click_link_or_button('abore', exact: true)
62
+ end.to raise_error(Capybara::ElementNotFound, msg)
63
+ end
64
+
65
+ it 'does not click on approximately matching button' do
66
+ @session.visit('/form')
67
+ msg = 'Unable to find link or button "awe"'
68
+
69
+ expect do
70
+ @session.click_link_or_button('awe', exact: true)
71
+ end.to raise_error(Capybara::ElementNotFound, msg)
72
+ end
73
+ end
74
+ end
75
+
76
+ context "with a locator that doesn't exist" do
77
+ it 'should raise an error' do
78
+ @session.visit('/with_html')
79
+ msg = 'Unable to find link or button "does not exist"'
80
+ expect do
81
+ @session.click_link_or_button('does not exist')
82
+ end.to raise_error(Capybara::ElementNotFound, msg)
83
+ end
84
+ end
85
+
86
+ context 'with :disabled option' do
87
+ it 'ignores disabled buttons when false' do
88
+ @session.visit('/form')
89
+ expect do
90
+ @session.click_link_or_button('Disabled button', disabled: false)
91
+ end.to raise_error(Capybara::ElementNotFound)
92
+ end
93
+
94
+ it 'ignores disabled buttons by default' do
95
+ @session.visit('/form')
96
+ expect do
97
+ @session.click_link_or_button('Disabled button')
98
+ end.to raise_error(Capybara::ElementNotFound)
99
+ end
100
+
101
+ it 'happily clicks on links which incorrectly have the disabled attribute' do
102
+ @session.visit('/with_html')
103
+ @session.click_link_or_button('Disabled link')
104
+ expect(@session).to have_content('Bar')
105
+ end
106
+ end
107
+
108
+ it 'should return the element clicked' do
109
+ @session.visit('/with_html')
110
+ link = @session.find(:link, 'Blank Anchor')
111
+ expect(@session.click_link_or_button('Blank Anchor')).to eq link
112
+ end
113
+
114
+ context 'with enable_aria_label' do
115
+ it 'should click on link' do
116
+ @session.visit('/with_html')
117
+ expect do
118
+ @session.click_link_or_button('Go to simple', enable_aria_label: true)
119
+ end.not_to raise_error
120
+ end
121
+
122
+ it 'should click on button' do
123
+ @session.visit('/form')
124
+ expect do
125
+ @session.click_link_or_button('Aria button', enable_aria_label: true)
126
+ end.not_to raise_error
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#click_link' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should wait for asynchronous load', requires: [:js] do
9
+ Capybara.default_max_wait_time = 2
10
+ @session.visit('/with_js')
11
+ @session.click_link('Click me')
12
+ @session.click_link('Has been clicked')
13
+ end
14
+
15
+ it 'casts to string' do
16
+ @session.click_link(:foo)
17
+ expect(@session).to have_content('Another World')
18
+ end
19
+
20
+ it 'raises any errors caught inside the server', requires: [:server] do
21
+ quietly { @session.visit('/error') }
22
+ expect do
23
+ @session.click_link('foo')
24
+ end.to raise_error(TestApp::TestAppError)
25
+ end
26
+
27
+ context 'with id given' do
28
+ it 'should take user to the linked page' do
29
+ @session.click_link('foo')
30
+ expect(@session).to have_content('Another World')
31
+ end
32
+ end
33
+
34
+ context 'with text given' do
35
+ it 'should take user to the linked page' do
36
+ @session.click_link('labore')
37
+ expect(@session).to have_content('Bar')
38
+ end
39
+
40
+ it 'should accept partial matches', :exact_false do
41
+ @session.click_link('abo')
42
+ expect(@session).to have_content('Bar')
43
+ end
44
+ end
45
+
46
+ context 'with title given' do
47
+ it 'should take user to the linked page' do
48
+ @session.click_link('awesome title')
49
+ expect(@session).to have_content('Bar')
50
+ end
51
+
52
+ it 'should accept partial matches', :exact_false do
53
+ @session.click_link('some titl')
54
+ expect(@session).to have_content('Bar')
55
+ end
56
+ end
57
+
58
+ context 'with alternative text given to a contained image' do
59
+ it 'should take user to the linked page' do
60
+ @session.click_link('awesome image')
61
+ expect(@session).to have_content('Bar')
62
+ end
63
+
64
+ it 'should accept partial matches', :exact_false do
65
+ @session.click_link('some imag')
66
+ expect(@session).to have_content('Bar')
67
+ end
68
+ end
69
+
70
+ context "with a locator that doesn't exist" do
71
+ it 'should raise an error' do
72
+ msg = 'Unable to find link "does not exist"'
73
+ expect do
74
+ @session.click_link('does not exist')
75
+ end.to raise_error(Capybara::ElementNotFound, msg)
76
+ end
77
+ end
78
+
79
+ context 'with :href option given' do
80
+ it 'should find links with valid href' do
81
+ @session.click_link('labore', href: '/with_simple_html')
82
+ expect(@session).to have_content('Bar')
83
+ end
84
+
85
+ it "should raise error if link wasn't found" do
86
+ expect { @session.click_link('labore', href: 'invalid_href') }.to raise_error(Capybara::ElementNotFound, /with href "invalid_href/)
87
+ end
88
+ end
89
+
90
+ context 'with a regex :href option given' do
91
+ it 'should find a link matching an all-matching regex pattern' do
92
+ @session.click_link('labore', href: /.+/)
93
+ expect(@session).to have_content('Bar')
94
+ end
95
+
96
+ it 'should find a link matching an exact regex pattern' do
97
+ @session.click_link('labore', href: %r{/with_simple_html})
98
+ expect(@session).to have_content('Bar')
99
+ end
100
+
101
+ it 'should find a link matching a partial regex pattern' do
102
+ @session.click_link('labore', href: %r{/with_simple})
103
+ expect(@session).to have_content('Bar')
104
+ end
105
+
106
+ it "should raise an error if no link's href matched the pattern" do
107
+ expect { @session.click_link('labore', href: /invalid_pattern/) }.to raise_error(Capybara::ElementNotFound, %r{with href matching /invalid_pattern/})
108
+ expect { @session.click_link('labore', href: /.+d+/) }.to raise_error(Capybara::ElementNotFound, /#{Regexp.quote "with href matching /.+d+/"}/)
109
+ end
110
+
111
+ context 'href: nil' do
112
+ it 'should not raise an error on links with no href attribute' do
113
+ expect { @session.click_link('No Href', href: nil) }.not_to raise_error
114
+ end
115
+
116
+ it 'should raise an error if href attribute exists' do
117
+ expect { @session.click_link('Blank Href', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
118
+ expect { @session.click_link('Normal Anchor', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
119
+ end
120
+ end
121
+
122
+ context 'href: false' do
123
+ it 'should not raise an error on links with no href attribute' do
124
+ expect { @session.click_link('No Href', href: false) }.not_to raise_error
125
+ end
126
+
127
+ it 'should not raise an error if href attribute exists' do
128
+ expect { @session.click_link('Blank Href', href: false) }.not_to raise_error
129
+ expect { @session.click_link('Normal Anchor', href: false) }.not_to raise_error
130
+ end
131
+ end
132
+ end
133
+
134
+ it 'should follow relative links' do
135
+ @session.visit('/')
136
+ @session.click_link('Relative')
137
+ expect(@session).to have_content('This is a test')
138
+ end
139
+
140
+ it 'should follow protocol relative links' do
141
+ @session.click_link('Protocol')
142
+ expect(@session).to have_content('Another World')
143
+ end
144
+
145
+ it 'should follow redirects' do
146
+ @session.click_link('Redirect')
147
+ expect(@session).to have_content('You landed')
148
+ end
149
+
150
+ it 'should follow redirects back to itself' do
151
+ @session.click_link('BackToMyself')
152
+ expect(@session).to have_css('#referrer', text: %r{/with_html$})
153
+ expect(@session).to have_content('This is a test')
154
+ end
155
+
156
+ it 'should add query string to current URL with naked query string' do
157
+ @session.click_link('Naked Query String')
158
+ expect(@session).to have_content('Query String sent')
159
+ end
160
+
161
+ it 'should do nothing on anchor links' do
162
+ @session.fill_in('test_field', with: 'blah')
163
+ @session.click_link('Normal Anchor')
164
+ expect(@session.find_field('test_field').value).to eq('blah')
165
+ @session.click_link('Blank Anchor')
166
+ expect(@session.find_field('test_field').value).to eq('blah')
167
+ @session.click_link('Blank JS Anchor')
168
+ expect(@session.find_field('test_field').value).to eq('blah')
169
+ end
170
+
171
+ it 'should do nothing on URL+anchor links for the same page' do
172
+ @session.fill_in('test_field', with: 'blah')
173
+ @session.click_link('Anchor on same page')
174
+ expect(@session.find_field('test_field').value).to eq('blah')
175
+ end
176
+
177
+ it 'should follow link on URL+anchor links for a different page' do
178
+ @session.click_link('Anchor on different page')
179
+ expect(@session).to have_content('Bar')
180
+ end
181
+
182
+ it 'should follow link on anchor if the path has regex special characters' do
183
+ @session.visit('/with.*html')
184
+ @session.click_link('Anchor on different page')
185
+ expect(@session).to have_content('Bar')
186
+ end
187
+
188
+ it 'should raise an error with links with no href' do
189
+ expect do
190
+ @session.click_link('No Href')
191
+ end.to raise_error(Capybara::ElementNotFound)
192
+ end
193
+
194
+ context 'with :exact option' do
195
+ it 'should accept partial matches when false' do
196
+ @session.click_link('abo', exact: false)
197
+ expect(@session).to have_content('Bar')
198
+ end
199
+
200
+ it 'should not accept partial matches when true' do
201
+ expect do
202
+ @session.click_link('abo', exact: true)
203
+ end.to raise_error(Capybara::ElementNotFound)
204
+ end
205
+ end
206
+
207
+ context 'without locator' do
208
+ it 'uses options' do
209
+ @session.click_link(href: '/foo')
210
+ expect(@session).to have_content('Another World')
211
+ end
212
+ end
213
+
214
+ it 'should return element clicked' do
215
+ el = @session.find(:link, 'Normal Anchor')
216
+ expect(@session.click_link('Normal Anchor')).to eq el
217
+ end
218
+
219
+ it 'can download a file', requires: [:download] do
220
+ # This requires the driver used for the test to be configured
221
+ # to download documents with the mime type "text/csv"
222
+ download_file = File.join(Capybara.save_path, 'download.csv')
223
+ expect(File).not_to exist(download_file)
224
+ @session.click_link('Download Me')
225
+ sleep 2 # allow time for file to download
226
+ expect(File).to exist(download_file)
227
+ FileUtils.rm_rf download_file
228
+ end
229
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#current_scope' do
4
+ before do
5
+ @session.visit('/with_scope')
6
+ end
7
+
8
+ context 'when not in a #within block' do
9
+ it 'should return the document' do
10
+ expect(@session.current_scope).to be_kind_of Capybara::Node::Document
11
+ end
12
+ end
13
+
14
+ context 'when in a #within block' do
15
+ it 'should return the element in scope' do
16
+ @session.within(:css, '#simple_first_name') do
17
+ expect(@session.current_scope[:name]).to eq 'first_name'
18
+ end
19
+ end
20
+ end
21
+
22
+ context 'when in a nested #within block' do
23
+ it 'should return the element in scope' do
24
+ @session.within("//div[@id='for_bar']") do
25
+ @session.within(".//input[@value='Peter']") do
26
+ expect(@session.current_scope[:name]).to eq 'form[first_name]'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capybara/spec/test_app'
4
+
5
+ Capybara::SpecHelper.spec '#current_url, #current_path, #current_host' do
6
+ before :all do # rubocop:disable RSpec/BeforeAfterAll
7
+ @servers = Array.new(2) { Capybara::Server.new(TestApp.new).boot }
8
+ # sanity check
9
+ expect(@servers[0].port).not_to eq(@servers[1].port) # rubocop:disable RSpec/ExpectInHook
10
+ expect(@servers.map(&:port)).not_to include 80 # rubocop:disable RSpec/ExpectInHook
11
+ end
12
+
13
+ def bases
14
+ @servers.map { |s| "http://#{s.host}:#{s.port}" }
15
+ end
16
+
17
+ def should_be_on(server_index, path = '/host', scheme = 'http')
18
+ # Check that we are on /host on the given server
19
+ s = @servers[server_index]
20
+
21
+ expect(@session).to have_current_path("#{scheme}://#{s.host}:#{s.port}#{path}", url: true)
22
+
23
+ expect(@session.current_url.chomp('?')).to eq("#{scheme}://#{s.host}:#{s.port}#{path}")
24
+ expect(@session.current_host).to eq("#{scheme}://#{s.host}") # no port
25
+ expect(@session.current_path).to eq(path)
26
+ # Server should agree with us
27
+ expect(@session).to have_content("Current host is #{scheme}://#{s.host}:#{s.port}") if path == '/host'
28
+ end
29
+
30
+ def visit_host_links
31
+ @session.visit("#{bases[0]}/host_links?absolute_host=#{bases[1]}")
32
+ end
33
+
34
+ it 'is affected by visiting a page directly' do
35
+ @session.visit("#{bases[0]}/host")
36
+ should_be_on 0
37
+ end
38
+
39
+ it 'returns to the app host when visiting a relative url' do
40
+ Capybara.app_host = bases[1]
41
+ @session.visit("#{bases[0]}/host")
42
+ should_be_on 0
43
+ @session.visit('/host')
44
+ should_be_on 1
45
+ Capybara.app_host = nil
46
+ end
47
+
48
+ it 'is affected by setting Capybara.app_host' do
49
+ Capybara.app_host = bases[0]
50
+ @session.visit('/host')
51
+ should_be_on 0
52
+ Capybara.app_host = bases[1]
53
+ @session.visit('/host')
54
+ should_be_on 1
55
+ Capybara.app_host = nil
56
+ end
57
+
58
+ it 'is unaffected by following a relative link' do
59
+ visit_host_links
60
+ @session.click_link('Relative Host')
61
+ should_be_on 0
62
+ end
63
+
64
+ it 'is affected by following an absolute link' do
65
+ visit_host_links
66
+ @session.click_link('Absolute Host')
67
+ should_be_on 1
68
+ end
69
+
70
+ it 'is unaffected by posting through a relative form' do
71
+ visit_host_links
72
+ @session.click_button('Relative Host')
73
+ should_be_on 0
74
+ end
75
+
76
+ it 'is affected by posting through an absolute form' do
77
+ visit_host_links
78
+ @session.click_button('Absolute Host')
79
+ should_be_on 1
80
+ end
81
+
82
+ it 'is affected by following a redirect' do
83
+ @session.visit("#{bases[0]}/redirect")
84
+ should_be_on 0, '/landed'
85
+ end
86
+
87
+ it 'is affected by pushState', requires: [:js] do
88
+ @session.visit('/with_js')
89
+ @session.execute_script("window.history.pushState({}, '', '/pushed')")
90
+ expect(@session.current_path).to eq('/pushed')
91
+ end
92
+
93
+ it 'is affected by replaceState', requires: [:js] do
94
+ @session.visit('/with_js')
95
+ @session.execute_script("window.history.replaceState({}, '', '/replaced')")
96
+ expect(@session.current_path).to eq('/replaced')
97
+ end
98
+
99
+ it "doesn't raise exception on a nil current_url", requires: [:driver] do
100
+ allow(@session.driver).to receive(:current_url).and_return(nil)
101
+ @session.visit('/')
102
+ expect { @session.current_url }.not_to raise_exception
103
+ expect { @session.current_path }.not_to raise_exception
104
+ end
105
+
106
+ context 'within iframe', requires: [:frames] do
107
+ it 'should get the url of the top level browsing context' do
108
+ @session.visit('/within_frames')
109
+ expect(@session.current_url).to match(/within_frames\z/)
110
+ @session.within_frame('frameOne') do
111
+ expect(@session.current_url).to match(/within_frames\z/)
112
+ end
113
+ end
114
+ end
115
+ end