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,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#have_sibling' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should assert a prior sibling element using the given locator' do
9
+ el = @session.find(:css, '#mid_sibling')
10
+ expect(el).to have_sibling(:css, '#pre_sibling')
11
+ end
12
+
13
+ it 'should assert a following sibling element using the given locator' do
14
+ el = @session.find(:css, '#mid_sibling')
15
+ expect(el).to have_sibling(:css, '#post_sibling')
16
+ end
17
+
18
+ it 'should not raise an error if there are multiple matches' do
19
+ el = @session.find(:css, '#mid_sibling')
20
+ expect(el).to have_sibling(:css, 'div')
21
+ end
22
+
23
+ it 'should allow counts to be specified' do
24
+ el = @session.find(:css, '#mid_sibling')
25
+
26
+ expect(el).to have_sibling(:css, 'div').exactly(2).times
27
+ expect do
28
+ expect(el).to have_sibling(:css, 'div').once
29
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
30
+ end
31
+ end
32
+
33
+ Capybara::SpecHelper.spec '#have_no_sibling' do
34
+ before do
35
+ @session.visit('/with_html')
36
+ end
37
+
38
+ it 'should assert no matching sibling' do
39
+ el = @session.find(:css, '#mid_sibling')
40
+ expect(el).to have_no_sibling(:css, '#not_a_sibling')
41
+ expect(el).not_to have_sibling(:css, '#not_a_sibling')
42
+ end
43
+
44
+ it 'should raise if there are matching siblings' do
45
+ el = @session.find(:css, '#mid_sibling')
46
+ expect do
47
+ expect(el).to have_no_sibling(:css, '#pre_sibling')
48
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
49
+ end
50
+ end
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#has_table?' do
4
+ before do
5
+ @session.visit('/tables')
6
+ end
7
+
8
+ it 'should be true if the table is on the page' do
9
+ expect(@session).to have_table('Villain')
10
+ expect(@session).to have_table('villain_table')
11
+ expect(@session).to have_table(:villain_table)
12
+ end
13
+
14
+ it 'should accept rows with column header hashes' do
15
+ expect(@session).to have_table('Horizontal Headers', with_rows:
16
+ [
17
+ { 'First Name' => 'Vern', 'Last Name' => 'Konopelski', 'City' => 'Everette' },
18
+ { 'First Name' => 'Palmer', 'Last Name' => 'Sawayn', 'City' => 'West Trinidad' }
19
+ ])
20
+ end
21
+
22
+ it 'should accept rows with partial column header hashses' do
23
+ expect(@session).to have_table('Horizontal Headers', with_rows:
24
+ [
25
+ { 'First Name' => 'Thomas' },
26
+ { 'Last Name' => 'Sawayn', 'City' => 'West Trinidad' }
27
+ ])
28
+ end
29
+
30
+ it 'should accept rows with array of cell values' do
31
+ expect(@session).to have_table('Horizontal Headers', with_rows:
32
+ [
33
+ %w[Thomas Walpole Oceanside],
34
+ ['Ratke', 'Lawrence', 'East Sorayashire']
35
+ ])
36
+ end
37
+
38
+ it 'should consider order of cells in each row' do
39
+ expect(@session).not_to have_table('Horizontal Headers', with_rows:
40
+ [
41
+ %w[Thomas Walpole Oceanside],
42
+ ['Lawrence', 'Ratke', 'East Sorayashire']
43
+ ])
44
+ end
45
+
46
+ it 'should accept all rows with array of cell values' do
47
+ expect(@session).to have_table('Horizontal Headers', rows:
48
+ [
49
+ %w[Thomas Walpole Oceanside],
50
+ %w[Danilo Wilkinson Johnsonville],
51
+ %w[Vern Konopelski Everette],
52
+ ['Ratke', 'Lawrence', 'East Sorayashire'],
53
+ ['Palmer', 'Sawayn', 'West Trinidad']
54
+ ])
55
+ end
56
+
57
+ it 'should match with vertical headers' do
58
+ expect(@session).to have_table('Vertical Headers', with_cols:
59
+ [
60
+ { 'First Name' => 'Thomas' },
61
+ { 'First Name' => 'Danilo', 'Last Name' => 'Wilkinson', 'City' => 'Johnsonville' },
62
+ { 'Last Name' => 'Sawayn', 'City' => 'West Trinidad' }
63
+ ])
64
+ end
65
+
66
+ it 'should match col with array of cell values' do
67
+ expect(@session).to have_table('Vertical Headers', with_cols:
68
+ [
69
+ %w[Vern Konopelski Everette]
70
+ ])
71
+ end
72
+
73
+ it 'should match cols with array of cell values' do
74
+ expect(@session).to have_table('Vertical Headers', with_cols:
75
+ [
76
+ %w[Danilo Wilkinson Johnsonville],
77
+ %w[Vern Konopelski Everette]
78
+ ])
79
+ end
80
+
81
+ it 'should match all cols with array of cell values' do
82
+ expect(@session).to have_table('Vertical Headers', cols:
83
+ [
84
+ %w[Thomas Walpole Oceanside],
85
+ %w[Danilo Wilkinson Johnsonville],
86
+ %w[Vern Konopelski Everette],
87
+ ['Ratke', 'Lawrence', 'East Sorayashire'],
88
+ ['Palmer', 'Sawayn', 'West Trinidad']
89
+ ])
90
+ end
91
+
92
+ it "should not match if the order of cell values doesn't match" do
93
+ expect(@session).not_to have_table('Vertical Headers', with_cols:
94
+ [
95
+ %w[Vern Everette Konopelski]
96
+ ])
97
+ end
98
+
99
+ it "should not match with vertical headers if the columns don't match" do
100
+ expect(@session).not_to have_table('Vertical Headers', with_cols:
101
+ [
102
+ { 'First Name' => 'Thomas' },
103
+ { 'First Name' => 'Danilo', 'Last Name' => 'Walpole', 'City' => 'Johnsonville' },
104
+ { 'Last Name' => 'Sawayn', 'City' => 'West Trinidad' }
105
+ ])
106
+ end
107
+
108
+ it 'should be false if the table is not on the page' do
109
+ expect(@session).not_to have_table('Monkey')
110
+ end
111
+
112
+ it 'should find row by header and cell values' do
113
+ expect(@session.find(:table, 'Horizontal Headers')).to have_selector(:table_row, 'First Name' => 'Thomas', 'Last Name' => 'Walpole')
114
+ expect(@session.find(:table, 'Horizontal Headers')).to have_selector(:table_row, 'Last Name' => 'Walpole')
115
+ expect(@session.find(:table, 'Horizontal Headers')).not_to have_selector(:table_row, 'First Name' => 'Walpole')
116
+ end
117
+
118
+ it 'should find row by cell values' do
119
+ expect(@session.find(:table, 'Horizontal Headers')).to have_selector(:table_row, %w[Thomas Walpole])
120
+ expect(@session.find(:table, 'Horizontal Headers')).not_to have_selector(:table_row, %w[Walpole Thomas])
121
+ expect(@session.find(:table, 'Horizontal Headers')).not_to have_selector(:table_row, %w[Other])
122
+ end
123
+ end
124
+
125
+ Capybara::SpecHelper.spec '#has_no_table?' do
126
+ before do
127
+ @session.visit('/tables')
128
+ end
129
+
130
+ it 'should be false if the table is on the page' do
131
+ expect(@session).not_to have_no_table('Villain')
132
+ expect(@session).not_to have_no_table('villain_table')
133
+ end
134
+
135
+ it 'should be true if the table is not on the page' do
136
+ expect(@session).to have_no_table('Monkey')
137
+ end
138
+
139
+ it 'should consider rows' do
140
+ expect(@session).to have_no_table('Horizontal Headers', with_rows:
141
+ [
142
+ { 'First Name' => 'Thomas', 'City' => 'Los Angeles' }
143
+ ])
144
+ end
145
+
146
+ context 'using :with_cols' do
147
+ it 'should consider a single column' do
148
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
149
+ [
150
+ { 'First Name' => 'Joe' }
151
+ ])
152
+ end
153
+
154
+ it 'should be true even if the last column does exist' do
155
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
156
+ [
157
+ {
158
+ 'First Name' => 'What?',
159
+ 'What?' => 'Walpole',
160
+ 'City' => 'Oceanside' # This line makes the example fail
161
+ }
162
+ ])
163
+ end
164
+
165
+ it 'should be true if none of the columns exist' do
166
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
167
+ [
168
+ {
169
+ 'First Name' => 'What?',
170
+ 'What?' => 'Walpole',
171
+ 'City' => 'What?'
172
+ }
173
+ ])
174
+ end
175
+
176
+ it 'should be true if the first column does match' do
177
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
178
+ [
179
+ {
180
+ 'First Name' => 'Thomas',
181
+ 'Last Name' => 'What',
182
+ 'City' => 'What'
183
+ }
184
+ ])
185
+ end
186
+
187
+ it 'should be true if none of the columns match' do
188
+ expect(@session).to have_no_table('Vertical Headers', with_cols:
189
+ [
190
+ {
191
+ 'First Name' => 'What',
192
+ 'Last Name' => 'What',
193
+ 'City' => 'What'
194
+ }
195
+ ])
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,394 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#has_text?' do
4
+ it 'should be true if the given text is on the page at least once' do
5
+ @session.visit('/with_html')
6
+ expect(@session).to have_text('est')
7
+ expect(@session).to have_text('Lorem')
8
+ expect(@session).to have_text('Redirect')
9
+ expect(@session).to have_text(:Redirect)
10
+ end
11
+
12
+ it 'should be true if scoped to an element which has the text' do
13
+ @session.visit('/with_html')
14
+ @session.within("//a[@title='awesome title']") do
15
+ expect(@session).to have_text('labore')
16
+ end
17
+ end
18
+
19
+ it 'should be false if scoped to an element which does not have the text' do
20
+ @session.visit('/with_html')
21
+ @session.within("//a[@title='awesome title']") do
22
+ expect(@session).not_to have_text('monkey')
23
+ end
24
+ end
25
+
26
+ it 'should ignore tags' do
27
+ @session.visit('/with_html')
28
+ expect(@session).not_to have_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
29
+ expect(@session).to have_text('exercitation ullamco laboris')
30
+ end
31
+
32
+ it 'should search correctly normalized text' do
33
+ @session.visit('/with_html')
34
+ expect(@session).to have_text('text with whitespace')
35
+ end
36
+
37
+ it 'should search whitespace collapsed text' do
38
+ @session.visit('/with_html')
39
+ expect(@session).to have_text('text with whitespace', normalize_ws: true)
40
+ end
41
+
42
+ context 'with enabled default collapsing whitespace' do
43
+ before { Capybara.default_normalize_ws = true }
44
+
45
+ it 'should search unnormalized text' do
46
+ @session.visit('/with_html')
47
+ expect(@session).to have_text('text with whitespace', normalize_ws: false)
48
+ end
49
+
50
+ it 'should search whitespace collapsed text' do
51
+ @session.visit('/with_html')
52
+ expect(@session).to have_text('text with whitespace')
53
+ end
54
+ end
55
+
56
+ it 'should be false if the given text is not on the page' do
57
+ @session.visit('/with_html')
58
+ expect(@session).not_to have_text('xxxxyzzz')
59
+ expect(@session).not_to have_text('monkey')
60
+ end
61
+
62
+ it 'should handle single quotes in the text' do
63
+ @session.visit('/with-quotes')
64
+ expect(@session).to have_text("can't")
65
+ end
66
+
67
+ it 'should handle double quotes in the text' do
68
+ @session.visit('/with-quotes')
69
+ expect(@session).to have_text('"No," he said')
70
+ end
71
+
72
+ it 'should handle mixed single and double quotes in the text' do
73
+ @session.visit('/with-quotes')
74
+ expect(@session).to have_text(%q("you can't do that."))
75
+ end
76
+
77
+ it 'should be false if text is in the title tag in the head' do
78
+ @session.visit('/with_js')
79
+ expect(@session).not_to have_text('with_js')
80
+ end
81
+
82
+ it 'should be false if text is inside a script tag in the body' do
83
+ @session.visit('/with_js')
84
+ expect(@session).not_to have_text('a javascript comment')
85
+ expect(@session).not_to have_text('aVar')
86
+ end
87
+
88
+ it 'should be false if the given text is on the page but not visible' do
89
+ @session.visit('/with_html')
90
+ expect(@session).not_to have_text('Inside element with hidden ancestor')
91
+ end
92
+
93
+ it 'should be true if :all given and text is invisible.' do
94
+ @session.visit('/with_html')
95
+ expect(@session).to have_text(:all, 'Some of this text is hidden!')
96
+ end
97
+
98
+ it 'should be true if `Capybara.ignore_hidden_elements = false` and text is invisible.' do
99
+ Capybara.ignore_hidden_elements = false
100
+ @session.visit('/with_html')
101
+ expect(@session).to have_text('Some of this text is hidden!')
102
+ end
103
+
104
+ it 'should be true if the text in the page matches given regexp' do
105
+ @session.visit('/with_html')
106
+ expect(@session).to have_text(/Lorem/)
107
+ end
108
+
109
+ it "should be false if the text in the page doesn't match given regexp" do
110
+ @session.visit('/with_html')
111
+ expect(@session).not_to have_text(/xxxxyzzz/)
112
+ end
113
+
114
+ context 'with object implementing to_s and to_hash' do
115
+ it 'should work if the object is passed alone' do
116
+ with_to_hash = Class.new do
117
+ def to_s; '42' end
118
+ def to_hash; { value: 'Other hash' } end
119
+ end.new
120
+ @session.visit('/with_html')
121
+ expect(@session).to have_text(with_to_hash)
122
+ end
123
+
124
+ it 'should work if passed with empty options' do
125
+ with_to_hash = Class.new do
126
+ def to_s; '42' end
127
+ def to_hash; { value: 'Other hash' } end
128
+ end.new
129
+ @session.visit('/with_html')
130
+ if RUBY_VERSION >= '2.7'
131
+ expect(@session).to have_text(:visible, with_to_hash, **{})
132
+ else
133
+ expect(@session).to have_text(:visible, with_to_hash, {})
134
+ end
135
+ end
136
+
137
+ it 'should fail if passed without empty options' do
138
+ with_to_hash = Class.new do
139
+ def to_s; '42' end
140
+ def to_hash; { blah: 'Other hash' } end
141
+ end.new
142
+ @session.visit('/with_html')
143
+ expect do
144
+ expect(@session).to have_text(:visible, with_to_hash)
145
+ end.to raise_error(ArgumentError)
146
+ end
147
+ end
148
+
149
+ context 'with exact: true option' do
150
+ it 'should be true if text matches exactly' do
151
+ @session.visit('/with_html')
152
+ expect(@session.find(:id, 'h2one')).to have_text('Header Class Test One', exact: true)
153
+ end
154
+
155
+ it "should be false if text doesn't match exactly" do
156
+ @session.visit('/with_html')
157
+ expect(@session.find(:id, 'h2one')).not_to have_text('Header Class Test On', exact: true)
158
+ end
159
+ end
160
+
161
+ it 'should escape any characters that would have special meaning in a regexp' do
162
+ @session.visit('/with_html')
163
+ expect(@session).not_to have_text('.orem')
164
+ end
165
+
166
+ it 'should accept non-string parameters' do
167
+ @session.visit('/with_html')
168
+ expect(@session).to have_text(42)
169
+ end
170
+
171
+ it 'should be true when passed nil' do
172
+ # nil is converted to '' when to_s is invoked
173
+ @session.visit('/with_html')
174
+ expect(@session).to have_text(nil)
175
+ end
176
+
177
+ it 'should warn when passed nil' do
178
+ @session.visit('/with_html')
179
+ expect_any_instance_of(Kernel).to receive(:warn).with(/Checking for expected text of nil is confusing/) # rubocop:disable RSpec/AnyInstance
180
+ expect(@session).to have_text(nil)
181
+ end
182
+
183
+ it 'should wait for text to appear', requires: [:js] do
184
+ Capybara.using_wait_time(3) do
185
+ @session.visit('/with_js')
186
+ @session.click_link('Click me')
187
+ expect(@session).to have_text('Has been clicked')
188
+ end
189
+ end
190
+
191
+ context 'with between' do
192
+ it 'should be true if the text occurs within the range given' do
193
+ @session.visit('/with_count')
194
+ expect(@session).to have_text('count', between: 1..3)
195
+ expect(@session).to have_text(/count/, between: 2..2)
196
+ end
197
+
198
+ it 'should be false if the text occurs more or fewer times than range' do
199
+ @session.visit('/with_count')
200
+ expect(@session).not_to have_text('count', between: 0..1)
201
+ expect(@session).not_to have_text('count', between: 3..10)
202
+ expect(@session).not_to have_text(/count/, between: 2...2)
203
+ end
204
+ end
205
+
206
+ context 'with count' do
207
+ it 'should be true if the text occurs the given number of times' do
208
+ @session.visit('/with_count')
209
+ expect(@session).to have_text('count', count: 2)
210
+ expect(@session).to have_text('count').exactly(2).times
211
+ end
212
+
213
+ it 'should be false if the text occurs a different number of times than the given' do
214
+ @session.visit('/with_count')
215
+ expect(@session).not_to have_text('count', count: 0)
216
+ expect(@session).not_to have_text('count', count: 1)
217
+ expect(@session).not_to have_text('count').once
218
+ expect(@session).not_to have_text(/count/, count: 3)
219
+ end
220
+
221
+ it 'should coerce count to an integer' do
222
+ @session.visit('/with_count')
223
+ expect(@session).to have_text('count', count: '2')
224
+ expect(@session).not_to have_text('count', count: '3')
225
+ end
226
+ end
227
+
228
+ context 'with maximum' do
229
+ it 'should be true when text occurs same or fewer times than given' do
230
+ @session.visit('/with_count')
231
+ expect(@session).to have_text('count', maximum: 2)
232
+ expect(@session).to have_text('count').at_most(2).times
233
+ expect(@session).to have_text(/count/, maximum: 3)
234
+ end
235
+
236
+ it 'should be false when text occurs more times than given' do
237
+ @session.visit('/with_count')
238
+ expect(@session).not_to have_text('count', maximum: 1)
239
+ expect(@session).not_to have_text('count').at_most(1).times
240
+ expect(@session).not_to have_text('count', maximum: 0)
241
+ end
242
+
243
+ it 'should coerce maximum to an integer' do
244
+ @session.visit('/with_count')
245
+ expect(@session).to have_text('count', maximum: '2')
246
+ expect(@session).not_to have_text('count', maximum: '1')
247
+ end
248
+ end
249
+
250
+ context 'with minimum' do
251
+ it 'should be true when text occurs same or more times than given' do
252
+ @session.visit('/with_count')
253
+ expect(@session).to have_text('count', minimum: 2)
254
+ expect(@session).to have_text('count').at_least(2).times
255
+ expect(@session).to have_text(/count/, minimum: 0)
256
+ end
257
+
258
+ it 'should be false when text occurs fewer times than given' do
259
+ @session.visit('/with_count')
260
+ expect(@session).not_to have_text('count', minimum: 3)
261
+ expect(@session).not_to have_text('count').at_least(3).times
262
+ end
263
+
264
+ it 'should coerce minimum to an integer' do
265
+ @session.visit('/with_count')
266
+ expect(@session).to have_text('count', minimum: '2')
267
+ expect(@session).not_to have_text('count', minimum: '3')
268
+ end
269
+ end
270
+
271
+ context 'with wait', requires: [:js] do
272
+ it 'should find element if it appears before given wait duration' do
273
+ Capybara.using_wait_time(0.1) do
274
+ @session.visit('/with_js')
275
+ @session.click_link('Click me')
276
+ expect(@session).to have_text('Has been clicked', wait: 3)
277
+ end
278
+ end
279
+ end
280
+
281
+ it 'should raise an error if an invalid option is passed' do
282
+ @session.visit('/with_html')
283
+ expect do
284
+ expect(@session).to have_text('Lorem', invalid: true)
285
+ end.to raise_error(ArgumentError)
286
+ end
287
+ end
288
+
289
+ Capybara::SpecHelper.spec '#has_no_text?' do
290
+ it 'should be false if the given text is on the page at least once' do
291
+ @session.visit('/with_html')
292
+ expect(@session).not_to have_no_text('est')
293
+ expect(@session).not_to have_no_text('Lorem')
294
+ expect(@session).not_to have_no_text('Redirect')
295
+ end
296
+
297
+ it 'should be false if scoped to an element which has the text' do
298
+ @session.visit('/with_html')
299
+ @session.within("//a[@title='awesome title']") do
300
+ expect(@session).not_to have_no_text('labore')
301
+ end
302
+ end
303
+
304
+ it 'should be true if scoped to an element which does not have the text' do
305
+ @session.visit('/with_html')
306
+ @session.within("//a[@title='awesome title']") do
307
+ expect(@session).to have_no_text('monkey')
308
+ end
309
+ end
310
+
311
+ it 'should ignore tags' do
312
+ @session.visit('/with_html')
313
+ expect(@session).to have_no_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
314
+ expect(@session).not_to have_no_text('exercitation ullamco laboris')
315
+ end
316
+
317
+ it 'should be true if the given text is not on the page' do
318
+ @session.visit('/with_html')
319
+ expect(@session).to have_no_text('xxxxyzzz')
320
+ expect(@session).to have_no_text('monkey')
321
+ end
322
+
323
+ it 'should handle single quotes in the text' do
324
+ @session.visit('/with-quotes')
325
+ expect(@session).not_to have_no_text("can't")
326
+ end
327
+
328
+ it 'should handle double quotes in the text' do
329
+ @session.visit('/with-quotes')
330
+ expect(@session).not_to have_no_text('"No," he said')
331
+ end
332
+
333
+ it 'should handle mixed single and double quotes in the text' do
334
+ @session.visit('/with-quotes')
335
+ expect(@session).not_to have_no_text(%q("you can't do that."))
336
+ end
337
+
338
+ it 'should be true if text is in the title tag in the head' do
339
+ @session.visit('/with_js')
340
+ expect(@session).to have_no_text('with_js')
341
+ end
342
+
343
+ it 'should be true if text is inside a script tag in the body' do
344
+ @session.visit('/with_js')
345
+ expect(@session).to have_no_text('a javascript comment')
346
+ expect(@session).to have_no_text('aVar')
347
+ end
348
+
349
+ it 'should be true if the given text is on the page but not visible' do
350
+ @session.visit('/with_html')
351
+ expect(@session).to have_no_text('Inside element with hidden ancestor')
352
+ end
353
+
354
+ it 'should be false if :all given and text is invisible.' do
355
+ @session.visit('/with_html')
356
+ expect(@session).not_to have_no_text(:all, 'Some of this text is hidden!')
357
+ end
358
+
359
+ it 'should be false if `Capybara.ignore_hidden_elements = false` and text is invisible.' do
360
+ Capybara.ignore_hidden_elements = false
361
+ @session.visit('/with_html')
362
+ expect(@session).not_to have_no_text('Some of this text is hidden!')
363
+ end
364
+
365
+ it "should be true if the text in the page doesn't match given regexp" do
366
+ @session.visit('/with_html')
367
+ expect(@session).to have_no_text(/xxxxyzzz/)
368
+ end
369
+
370
+ it 'should be false if the text in the page matches given regexp' do
371
+ @session.visit('/with_html')
372
+ expect(@session).not_to have_no_text(/Lorem/)
373
+ end
374
+
375
+ it 'should escape any characters that would have special meaning in a regexp' do
376
+ @session.visit('/with_html')
377
+ expect(@session).to have_no_text('.orem')
378
+ end
379
+
380
+ it 'should wait for text to disappear', requires: [:js] do
381
+ Capybara.default_max_wait_time = 2
382
+ @session.visit('/with_js')
383
+ @session.click_link('Click me')
384
+ expect(@session).to have_no_text('I changed it')
385
+ end
386
+
387
+ context 'with wait', requires: [:js] do
388
+ it 'should not find element if it appears after given wait duration' do
389
+ @session.visit('/with_js')
390
+ @session.click_link('Click me')
391
+ expect(@session).to have_no_text('Has been clicked', wait: 0.05)
392
+ end
393
+ end
394
+ end