capybara 2.18.0 → 3.40.0

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/History.md +945 -12
  4. data/License.txt +1 -1
  5. data/README.md +264 -90
  6. data/lib/capybara/config.rb +29 -57
  7. data/lib/capybara/cucumber.rb +2 -3
  8. data/lib/capybara/driver/base.rb +35 -18
  9. data/lib/capybara/driver/node.rb +40 -10
  10. data/lib/capybara/dsl.rb +10 -7
  11. data/lib/capybara/helpers.rb +70 -31
  12. data/lib/capybara/minitest/spec.rb +185 -83
  13. data/lib/capybara/minitest.rb +232 -112
  14. data/lib/capybara/node/actions.rb +274 -171
  15. data/lib/capybara/node/base.rb +42 -34
  16. data/lib/capybara/node/document.rb +15 -3
  17. data/lib/capybara/node/document_matchers.rb +19 -21
  18. data/lib/capybara/node/element.rb +362 -135
  19. data/lib/capybara/node/finders.rb +151 -137
  20. data/lib/capybara/node/matchers.rb +394 -209
  21. data/lib/capybara/node/simple.rb +59 -26
  22. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  23. data/lib/capybara/queries/active_element_query.rb +18 -0
  24. data/lib/capybara/queries/ancestor_query.rb +12 -9
  25. data/lib/capybara/queries/base_query.rb +39 -28
  26. data/lib/capybara/queries/current_path_query.rb +21 -27
  27. data/lib/capybara/queries/match_query.rb +14 -7
  28. data/lib/capybara/queries/selector_query.rb +659 -149
  29. data/lib/capybara/queries/sibling_query.rb +11 -9
  30. data/lib/capybara/queries/style_query.rb +45 -0
  31. data/lib/capybara/queries/text_query.rb +56 -38
  32. data/lib/capybara/queries/title_query.rb +8 -11
  33. data/lib/capybara/rack_test/browser.rb +114 -42
  34. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  35. data/lib/capybara/rack_test/driver.rb +22 -17
  36. data/lib/capybara/rack_test/errors.rb +6 -0
  37. data/lib/capybara/rack_test/form.rb +93 -58
  38. data/lib/capybara/rack_test/node.rb +184 -81
  39. data/lib/capybara/rails.rb +3 -7
  40. data/lib/capybara/registration_container.rb +41 -0
  41. data/lib/capybara/registrations/drivers.rb +42 -0
  42. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  43. data/lib/capybara/registrations/servers.rb +66 -0
  44. data/lib/capybara/result.rb +97 -63
  45. data/lib/capybara/rspec/features.rb +17 -50
  46. data/lib/capybara/rspec/matcher_proxies.rb +52 -15
  47. data/lib/capybara/rspec/matchers/base.rb +113 -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 +69 -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 +43 -0
  59. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  60. data/lib/capybara/rspec/matchers.rb +146 -310
  61. data/lib/capybara/rspec.rb +7 -11
  62. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  63. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  64. data/lib/capybara/selector/css.rb +85 -13
  65. data/lib/capybara/selector/definition/button.rb +68 -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 +28 -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 +55 -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/definition.rb +280 -0
  87. data/lib/capybara/selector/filter.rb +2 -17
  88. data/lib/capybara/selector/filter_set.rb +80 -33
  89. data/lib/capybara/selector/filters/base.rb +50 -6
  90. data/lib/capybara/selector/filters/expression_filter.rb +8 -26
  91. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  92. data/lib/capybara/selector/filters/node_filter.rb +16 -12
  93. data/lib/capybara/selector/regexp_disassembler.rb +211 -0
  94. data/lib/capybara/selector/selector.rb +93 -210
  95. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  96. data/lib/capybara/selector.rb +475 -523
  97. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  98. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  99. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  100. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  101. data/lib/capybara/selenium/driver.rb +298 -267
  102. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
  103. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  104. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
  105. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  106. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  107. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  108. data/lib/capybara/selenium/extensions/find.rb +110 -0
  109. data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
  110. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  111. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  112. data/lib/capybara/selenium/node.rb +517 -145
  113. data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
  114. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  115. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
  116. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  117. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  118. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  119. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  120. data/lib/capybara/selenium/patches/logs.rb +45 -0
  121. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  122. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  123. data/lib/capybara/server/animation_disabler.rb +80 -0
  124. data/lib/capybara/server/checker.rb +44 -0
  125. data/lib/capybara/server/middleware.rb +71 -0
  126. data/lib/capybara/server.rb +59 -67
  127. data/lib/capybara/session/config.rb +81 -67
  128. data/lib/capybara/session/matchers.rb +28 -20
  129. data/lib/capybara/session.rb +337 -365
  130. data/lib/capybara/spec/public/jquery.js +5 -5
  131. data/lib/capybara/spec/public/offset.js +6 -0
  132. data/lib/capybara/spec/public/test.js +151 -12
  133. data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
  134. data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
  135. data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
  136. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  137. data/lib/capybara/spec/session/all_spec.rb +161 -57
  138. data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
  140. data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
  141. data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
  142. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  143. data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
  144. data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +22 -12
  145. data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
  146. data/lib/capybara/spec/session/body_spec.rb +12 -13
  147. data/lib/capybara/spec/session/check_spec.rb +117 -55
  148. data/lib/capybara/spec/session/choose_spec.rb +64 -31
  149. data/lib/capybara/spec/session/click_button_spec.rb +231 -173
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
  151. data/lib/capybara/spec/session/click_link_spec.rb +93 -58
  152. data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
  153. data/lib/capybara/spec/session/current_url_spec.rb +57 -39
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
  162. data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
  163. data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
  164. data/lib/capybara/spec/session/find_button_spec.rb +25 -24
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
  166. data/lib/capybara/spec/session/find_field_spec.rb +37 -41
  167. data/lib/capybara/spec/session/find_link_spec.rb +46 -17
  168. data/lib/capybara/spec/session/find_spec.rb +260 -145
  169. data/lib/capybara/spec/session/first_spec.rb +80 -52
  170. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  171. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  172. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +33 -20
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
  174. data/lib/capybara/spec/session/go_back_spec.rb +2 -1
  175. data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +31 -31
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +100 -13
  180. data/lib/capybara/spec/session/has_css_spec.rb +272 -137
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
  182. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  183. data/lib/capybara/spec/session/has_field_spec.rb +139 -59
  184. data/lib/capybara/spec/session/has_link_spec.rb +47 -6
  185. data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
  186. data/lib/capybara/spec/session/has_select_spec.rb +107 -72
  187. data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
  188. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  189. data/lib/capybara/spec/session/has_table_spec.rb +183 -5
  190. data/lib/capybara/spec/session/has_text_spec.rb +106 -62
  191. data/lib/capybara/spec/session/has_title_spec.rb +20 -14
  192. data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
  193. data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
  194. data/lib/capybara/spec/session/html_spec.rb +14 -6
  195. data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
  196. data/lib/capybara/spec/session/node_spec.rb +1024 -153
  197. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  198. data/lib/capybara/spec/session/refresh_spec.rb +12 -6
  199. data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
  200. data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
  201. data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
  202. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
  203. data/lib/capybara/spec/session/save_page_spec.rb +42 -55
  204. data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
  205. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  206. data/lib/capybara/spec/session/scroll_spec.rb +119 -0
  207. data/lib/capybara/spec/session/select_spec.rb +107 -81
  208. data/lib/capybara/spec/session/selectors_spec.rb +52 -19
  209. data/lib/capybara/spec/session/sibling_spec.rb +10 -10
  210. data/lib/capybara/spec/session/text_spec.rb +37 -21
  211. data/lib/capybara/spec/session/title_spec.rb +17 -5
  212. data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
  213. data/lib/capybara/spec/session/unselect_spec.rb +39 -38
  214. data/lib/capybara/spec/session/visit_spec.rb +85 -53
  215. data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
  216. data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
  217. data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
  218. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
  219. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
  220. data/lib/capybara/spec/session/window/window_spec.rb +97 -63
  221. data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
  222. data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
  223. data/lib/capybara/spec/session/within_spec.rb +83 -44
  224. data/lib/capybara/spec/spec_helper.rb +54 -44
  225. data/lib/capybara/spec/test_app.rb +158 -43
  226. data/lib/capybara/spec/views/animated.erb +49 -0
  227. data/lib/capybara/spec/views/form.erb +163 -42
  228. data/lib/capybara/spec/views/frame_child.erb +4 -3
  229. data/lib/capybara/spec/views/frame_one.erb +2 -1
  230. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  231. data/lib/capybara/spec/views/frame_two.erb +1 -1
  232. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  233. data/lib/capybara/spec/views/layout.erb +10 -0
  234. data/lib/capybara/spec/views/obscured.erb +47 -0
  235. data/lib/capybara/spec/views/offset.erb +33 -0
  236. data/lib/capybara/spec/views/path.erb +2 -2
  237. data/lib/capybara/spec/views/popup_one.erb +1 -1
  238. data/lib/capybara/spec/views/popup_two.erb +1 -1
  239. data/lib/capybara/spec/views/react.erb +45 -0
  240. data/lib/capybara/spec/views/scroll.erb +21 -0
  241. data/lib/capybara/spec/views/spatial.erb +31 -0
  242. data/lib/capybara/spec/views/tables.erb +68 -1
  243. data/lib/capybara/spec/views/with_animation.erb +81 -0
  244. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  245. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  246. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  247. data/lib/capybara/spec/views/with_hover.erb +3 -2
  248. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  249. data/lib/capybara/spec/views/with_html.erb +69 -12
  250. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  251. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  252. data/lib/capybara/spec/views/with_js.erb +30 -5
  253. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  254. data/lib/capybara/spec/views/with_namespace.erb +21 -0
  255. data/lib/capybara/spec/views/with_scope.erb +2 -2
  256. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  257. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  258. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  259. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  260. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  261. data/lib/capybara/spec/views/with_windows.erb +1 -1
  262. data/lib/capybara/spec/views/within_frames.erb +5 -2
  263. data/lib/capybara/version.rb +2 -1
  264. data/lib/capybara/window.rb +36 -34
  265. data/lib/capybara.rb +134 -107
  266. data/spec/basic_node_spec.rb +60 -34
  267. data/spec/capybara_spec.rb +63 -88
  268. data/spec/counter_spec.rb +35 -0
  269. data/spec/css_builder_spec.rb +101 -0
  270. data/spec/css_splitter_spec.rb +38 -0
  271. data/spec/dsl_spec.rb +85 -64
  272. data/spec/filter_set_spec.rb +27 -9
  273. data/spec/fixtures/certificate.pem +25 -0
  274. data/spec/fixtures/key.pem +27 -0
  275. data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
  276. data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
  277. data/spec/minitest_spec.rb +52 -7
  278. data/spec/minitest_spec_spec.rb +94 -63
  279. data/spec/per_session_config_spec.rb +14 -13
  280. data/spec/rack_test_spec.rb +194 -125
  281. data/spec/regexp_dissassembler_spec.rb +250 -0
  282. data/spec/result_spec.rb +111 -50
  283. data/spec/rspec/features_spec.rb +37 -31
  284. data/spec/rspec/scenarios_spec.rb +10 -8
  285. data/spec/rspec/shared_spec_matchers.rb +473 -422
  286. data/spec/rspec/views_spec.rb +5 -3
  287. data/spec/rspec_matchers_spec.rb +52 -11
  288. data/spec/rspec_spec.rb +109 -89
  289. data/spec/sauce_spec_chrome.rb +43 -0
  290. data/spec/selector_spec.rb +397 -68
  291. data/spec/selenium_spec_chrome.rb +187 -40
  292. data/spec/selenium_spec_chrome_remote.rb +96 -0
  293. data/spec/selenium_spec_edge.rb +60 -0
  294. data/spec/selenium_spec_firefox.rb +201 -41
  295. data/spec/selenium_spec_firefox_remote.rb +94 -0
  296. data/spec/selenium_spec_ie.rb +149 -0
  297. data/spec/selenium_spec_safari.rb +162 -0
  298. data/spec/server_spec.rb +213 -102
  299. data/spec/session_spec.rb +53 -16
  300. data/spec/shared_selenium_node.rb +79 -0
  301. data/spec/shared_selenium_session.rb +473 -122
  302. data/spec/spec_helper.rb +126 -7
  303. data/spec/whitespace_normalizer_spec.rb +54 -0
  304. data/spec/xpath_builder_spec.rb +93 -0
  305. metadata +355 -73
  306. data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
  307. data/.yard/templates_custom/default/class/html/setup.rb +0 -17
  308. data/.yard/yard_extensions.rb +0 -78
  309. data/lib/capybara/query.rb +0 -7
  310. data/lib/capybara/rspec/compound.rb +0 -95
  311. data/lib/capybara/spec/session/assert_current_path.rb +0 -72
  312. data/lib/capybara/spec/session/assert_selector.rb +0 -148
  313. data/lib/capybara/spec/session/assert_text.rb +0 -234
  314. data/lib/capybara/spec/session/source_spec.rb +0 -0
  315. data/lib/capybara/spec/views/with_title.erb +0 -5
  316. data/spec/selenium_spec_marionette.rb +0 -127
