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,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#go_forward', requires: [:js] do
4
+ it 'should fetch a response from the driver from the previous page' do
5
+ @session.visit('/')
6
+ expect(@session).to have_content('Hello world!')
7
+ @session.visit('/foo')
8
+ expect(@session).to have_content('Another World')
9
+ @session.go_back
10
+ expect(@session).to have_content('Hello world!')
11
+ @session.go_forward
12
+ expect(@session).to have_content('Another World')
13
+ end
14
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#have_all_of_selectors' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should be true if the given selectors are on the page' do
9
+ expect(@session).to have_all_of_selectors(:css, 'p a#foo', 'h2#h2one', 'h2#h2two')
10
+ end
11
+
12
+ it 'should be false if any of the given selectors are not on the page' do
13
+ expect do
14
+ expect(@session).to have_all_of_selectors(:css, 'p a#foo', 'h2#h2three', 'h2#h2one')
15
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
16
+ end
17
+
18
+ it 'should use default selector' do
19
+ Capybara.default_selector = :css
20
+ expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2two', 'h2#h2one')
21
+ expect do
22
+ expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2three', 'h2#h2one')
23
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
24
+ end
25
+
26
+ context 'should respect scopes' do
27
+ it 'when used with `within`' do
28
+ @session.within "//p[@id='first']" do
29
+ expect(@session).to have_all_of_selectors(".//a[@id='foo']")
30
+ expect do
31
+ expect(@session).to have_all_of_selectors(".//a[@id='red']")
32
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
33
+ end
34
+ end
35
+
36
+ it 'when called on elements' do
37
+ el = @session.find "//p[@id='first']"
38
+ expect(el).to have_all_of_selectors(".//a[@id='foo']")
39
+ expect do
40
+ expect(el).to have_all_of_selectors(".//a[@id='red']")
41
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
42
+ end
43
+ end
44
+
45
+ context 'with options' do
46
+ it 'should apply options to all locators' do
47
+ expect(@session).to have_all_of_selectors(:field, 'normal', 'additional_newline', type: :textarea)
48
+ expect do
49
+ expect(@session).to have_all_of_selectors(:field, 'normal', 'test_field', 'additional_newline', type: :textarea)
50
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
51
+ end
52
+ end
53
+
54
+ context 'with wait', requires: [:js] do
55
+ it 'should not raise error if all the elements appear before given wait duration' do
56
+ Capybara.using_wait_time(0.1) do
57
+ @session.visit('/with_js')
58
+ @session.click_link('Click me')
59
+ expect(@session).to have_all_of_selectors(:css, 'a#clickable', 'a#has-been-clicked', '#drag', wait: 5)
60
+ end
61
+ end
62
+ end
63
+
64
+ it 'cannot be negated' do
65
+ expect do
66
+ expect(@session).not_to have_all_of_selectors(:css, 'p a#foo', 'h2#h2one', 'h2#h2two')
67
+ end.to raise_error ArgumentError
68
+ end
69
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#have_ancestor' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should assert an ancestor using the given locator' do
9
+ el = @session.find(:css, '#ancestor1')
10
+ expect(el).to have_ancestor(:css, '#ancestor2')
11
+ end
12
+
13
+ it 'should assert an ancestor even if not parent' do
14
+ el = @session.find(:css, '#child')
15
+ expect(el).to have_ancestor(:css, '#ancestor3')
16
+ end
17
+
18
+ it 'should not raise an error if there are multiple matches' do
19
+ el = @session.find(:css, '#child')
20
+ expect(el).to have_ancestor(:css, 'div')
21
+ end
22
+
23
+ it 'should allow counts to be specified' do
24
+ el = @session.find(:css, '#child')
25
+
26
+ expect do
27
+ expect(el).to have_ancestor(:css, 'div').once
28
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
29
+
30
+ expect(el).to have_ancestor(:css, 'div').exactly(3).times
31
+ end
32
+ end
33
+
34
+ Capybara::SpecHelper.spec '#have_no_ancestor' do
35
+ before do
36
+ @session.visit('/with_html')
37
+ end
38
+
39
+ it 'should assert no matching ancestor' do
40
+ el = @session.find(:css, '#ancestor1')
41
+ expect(el).to have_no_ancestor(:css, '#child')
42
+ expect(el).to have_no_ancestor(:css, '#ancestor1_sibiling')
43
+ expect(el).not_to have_ancestor(:css, '#child')
44
+ expect(el).not_to have_ancestor(:css, '#ancestor1_sibiling')
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#have_any_of_selectors' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should be true if any of the given selectors are on the page' do
9
+ expect(@session).to have_any_of_selectors(:css, 'p a#foo', 'h2#blah', 'h2#h2two')
10
+ end
11
+
12
+ it 'should be false if none of the given selectors are not on the page' do
13
+ expect do
14
+ expect(@session).to have_any_of_selectors(:css, 'span a#foo', 'h2#h2nope', 'h2#h2one_no')
15
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
16
+ end
17
+
18
+ it 'should use default selector' do
19
+ Capybara.default_selector = :css
20
+ expect(@session).to have_any_of_selectors('p a#foo', 'h2#h2two', 'a#not_on_page')
21
+ expect do
22
+ expect(@session).to have_any_of_selectors('p a#blah', 'h2#h2three')
23
+ end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
24
+ end
25
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#has_button?' do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it 'should be true if the given button is on the page' do
9
+ expect(@session).to have_button('med')
10
+ expect(@session).to have_button('crap321')
11
+ expect(@session).to have_button(:crap321)
12
+ end
13
+
14
+ it 'should be true for disabled buttons if disabled: true' do
15
+ expect(@session).to have_button('Disabled button', disabled: true)
16
+ end
17
+
18
+ it 'should be false if the given button is not on the page' do
19
+ expect(@session).not_to have_button('monkey')
20
+ end
21
+
22
+ it 'should be false for disabled buttons by default' do
23
+ expect(@session).not_to have_button('Disabled button')
24
+ end
25
+
26
+ it 'should be false for disabled buttons if disabled: false' do
27
+ expect(@session).not_to have_button('Disabled button', disabled: false)
28
+ end
29
+
30
+ it 'should be true for disabled buttons if disabled: :all' do
31
+ expect(@session).to have_button('Disabled button', disabled: :all)
32
+ end
33
+
34
+ it 'should be true for enabled buttons if disabled: :all' do
35
+ expect(@session).to have_button('med', disabled: :all)
36
+ end
37
+
38
+ it 'can verify button type' do
39
+ expect(@session).to have_button('awe123', type: 'submit')
40
+ expect(@session).not_to have_button('awe123', type: 'reset')
41
+ end
42
+ end
43
+
44
+ Capybara::SpecHelper.spec '#has_no_button?' do
45
+ before do
46
+ @session.visit('/form')
47
+ end
48
+
49
+ it 'should be true if the given button is on the page' do
50
+ expect(@session).not_to have_no_button('med')
51
+ expect(@session).not_to have_no_button('crap321')
52
+ end
53
+
54
+ it 'should be true for disabled buttons if disabled: true' do
55
+ expect(@session).not_to have_no_button('Disabled button', disabled: true)
56
+ end
57
+
58
+ it 'should be false if the given button is not on the page' do
59
+ expect(@session).to have_no_button('monkey')
60
+ end
61
+
62
+ it 'should be false for disabled buttons by default' do
63
+ expect(@session).to have_no_button('Disabled button')
64
+ end
65
+
66
+ it 'should be false for disabled buttons if disabled: false' do
67
+ expect(@session).to have_no_button('Disabled button', disabled: false)
68
+ end
69
+ end
@@ -0,0 +1,374 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#has_css?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it 'should be true if the given selector is on the page' do
9
+ expect(@session).to have_css('p')
10
+ expect(@session).to have_css('p a#foo')
11
+ end
12
+
13
+ it 'should warn when passed a symbol' do
14
+ # This was never a specifically accepted format but it has worked for a
15
+ # lot of versions.
16
+ # TODO: Remove in 4.0
17
+ expect_any_instance_of(Kernel).to receive(:warn) # rubocop:disable RSpec/AnyInstance
18
+ expect(@session).to have_css(:p)
19
+ end
20
+
21
+ it 'should be false if the given selector is not on the page' do
22
+ expect(@session).not_to have_css('abbr')
23
+ expect(@session).not_to have_css('p a#doesnotexist')
24
+ expect(@session).not_to have_css('p.nosuchclass')
25
+ end
26
+
27
+ it 'should support :id option' do
28
+ expect(@session).to have_css('h2', id: 'h2one')
29
+ expect(@session).to have_css('h2')
30
+ expect(@session).to have_css('h2', id: /h2o/)
31
+ expect(@session).to have_css('li', id: /john|paul/)
32
+ end
33
+
34
+ it 'should support :class option' do
35
+ expect(@session).to have_css('li', class: 'guitarist')
36
+ expect(@session).to have_css('li', class: /guitar/)
37
+ expect(@session).to have_css('li', class: /guitar|drummer/)
38
+ expect(@session).to have_css('li', class: %w[beatle guitarist])
39
+ expect(@session).to have_css('li', class: /.*/)
40
+ end
41
+
42
+ context ':style option' do
43
+ it 'should support String' do
44
+ expect(@session).to have_css('p', style: 'line-height: 25px;')
45
+
46
+ expect do
47
+ expect(@session).to have_css('p', style: 'display: not_valid')
48
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /style attribute "display: not_valid"/)
49
+ end
50
+
51
+ it 'should support Regexp' do
52
+ expect(@session).to have_css('p', style: /-height: 2/)
53
+
54
+ expect do
55
+ expect(@session).to have_css('p', style: /not_valid/)
56
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, %r{style attribute matching /not_valid/})
57
+ end
58
+
59
+ it 'should support Hash', requires: [:css] do
60
+ expect(@session).to have_css('p', style: { 'line-height': '25px' })
61
+
62
+ expect do
63
+ expect(@session).to have_css('p', style: { 'line-height': '30px' })
64
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /with styles \{:"line-height"=>"30px"\}/)
65
+ end
66
+ end
67
+
68
+ it 'should support case insensitive :class and :id options' do
69
+ expect(@session).to have_css('li', class: /UiTaRI/i)
70
+ expect(@session).to have_css('h2', id: /2ON/i)
71
+ end
72
+
73
+ context 'when scoped' do
74
+ it 'should look in the scope' do
75
+ @session.within "//p[@id='first']" do
76
+ expect(@session).to have_css('a#foo')
77
+ expect(@session).not_to have_css('a#red')
78
+ end
79
+ end
80
+
81
+ it 'should be able to generate an error message if the scope is a sibling' do
82
+ el = @session.find(:css, '#first')
83
+ @session.within el.sibling(:css, '#second') do
84
+ expect do
85
+ expect(@session).to have_css('a#not_on_page')
86
+ end.to raise_error(/there were no matches/)
87
+ end
88
+ end
89
+
90
+ it 'should be able to generate an error message if the scope is a sibling from XPath' do
91
+ el = @session.find(:css, '#first').find(:xpath, './following-sibling::*[1]') do
92
+ expect do
93
+ expect(el).to have_css('a#not_on_page')
94
+ end.to raise_error(/there were no matches/)
95
+ end
96
+ end
97
+ end
98
+
99
+ it 'should wait for content to appear', requires: [:js] do
100
+ Capybara.default_max_wait_time = 2
101
+ @session.visit('/with_js')
102
+ @session.click_link('Click me')
103
+ expect(@session).to have_css("input[type='submit'][value='New Here']")
104
+ end
105
+
106
+ context 'with predicates_wait == true' do
107
+ it 'should wait for content to appear', requires: [:js] do
108
+ Capybara.predicates_wait = true
109
+ Capybara.default_max_wait_time = 2
110
+ @session.visit('/with_js')
111
+ @session.click_link('Click me')
112
+ expect(@session.has_css?("input[type='submit'][value='New Here']")).to be true
113
+ end
114
+ end
115
+
116
+ context 'with predicates_wait == false' do
117
+ before do
118
+ Capybara.predicates_wait = false
119
+ Capybara.default_max_wait_time = 5
120
+ @session.visit('/with_js')
121
+ @session.click_link('Click me')
122
+ end
123
+
124
+ it 'should not wait for content to appear', requires: [:js] do
125
+ expect(@session.has_css?("input[type='submit'][value='New Here']")).to be false
126
+ end
127
+
128
+ it 'should should the default wait time if true is passed for :wait', requires: [:js] do
129
+ expect(@session.has_css?("input[type='submit'][value='New Here']", wait: true)).to be true
130
+ end
131
+ end
132
+
133
+ context 'with between' do
134
+ it 'should be true if the content occurs within the range given' do
135
+ expect(@session).to have_css('p', between: 1..4)
136
+ expect(@session).to have_css('p a#foo', between: 1..3)
137
+ expect(@session).to have_css('p a.doesnotexist', between: 0..8)
138
+ end
139
+
140
+ it 'should be false if the content occurs more or fewer times than range' do
141
+ expect(@session).not_to have_css('p', between: 6..11)
142
+ expect(@session).not_to have_css('p a#foo', between: 4..7)
143
+ expect(@session).not_to have_css('p a.doesnotexist', between: 3..8)
144
+ end
145
+ end
146
+
147
+ context 'with count' do
148
+ it 'should be true if the content occurs the given number of times' do
149
+ expect(@session).to have_css('p', count: 3)
150
+ expect(@session).to have_css('p').exactly(3).times
151
+ expect(@session).to have_css('p a#foo', count: 1)
152
+ expect(@session).to have_css('p a#foo').once
153
+ expect(@session).to have_css('p a.doesnotexist', count: 0)
154
+ expect(@session).to have_css('li', class: /guitar|drummer/, count: 4)
155
+ expect(@session).to have_css('li', id: /john|paul/, class: /guitar|drummer/, count: 2)
156
+ expect(@session).to have_css('li', class: %w[beatle guitarist], count: 2)
157
+ expect(@session).to have_css('p', style: 'line-height: 25px;', count: 1)
158
+ expect(@session).to have_css('p', style: /-height: 2/, count: 1)
159
+ end
160
+
161
+ it 'should be true if the content occurs the given number of times in CSS processing drivers', requires: [:css] do
162
+ expect(@session).to have_css('p', style: { 'line-height': '25px' }, count: 1)
163
+ end
164
+
165
+ it 'should be false if the content occurs a different number of times than the given' do
166
+ expect(@session).not_to have_css('p', count: 6)
167
+ expect(@session).not_to have_css('p').exactly(5).times
168
+ expect(@session).not_to have_css('p a#foo', count: 2)
169
+ expect(@session).not_to have_css('p a.doesnotexist', count: 1)
170
+ end
171
+
172
+ it 'should coerce count to an integer' do
173
+ expect(@session).to have_css('p', count: '3')
174
+ expect(@session).to have_css('p a#foo', count: '1')
175
+ end
176
+ end
177
+
178
+ context 'with maximum' do
179
+ it 'should be true when content occurs same or fewer times than given' do
180
+ expect(@session).to have_css('h2.head', maximum: 5) # edge case
181
+ expect(@session).to have_css('h2', maximum: 10)
182
+ expect(@session).to have_css('h2').at_most(10).times
183
+ expect(@session).to have_css('p a.doesnotexist', maximum: 1)
184
+ expect(@session).to have_css('p a.doesnotexist', maximum: 0)
185
+ end
186
+
187
+ it 'should be false when content occurs more times than given' do
188
+ # expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
189
+ # expect(@session).not_to have_css('h2', maximum: 3)
190
+ expect(@session).not_to have_css('h2').at_most(3).times
191
+ # expect(@session).not_to have_css('p', maximum: 1)
192
+ end
193
+
194
+ it 'should coerce maximum to an integer' do
195
+ expect(@session).to have_css('h2.head', maximum: '5') # edge case
196
+ expect(@session).to have_css('h2', maximum: '10')
197
+ end
198
+ end
199
+
200
+ context 'with minimum' do
201
+ it 'should be true when content occurs same or more times than given' do
202
+ expect(@session).to have_css('h2.head', minimum: 5) # edge case
203
+ expect(@session).to have_css('h2', minimum: 3)
204
+ expect(@session).to have_css('h2').at_least(2).times
205
+ expect(@session).to have_css('p a.doesnotexist', minimum: 0)
206
+ end
207
+
208
+ it 'should be false when content occurs fewer times than given' do
209
+ expect(@session).not_to have_css('h2.head', minimum: 6) # edge case
210
+ expect(@session).not_to have_css('h2', minimum: 8)
211
+ expect(@session).not_to have_css('h2').at_least(8).times
212
+ expect(@session).not_to have_css('p', minimum: 10)
213
+ expect(@session).not_to have_css('p a.doesnotexist', minimum: 1)
214
+ end
215
+
216
+ it 'should coerce minimum to an integer' do
217
+ expect(@session).to have_css('h2.head', minimum: '5') # edge case
218
+ expect(@session).to have_css('h2', minimum: '3')
219
+ end
220
+ end
221
+
222
+ context 'with text' do
223
+ it 'should discard all matches where the given string is not contained' do
224
+ expect(@session).to have_css('p a', text: 'Redirect', count: 1)
225
+ expect(@session).not_to have_css('p a', text: 'Doesnotexist')
226
+ end
227
+
228
+ it 'should discard all matches where the given regexp is not matched' do
229
+ expect(@session).to have_css('p a', text: /re[dab]i/i, count: 1)
230
+ expect(@session).not_to have_css('p a', text: /Red$/)
231
+ end
232
+ end
233
+
234
+ context 'with spatial requirements', requires: [:spatial] do
235
+ before do
236
+ @session.visit('/spatial')
237
+ end
238
+
239
+ let :center do
240
+ @session.find(:css, '.center')
241
+ end
242
+
243
+ it 'accepts spatial options' do
244
+ expect(@session).to have_css('div', above: center).thrice
245
+ expect(@session).to have_css('div', above: center, right_of: center).once
246
+ end
247
+
248
+ it 'supports spatial sugar' do
249
+ expect(@session).to have_css('div').left_of(center).thrice
250
+ expect(@session).to have_css('div').below(center).right_of(center).once
251
+ expect(@session).to have_css('div').near(center).exactly(8).times
252
+ end
253
+ end
254
+
255
+ it 'should allow escapes in the CSS selector' do
256
+ expect(@session).to have_css('p[data-random="abc\\\\def"]')
257
+ expect(@session).to have_css("p[data-random='#{Capybara::Selector::CSS.escape('abc\def')}']")
258
+ end
259
+ end
260
+
261
+ Capybara::SpecHelper.spec '#has_no_css?' do
262
+ before do
263
+ @session.visit('/with_html')
264
+ end
265
+
266
+ it 'should be false if the given selector is on the page' do
267
+ expect(@session).not_to have_no_css('p')
268
+ expect(@session).not_to have_no_css('p a#foo')
269
+ end
270
+
271
+ it 'should be true if the given selector is not on the page' do
272
+ expect(@session).to have_no_css('abbr')
273
+ expect(@session).to have_no_css('p a#doesnotexist')
274
+ expect(@session).to have_no_css('p.nosuchclass')
275
+ end
276
+
277
+ it 'should respect scopes' do
278
+ @session.within "//p[@id='first']" do
279
+ expect(@session).not_to have_no_css('a#foo')
280
+ expect(@session).to have_no_css('a#red')
281
+ end
282
+ end
283
+
284
+ it 'should wait for content to disappear', requires: [:js] do
285
+ Capybara.default_max_wait_time = 2
286
+ @session.visit('/with_js')
287
+ @session.click_link('Click me')
288
+ expect(@session).to have_no_css('p#change')
289
+ end
290
+
291
+ context 'with between' do
292
+ it 'should be false if the content occurs within the range given' do
293
+ expect(@session).not_to have_no_css('p', between: 1..4)
294
+ expect(@session).not_to have_no_css('p a#foo', between: 1..3)
295
+ expect(@session).not_to have_no_css('p a.doesnotexist', between: 0..2)
296
+ end
297
+
298
+ it 'should be true if the content occurs more or fewer times than range' do
299
+ expect(@session).to have_no_css('p', between: 6..11)
300
+ expect(@session).to have_no_css('p a#foo', between: 4..7)
301
+ expect(@session).to have_no_css('p a.doesnotexist', between: 3..8)
302
+ end
303
+ end
304
+
305
+ context 'with count' do
306
+ it 'should be false if the content is on the page the given number of times' do
307
+ expect(@session).not_to have_no_css('p', count: 3)
308
+ expect(@session).not_to have_no_css('p a#foo', count: 1)
309
+ expect(@session).not_to have_no_css('p a.doesnotexist', count: 0)
310
+ end
311
+
312
+ it 'should be true if the content is on the page the given number of times' do
313
+ expect(@session).to have_no_css('p', count: 6)
314
+ expect(@session).to have_no_css('p a#foo', count: 2)
315
+ expect(@session).to have_no_css('p a.doesnotexist', count: 1)
316
+ end
317
+
318
+ it 'should coerce count to an integer' do
319
+ expect(@session).not_to have_no_css('p', count: '3')
320
+ expect(@session).not_to have_no_css('p a#foo', count: '1')
321
+ end
322
+ end
323
+
324
+ context 'with maximum' do
325
+ it 'should be false when content occurs same or fewer times than given' do
326
+ expect(@session).not_to have_no_css('h2.head', maximum: 5) # edge case
327
+ expect(@session).not_to have_no_css('h2', maximum: 10)
328
+ expect(@session).not_to have_no_css('p a.doesnotexist', maximum: 0)
329
+ end
330
+
331
+ it 'should be true when content occurs more times than given' do
332
+ expect(@session).to have_no_css('h2.head', maximum: 4) # edge case
333
+ expect(@session).to have_no_css('h2', maximum: 3)
334
+ expect(@session).to have_no_css('p', maximum: 1)
335
+ end
336
+
337
+ it 'should coerce maximum to an integer' do
338
+ expect(@session).not_to have_no_css('h2.head', maximum: '5') # edge case
339
+ expect(@session).not_to have_no_css('h2', maximum: '10')
340
+ end
341
+ end
342
+
343
+ context 'with minimum' do
344
+ it 'should be false when content occurs same or more times than given' do
345
+ expect(@session).not_to have_no_css('h2.head', minimum: 5) # edge case
346
+ expect(@session).not_to have_no_css('h2', minimum: 3)
347
+ expect(@session).not_to have_no_css('p a.doesnotexist', minimum: 0)
348
+ end
349
+
350
+ it 'should be true when content occurs fewer times than given' do
351
+ expect(@session).to have_no_css('h2.head', minimum: 6) # edge case
352
+ expect(@session).to have_no_css('h2', minimum: 8)
353
+ expect(@session).to have_no_css('p', minimum: 15)
354
+ expect(@session).to have_no_css('p a.doesnotexist', minimum: 1)
355
+ end
356
+
357
+ it 'should coerce minimum to an integer' do
358
+ expect(@session).not_to have_no_css('h2.head', minimum: '4') # edge case
359
+ expect(@session).not_to have_no_css('h2', minimum: '3')
360
+ end
361
+ end
362
+
363
+ context 'with text' do
364
+ it 'should discard all matches where the given string is not contained' do
365
+ expect(@session).not_to have_no_css('p a', text: 'Redirect', count: 1)
366
+ expect(@session).to have_no_css('p a', text: 'Doesnotexist')
367
+ end
368
+
369
+ it 'should discard all matches where the given regexp is not matched' do
370
+ expect(@session).not_to have_no_css('p a', text: /re[dab]i/i, count: 1)
371
+ expect(@session).to have_no_css('p a', text: /Red$/)
372
+ end
373
+ end
374
+ end