@@ -1,44 +1,59 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_text?' do
3
- it "should be true if the given text is on the page at least once" do
4
+ it 'should be true if the given text is on the page at least once' do
4
5
  @session.visit('/with_html')
5
6
  expect(@session).to have_text('est')
6
7
  expect(@session).to have_text('Lorem')
7
8
  expect(@session).to have_text('Redirect')
8
- expect(@session).to have_text(:'Redirect')
9
+ expect(@session).to have_text(:Redirect)
9
10
  end
10
11
 
11
- it "should be true if scoped to an element which has the text" do
12
+ it 'should be true if scoped to an element which has the text' do
12
13
  @session.visit('/with_html')
13
14
  @session.within("//a[@title='awesome title']") do
14
15
  expect(@session).to have_text('labore')
15
16
  end
16
17
  end
17
18
 
18
- it "should be false if scoped to an element which does not have the text" do
19
+ it 'should be false if scoped to an element which does not have the text' do
19
20
  @session.visit('/with_html')
20
21
  @session.within("//a[@title='awesome title']") do
21
22
  expect(@session).not_to have_text('monkey')
22
23
  end
23
24
  end
24
25
 
25
- it "should ignore tags" do
26
+ it 'should ignore tags' do
26
27
  @session.visit('/with_html')
27
28
  expect(@session).not_to have_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
28
29
  expect(@session).to have_text('exercitation ullamco laboris')
29
30
  end
30
31
 
31
- it "should ignore extra whitespace and newlines" do
32
+ it 'should search correctly normalized text' do
32
33
  @session.visit('/with_html')
33
- expect(@session).to have_text('text with whitespace')
34
+ expect(@session).to have_text('text with whitespace')
34
35
  end
35
36
 
36
- it "should ignore whitespace and newlines in the search string" do
37
+ it 'should search whitespace collapsed text' do
37
38
  @session.visit('/with_html')
38
- expect(@session).to have_text("text with \n\n whitespace")
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
39
54
  end
40
55
 
41
- it "should be false if the given text is not on the page" do
56
+ it 'should be false if the given text is not on the page' do
42
57
  @session.visit('/with_html')
43
58
  expect(@session).not_to have_text('xxxxyzzz')
44
59
  expect(@session).not_to have_text('monkey')
@@ -51,12 +66,12 @@ Capybara::SpecHelper.spec '#has_text?' do
51
66
 
52
67
  it 'should handle double quotes in the text' do
53
68
  @session.visit('/with-quotes')
54
- expect(@session).to have_text(%q{"No," he said})
69
+ expect(@session).to have_text('"No," he said')
55
70
  end
56
71
 
57
72
  it 'should handle mixed single and double quotes in the text' do
58
73
  @session.visit('/with-quotes')
59
- expect(@session).to have_text(%q{"you can't do that."})
74
+ expect(@session).to have_text(%q("you can't do that."))
60
75
  end
61
76
 
62
77
  it 'should be false if text is in the title tag in the head' do
@@ -70,23 +85,23 @@ Capybara::SpecHelper.spec '#has_text?' do
70
85
  expect(@session).not_to have_text('aVar')
71
86
  end
72
87
 
73
- it "should be false if the given text is on the page but not visible" do
88
+ it 'should be false if the given text is on the page but not visible' do
74
89
  @session.visit('/with_html')
75
90
  expect(@session).not_to have_text('Inside element with hidden ancestor')
76
91
  end
77
92
 
78
- it "should be true if :all given and text is invisible." do
93
+ it 'should be true if :all given and text is invisible.' do
79
94
  @session.visit('/with_html')
80
95
  expect(@session).to have_text(:all, 'Some of this text is hidden!')
81
96
  end
82
97
 
83
- it "should be true if `Capybara.ignore_hidden_elements = false` and text is invisible." do
98
+ it 'should be true if `Capybara.ignore_hidden_elements = false` and text is invisible.' do
84
99
  Capybara.ignore_hidden_elements = false
85
100
  @session.visit('/with_html')
86
101
  expect(@session).to have_text('Some of this text is hidden!')
87
102
  end
88
103
 
89
- it "should be true if the text in the page matches given regexp" do
104
+ it 'should be true if the text in the page matches given regexp' do
90
105
  @session.visit('/with_html')
91
106
  expect(@session).to have_text(/Lorem/)
92
107
  end
@@ -96,50 +111,72 @@ Capybara::SpecHelper.spec '#has_text?' do
96
111
  expect(@session).not_to have_text(/xxxxyzzz/)
97
112
  end
98
113
 
99
- context "with exact: true option" do
100
- it "should be true if text matches exactly" do
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
101
120
  @session.visit('/with_html')
102
- expect(@session.find(:id, "h2one")).to have_text("Header Class Test One", exact: true)
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
+ expect(@session).to have_text(:visible, with_to_hash, **{})
131
+ end
132
+ end
133
+
134
+ context 'with exact: true option' do
135
+ it 'should be true if text matches exactly' do
136
+ @session.visit('/with_html')
137
+ expect(@session.find(:id, 'h2one')).to have_text('Header Class Test One', exact: true)
103
138
  end
104
139
 
105
140
  it "should be false if text doesn't match exactly" do
106
141
  @session.visit('/with_html')
107
- expect(@session.find(:id, "h2one")).not_to have_text("Header Class Test On", exact: true)
142
+ expect(@session.find(:id, 'h2one')).not_to have_text('Header Class Test On', exact: true)
108
143
  end
109
144
  end
110
145
 
111
- it "should escape any characters that would have special meaning in a regexp" do
146
+ it 'should escape any characters that would have special meaning in a regexp' do
112
147
  @session.visit('/with_html')
113
148
  expect(@session).not_to have_text('.orem')
114
149
  end
115
150
 
116
- it "should accept non-string parameters" do
151
+ it 'should accept non-string parameters' do
117
152
  @session.visit('/with_html')
118
153
  expect(@session).to have_text(42)
119
154
  end
120
155
 
121
- it "should be true when passed nil" do
156
+ it 'should be true when passed nil, and warn about it' do
122
157
  # nil is converted to '' when to_s is invoked
123
158
  @session.visit('/with_html')
124
- expect(@session).to have_text(nil)
159
+ expect do
160
+ expect(@session).to have_text(nil)
161
+ end.to output(/Checking for expected text of nil is confusing/).to_stderr
125
162
  end
126
163
 
127
- it "should wait for text to appear", requires: [:js] do
164
+ it 'should wait for text to appear', requires: [:js] do
128
165
  Capybara.using_wait_time(3) do
129
166
  @session.visit('/with_js')
130
167
  @session.click_link('Click me')
131
- expect(@session).to have_text("Has been clicked")
168
+ expect(@session).to have_text('Has been clicked')
132
169
  end
133
170
  end
134
171
 
135
- context "with between" do
136
- it "should be true if the text occurs within the range given" do
172
+ context 'with between' do
173
+ it 'should be true if the text occurs within the range given' do
137
174
  @session.visit('/with_count')
138
175
  expect(@session).to have_text('count', between: 1..3)
139
176
  expect(@session).to have_text(/count/, between: 2..2)
140
177
  end
141
178
 
142
- it "should be false if the text occurs more or fewer times than range" do
179
+ it 'should be false if the text occurs more or fewer times than range' do
143
180
  @session.visit('/with_count')
144
181
  expect(@session).not_to have_text('count', between: 0..1)
145
182
  expect(@session).not_to have_text('count', between: 3..10)
@@ -147,76 +184,82 @@ Capybara::SpecHelper.spec '#has_text?' do
147
184
  end
148
185
  end
149
186
 
150
- context "with count" do
151
- it "should be true if the text occurs the given number of times" do
187
+ context 'with count' do
188
+ it 'should be true if the text occurs the given number of times' do
152
189
  @session.visit('/with_count')
153
190
  expect(@session).to have_text('count', count: 2)
191
+ expect(@session).to have_text('count').exactly(2).times
154
192
  end
155
193
 
156
- it "should be false if the text occurs a different number of times than the given" do
194
+ it 'should be false if the text occurs a different number of times than the given' do
157
195
  @session.visit('/with_count')
158
196
  expect(@session).not_to have_text('count', count: 0)
159
197
  expect(@session).not_to have_text('count', count: 1)
198
+ expect(@session).not_to have_text('count').once
160
199
  expect(@session).not_to have_text(/count/, count: 3)
161
200
  end
162
201
 
163
- it "should coerce count to an integer" do
202
+ it 'should coerce count to an integer' do
164
203
  @session.visit('/with_count')
165
204
  expect(@session).to have_text('count', count: '2')
166
205
  expect(@session).not_to have_text('count', count: '3')
167
206
  end
168
207
  end
169
208
 
170
- context "with maximum" do
171
- it "should be true when text occurs same or fewer times than given" do
209
+ context 'with maximum' do
210
+ it 'should be true when text occurs same or fewer times than given' do
172
211
  @session.visit('/with_count')
173
212
  expect(@session).to have_text('count', maximum: 2)
213
+ expect(@session).to have_text('count').at_most(2).times
174
214
  expect(@session).to have_text(/count/, maximum: 3)
175
215
  end
176
216
 
177
- it "should be false when text occurs more times than given" do
217
+ it 'should be false when text occurs more times than given' do
178
218
  @session.visit('/with_count')
179
219
  expect(@session).not_to have_text('count', maximum: 1)
220
+ expect(@session).not_to have_text('count').at_most(1).times
180
221
  expect(@session).not_to have_text('count', maximum: 0)
181
222
  end
182
223
 
183
- it "should coerce maximum to an integer" do
224
+ it 'should coerce maximum to an integer' do
184
225
  @session.visit('/with_count')
185
226
  expect(@session).to have_text('count', maximum: '2')
186
227
  expect(@session).not_to have_text('count', maximum: '1')
187
228
  end
188
229
  end
189
230
 
190
- context "with minimum" do
191
- it "should be true when text occurs same or more times than given" do
231
+ context 'with minimum' do
232
+ it 'should be true when text occurs same or more times than given' do
192
233
  @session.visit('/with_count')
193
234
  expect(@session).to have_text('count', minimum: 2)
235
+ expect(@session).to have_text('count').at_least(2).times
194
236
  expect(@session).to have_text(/count/, minimum: 0)
195
237
  end
196
238
 
197
- it "should be false when text occurs fewer times than given" do
239
+ it 'should be false when text occurs fewer times than given' do
198
240
  @session.visit('/with_count')
199
241
  expect(@session).not_to have_text('count', minimum: 3)
242
+ expect(@session).not_to have_text('count').at_least(3).times
200
243
  end
201
244
 
202
- it "should coerce minimum to an integer" do
245
+ it 'should coerce minimum to an integer' do
203
246
  @session.visit('/with_count')
204
247
  expect(@session).to have_text('count', minimum: '2')
205
248
  expect(@session).not_to have_text('count', minimum: '3')
206
249
  end
207
250
  end
208
251
 
209
- context "with wait", requires: [:js] do
210
- it "should find element if it appears before given wait duration" do
252
+ context 'with wait', requires: [:js] do
253
+ it 'should find element if it appears before given wait duration' do
211
254
  Capybara.using_wait_time(0.1) do
212
255
  @session.visit('/with_js')
213
256
  @session.click_link('Click me')
214
- expect(@session).to have_text('Has been clicked', wait: 0.9)
257
+ expect(@session).to have_text('Has been clicked', wait: 3)
215
258
  end
216
259
  end
217
260
  end
218
261
 
219
- it "should raise an error if an invalid option is passed" do
262
+ it 'should raise an error if an invalid option is passed' do
220
263
  @session.visit('/with_html')
221
264
  expect do
222
265
  expect(@session).to have_text('Lorem', invalid: true)
@@ -225,34 +268,34 @@ Capybara::SpecHelper.spec '#has_text?' do
225
268
  end
226
269
 
227
270
  Capybara::SpecHelper.spec '#has_no_text?' do
228
- it "should be false if the given text is on the page at least once" do
271
+ it 'should be false if the given text is on the page at least once' do
229
272
  @session.visit('/with_html')
230
273
  expect(@session).not_to have_no_text('est')
231
274
  expect(@session).not_to have_no_text('Lorem')
232
275
  expect(@session).not_to have_no_text('Redirect')
233
276
  end
234
277
 
235
- it "should be false if scoped to an element which has the text" do
278
+ it 'should be false if scoped to an element which has the text' do
236
279
  @session.visit('/with_html')
237
280
  @session.within("//a[@title='awesome title']") do
238
281
  expect(@session).not_to have_no_text('labore')
239
282
  end
240
283
  end
241
284
 
242
- it "should be true if scoped to an element which does not have the text" do
285
+ it 'should be true if scoped to an element which does not have the text' do
243
286
  @session.visit('/with_html')
244
287
  @session.within("//a[@title='awesome title']") do
245
288
  expect(@session).to have_no_text('monkey')
246
289
  end
247
290
  end
248
291
 
249
- it "should ignore tags" do
292
+ it 'should ignore tags' do
250
293
  @session.visit('/with_html')
251
294
  expect(@session).to have_no_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
252
295
  expect(@session).not_to have_no_text('exercitation ullamco laboris')
253
296
  end
254
297
 
255
- it "should be true if the given text is not on the page" do
298
+ it 'should be true if the given text is not on the page' do
256
299
  @session.visit('/with_html')
257
300
  expect(@session).to have_no_text('xxxxyzzz')
258
301
  expect(@session).to have_no_text('monkey')
@@ -265,12 +308,12 @@ Capybara::SpecHelper.spec '#has_no_text?' do
265
308
 
266
309
  it 'should handle double quotes in the text' do
267
310
  @session.visit('/with-quotes')
268
- expect(@session).not_to have_no_text(%q{"No," he said})
311
+ expect(@session).not_to have_no_text('"No," he said')
269
312
  end
270
313
 
271
314
  it 'should handle mixed single and double quotes in the text' do
272
315
  @session.visit('/with-quotes')
273
- expect(@session).not_to have_no_text(%q{"you can't do that."})
316
+ expect(@session).not_to have_no_text(%q("you can't do that."))
274
317
  end
275
318
 
276
319
  it 'should be true if text is in the title tag in the head' do
@@ -284,17 +327,17 @@ Capybara::SpecHelper.spec '#has_no_text?' do
284
327
  expect(@session).to have_no_text('aVar')
285
328
  end
286
329
 
287
- it "should be true if the given text is on the page but not visible" do
330
+ it 'should be true if the given text is on the page but not visible' do
288
331
  @session.visit('/with_html')
289
332
  expect(@session).to have_no_text('Inside element with hidden ancestor')
290
333
  end
291
334
 
292
- it "should be false if :all given and text is invisible." do
335
+ it 'should be false if :all given and text is invisible.' do
293
336
  @session.visit('/with_html')
294
337
  expect(@session).not_to have_no_text(:all, 'Some of this text is hidden!')
295
338
  end
296
339
 
297
- it "should be false if `Capybara.ignore_hidden_elements = false` and text is invisible." do
340
+ it 'should be false if `Capybara.ignore_hidden_elements = false` and text is invisible.' do
298
341
  Capybara.ignore_hidden_elements = false
299
342
  @session.visit('/with_html')
300
343
  expect(@session).not_to have_no_text('Some of this text is hidden!')
@@ -305,27 +348,28 @@ Capybara::SpecHelper.spec '#has_no_text?' do
305
348
  expect(@session).to have_no_text(/xxxxyzzz/)
306
349
  end
307
350
 
308
- it "should be false if the text in the page matches given regexp" do
351
+ it 'should be false if the text in the page matches given regexp' do
309
352
  @session.visit('/with_html')
310
353
  expect(@session).not_to have_no_text(/Lorem/)
311
354
  end
312
355
 
313
- it "should escape any characters that would have special meaning in a regexp" do
356
+ it 'should escape any characters that would have special meaning in a regexp' do
314
357
  @session.visit('/with_html')
315
358
  expect(@session).to have_no_text('.orem')
316
359
  end
317
360
 
318
- it "should wait for text to disappear", requires: [:js] do
361
+ it 'should wait for text to disappear', requires: [:js] do
362
+ Capybara.default_max_wait_time = 2
319
363
  @session.visit('/with_js')
320
364
  @session.click_link('Click me')
321
- expect(@session).to have_no_text("I changed it")
365
+ expect(@session).to have_no_text('I changed it')
322
366
  end
323
367
 
324
- context "with wait", requires: [:js] do
325
- it "should not find element if it appears after given wait duration" do
368
+ context 'with wait', requires: [:js] do
369
+ it 'should not find element if it appears after given wait duration' do
326
370
  @session.visit('/with_js')
327
371
  @session.click_link('Click me')
328
- expect(@session).to have_no_text('Has been clicked', wait: 0.1)
372
+ expect(@session).to have_no_text('Has been clicked', wait: 0.05)
329
373
  end
330
374
  end
331
375
  end
@@ -1,38 +1,43 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_title?' do
3
4
  before do
4
5
  @session.visit('/with_js')
5
6
  end
6
7
 
7
- it "should be true if the page has the given title" do
8
+ it 'should be true if the page has the given title' do
8
9
  expect(@session).to have_title('with_js')
10
+ expect(@session.has_title?('with_js')).to be true
9
11
  end
10
12
 
11
- it "should allow regexp matches" do
13
+ it 'should allow regexp matches' do
12
14
  expect(@session).to have_title(/w[a-z]{3}_js/)
13
15
  expect(@session).not_to have_title(/monkey/)
14
16
  end
15
17
 
16
- it "should wait for title", requires: [:js] do
17
- @session.click_link("Change title")
18
- expect(@session).to have_title("changed title")
18
+ it 'should wait for title', requires: [:js] do
19
+ @session.click_link('Change title')
20
+ expect(@session).to have_title('changed title')
19
21
  end
20
22
 
21
- it "should be false if the page has not the given title" do
23
+ it 'should be false if the page has not the given title' do
22
24
  expect(@session).not_to have_title('monkey')
25
+ expect(@session.has_title?('monkey')).to be false
23
26
  end
24
27
 
25
- it "should default to exact: false matching" do
28
+ it 'should default to exact: false matching' do
26
29
  expect(@session).to have_title('with_js', exact: false)
27
30
  expect(@session).to have_title('with_', exact: false)
28
31
  end
29
32
 
30
- it "should match exactly if exact: true option passed" do
33
+ it 'should match exactly if exact: true option passed' do
31
34
  expect(@session).to have_title('with_js', exact: true)
32
35
  expect(@session).not_to have_title('with_', exact: true)
36
+ expect(@session.has_title?('with_js', exact: true)).to be true
37
+ expect(@session.has_title?('with_', exact: true)).to be false
33
38
  end
34
39
 
35
- it "should match partial if exact: false option passed" do
40
+ it 'should match partial if exact: false option passed' do
36
41
  expect(@session).to have_title('with_js', exact: false)
37
42
  expect(@session).to have_title('with_', exact: false)
38
43
  end
@@ -43,23 +48,24 @@ Capybara::SpecHelper.spec '#has_no_title?' do
43
48
  @session.visit('/with_js')
44
49
  end
45
50
 
46
- it "should be false if the page has the given title" do
51
+ it 'should be false if the page has the given title' do
47
52
  expect(@session).not_to have_no_title('with_js')
48
53
  end
49
54
 
50
- it "should allow regexp matches" do
55
+ it 'should allow regexp matches' do
51
56
  expect(@session).not_to have_no_title(/w[a-z]{3}_js/)
52
57
  expect(@session).to have_no_title(/monkey/)
53
58
  end
54
59
 
55
- it "should wait for title to disappear", requires: [:js] do
60
+ it 'should wait for title to disappear', requires: [:js] do
56
61
  Capybara.using_wait_time(5) do
57
- @session.click_link("Change title") # triggers title change after 400ms
62
+ @session.click_link('Change title') # triggers title change after 400ms
58
63
  expect(@session).to have_no_title('with_js')
59
64
  end
60
65
  end
61
66
 
62
- it "should be true if the page has not the given title" do
67
+ it 'should be true if the page has not the given title' do
63
68
  expect(@session).to have_no_title('monkey')
69
+ expect(@session.has_no_title?('monkey')).to be true
64
70
  end
65
71
  end