capybara 3.3.0 → 3.40.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +803 -13
  4. data/License.txt +1 -1
  5. data/README.md +257 -84
  6. data/lib/capybara/config.rb +25 -9
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +17 -3
  9. data/lib/capybara/driver/node.rb +31 -6
  10. data/lib/capybara/dsl.rb +9 -7
  11. data/lib/capybara/helpers.rb +31 -7
  12. data/lib/capybara/minitest/spec.rb +180 -88
  13. data/lib/capybara/minitest.rb +262 -149
  14. data/lib/capybara/node/actions.rb +202 -116
  15. data/lib/capybara/node/base.rb +34 -19
  16. data/lib/capybara/node/document.rb +14 -2
  17. data/lib/capybara/node/document_matchers.rb +10 -12
  18. data/lib/capybara/node/element.rb +269 -115
  19. data/lib/capybara/node/finders.rb +99 -77
  20. data/lib/capybara/node/matchers.rb +327 -151
  21. data/lib/capybara/node/simple.rb +48 -13
  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 +8 -9
  25. data/lib/capybara/queries/base_query.rb +23 -16
  26. data/lib/capybara/queries/current_path_query.rb +16 -6
  27. data/lib/capybara/queries/match_query.rb +1 -0
  28. data/lib/capybara/queries/selector_query.rb +587 -130
  29. data/lib/capybara/queries/sibling_query.rb +8 -6
  30. data/lib/capybara/queries/style_query.rb +6 -2
  31. data/lib/capybara/queries/text_query.rb +28 -14
  32. data/lib/capybara/queries/title_query.rb +2 -2
  33. data/lib/capybara/rack_test/browser.rb +92 -25
  34. data/lib/capybara/rack_test/driver.rb +16 -7
  35. data/lib/capybara/rack_test/errors.rb +6 -0
  36. data/lib/capybara/rack_test/form.rb +68 -41
  37. data/lib/capybara/rack_test/node.rb +106 -39
  38. data/lib/capybara/rails.rb +1 -1
  39. data/lib/capybara/registration_container.rb +41 -0
  40. data/lib/capybara/registrations/drivers.rb +42 -0
  41. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  42. data/lib/capybara/registrations/servers.rb +66 -0
  43. data/lib/capybara/result.rb +75 -52
  44. data/lib/capybara/rspec/features.rb +7 -7
  45. data/lib/capybara/rspec/matcher_proxies.rb +39 -18
  46. data/lib/capybara/rspec/matchers/base.rb +113 -0
  47. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  48. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  49. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  50. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  51. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  52. data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
  53. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  54. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  55. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  56. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  57. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  58. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  59. data/lib/capybara/rspec/matchers.rb +141 -339
  60. data/lib/capybara/rspec.rb +2 -0
  61. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  62. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  63. data/lib/capybara/selector/css.rb +27 -25
  64. data/lib/capybara/selector/definition/button.rb +68 -0
  65. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  66. data/lib/capybara/selector/definition/css.rb +10 -0
  67. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  68. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  69. data/lib/capybara/selector/definition/element.rb +28 -0
  70. data/lib/capybara/selector/definition/field.rb +40 -0
  71. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  72. data/lib/capybara/selector/definition/file_field.rb +13 -0
  73. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  74. data/lib/capybara/selector/definition/frame.rb +17 -0
  75. data/lib/capybara/selector/definition/id.rb +6 -0
  76. data/lib/capybara/selector/definition/label.rb +62 -0
  77. data/lib/capybara/selector/definition/link.rb +55 -0
  78. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  79. data/lib/capybara/selector/definition/option.rb +27 -0
  80. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  81. data/lib/capybara/selector/definition/select.rb +81 -0
  82. data/lib/capybara/selector/definition/table.rb +109 -0
  83. data/lib/capybara/selector/definition/table_row.rb +21 -0
  84. data/lib/capybara/selector/definition/xpath.rb +5 -0
  85. data/lib/capybara/selector/definition.rb +280 -0
  86. data/lib/capybara/selector/filter.rb +1 -0
  87. data/lib/capybara/selector/filter_set.rb +73 -25
  88. data/lib/capybara/selector/filters/base.rb +24 -5
  89. data/lib/capybara/selector/filters/expression_filter.rb +3 -3
  90. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  91. data/lib/capybara/selector/filters/node_filter.rb +16 -2
  92. data/lib/capybara/selector/regexp_disassembler.rb +211 -0
  93. data/lib/capybara/selector/selector.rb +85 -348
  94. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  95. data/lib/capybara/selector.rb +474 -447
  96. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  98. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  99. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  100. data/lib/capybara/selenium/driver.rb +255 -143
  101. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +93 -11
  102. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  103. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
  104. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  105. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  106. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  107. data/lib/capybara/selenium/extensions/find.rb +110 -0
  108. data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
  109. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  110. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  111. data/lib/capybara/selenium/node.rb +436 -134
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -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/atoms.rb +18 -0
  118. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  119. data/lib/capybara/selenium/patches/logs.rb +45 -0
  120. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  121. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  122. data/lib/capybara/server/animation_disabler.rb +56 -19
  123. data/lib/capybara/server/checker.rb +9 -3
  124. data/lib/capybara/server/middleware.rb +28 -12
  125. data/lib/capybara/server.rb +33 -10
  126. data/lib/capybara/session/config.rb +34 -10
  127. data/lib/capybara/session/matchers.rb +23 -16
  128. data/lib/capybara/session.rb +230 -170
  129. data/lib/capybara/spec/public/jquery.js +5 -5
  130. data/lib/capybara/spec/public/offset.js +6 -0
  131. data/lib/capybara/spec/public/test.js +121 -8
  132. data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
  133. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  134. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  135. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  136. data/lib/capybara/spec/session/all_spec.rb +127 -40
  137. data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
  138. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
  139. data/lib/capybara/spec/session/assert_current_path_spec.rb +21 -18
  140. data/lib/capybara/spec/session/assert_selector_spec.rb +52 -58
  141. data/lib/capybara/spec/session/assert_style_spec.rb +7 -7
  142. data/lib/capybara/spec/session/assert_text_spec.rb +74 -50
  143. data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
  144. data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
  145. data/lib/capybara/spec/session/body_spec.rb +6 -6
  146. data/lib/capybara/spec/session/check_spec.rb +102 -47
  147. data/lib/capybara/spec/session/choose_spec.rb +58 -32
  148. data/lib/capybara/spec/session/click_button_spec.rb +219 -163
  149. data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -23
  150. data/lib/capybara/spec/session/click_link_spec.rb +77 -54
  151. data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
  152. data/lib/capybara/spec/session/current_url_spec.rb +38 -29
  153. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  154. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  155. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
  156. data/lib/capybara/spec/session/element/match_css_spec.rb +16 -10
  157. data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
  158. data/lib/capybara/spec/session/element/matches_selector_spec.rb +68 -56
  159. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  160. data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
  161. data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
  162. data/lib/capybara/spec/session/fill_in_spec.rb +101 -46
  163. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  164. data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
  165. data/lib/capybara/spec/session/find_field_spec.rb +32 -30
  166. data/lib/capybara/spec/session/find_link_spec.rb +31 -21
  167. data/lib/capybara/spec/session/find_spec.rb +244 -141
  168. data/lib/capybara/spec/session/first_spec.rb +43 -43
  169. data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
  170. data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
  171. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +30 -18
  172. data/lib/capybara/spec/session/frame/within_frame_spec.rb +45 -18
  173. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  174. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  175. data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
  176. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  177. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  178. data/lib/capybara/spec/session/has_button_spec.rb +94 -13
  179. data/lib/capybara/spec/session/has_css_spec.rb +272 -132
  180. data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
  181. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  182. data/lib/capybara/spec/session/has_field_spec.rb +137 -58
  183. data/lib/capybara/spec/session/has_link_spec.rb +44 -4
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +31 -31
  185. data/lib/capybara/spec/session/has_select_spec.rb +84 -50
  186. data/lib/capybara/spec/session/has_selector_spec.rb +111 -71
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +181 -4
  189. data/lib/capybara/spec/session/has_text_spec.rb +101 -53
  190. data/lib/capybara/spec/session/has_title_spec.rb +19 -14
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
  192. data/lib/capybara/spec/session/headers_spec.rb +1 -1
  193. data/lib/capybara/spec/session/html_spec.rb +13 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
  195. data/lib/capybara/spec/session/node_spec.rb +894 -142
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
  197. data/lib/capybara/spec/session/refresh_spec.rb +9 -7
  198. data/lib/capybara/spec/session/reset_session_spec.rb +63 -35
  199. data/lib/capybara/spec/session/response_code_spec.rb +1 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  202. data/lib/capybara/spec/session/save_page_spec.rb +37 -37
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +10 -10
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +119 -0
  206. data/lib/capybara/spec/session/select_spec.rb +85 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +49 -18
  208. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  209. data/lib/capybara/spec/session/text_spec.rb +25 -24
  210. data/lib/capybara/spec/session/title_spec.rb +7 -6
  211. data/lib/capybara/spec/session/uncheck_spec.rb +33 -21
  212. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  213. data/lib/capybara/spec/session/visit_spec.rb +68 -49
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
  216. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +20 -16
  217. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +6 -2
  218. data/lib/capybara/spec/session/window/window_spec.rb +62 -63
  219. data/lib/capybara/spec/session/window/windows_spec.rb +5 -1
  220. data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
  221. data/lib/capybara/spec/session/within_spec.rb +79 -42
  222. data/lib/capybara/spec/spec_helper.rb +41 -53
  223. data/lib/capybara/spec/test_app.rb +132 -43
  224. data/lib/capybara/spec/views/animated.erb +49 -0
  225. data/lib/capybara/spec/views/form.erb +139 -42
  226. data/lib/capybara/spec/views/frame_child.erb +4 -3
  227. data/lib/capybara/spec/views/frame_one.erb +2 -1
  228. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  229. data/lib/capybara/spec/views/frame_two.erb +1 -1
  230. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  231. data/lib/capybara/spec/views/layout.erb +10 -0
  232. data/lib/capybara/spec/views/obscured.erb +47 -0
  233. data/lib/capybara/spec/views/offset.erb +33 -0
  234. data/lib/capybara/spec/views/path.erb +2 -2
  235. data/lib/capybara/spec/views/popup_one.erb +1 -1
  236. data/lib/capybara/spec/views/popup_two.erb +1 -1
  237. data/lib/capybara/spec/views/react.erb +45 -0
  238. data/lib/capybara/spec/views/scroll.erb +21 -0
  239. data/lib/capybara/spec/views/spatial.erb +31 -0
  240. data/lib/capybara/spec/views/tables.erb +67 -0
  241. data/lib/capybara/spec/views/with_animation.erb +39 -4
  242. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  243. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  244. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  245. data/lib/capybara/spec/views/with_hover.erb +3 -2
  246. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  247. data/lib/capybara/spec/views/with_html.erb +37 -9
  248. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  249. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  250. data/lib/capybara/spec/views/with_js.erb +26 -5
  251. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  252. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  253. data/lib/capybara/spec/views/with_scope.erb +2 -2
  254. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  255. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  256. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  257. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  258. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  259. data/lib/capybara/spec/views/with_windows.erb +1 -1
  260. data/lib/capybara/spec/views/within_frames.erb +1 -1
  261. data/lib/capybara/version.rb +1 -1
  262. data/lib/capybara/window.rb +19 -25
  263. data/lib/capybara.rb +126 -111
  264. data/spec/basic_node_spec.rb +59 -34
  265. data/spec/capybara_spec.rb +56 -44
  266. data/spec/counter_spec.rb +35 -0
  267. data/spec/css_builder_spec.rb +101 -0
  268. data/spec/css_splitter_spec.rb +8 -8
  269. data/spec/dsl_spec.rb +79 -52
  270. data/spec/filter_set_spec.rb +9 -9
  271. data/spec/fixtures/selenium_driver_rspec_failure.rb +4 -4
  272. data/spec/fixtures/selenium_driver_rspec_success.rb +4 -4
  273. data/spec/minitest_spec.rb +45 -7
  274. data/spec/minitest_spec_spec.rb +87 -64
  275. data/spec/per_session_config_spec.rb +6 -6
  276. data/spec/rack_test_spec.rb +172 -116
  277. data/spec/regexp_dissassembler_spec.rb +250 -0
  278. data/spec/result_spec.rb +80 -72
  279. data/spec/rspec/features_spec.rb +21 -16
  280. data/spec/rspec/scenarios_spec.rb +10 -6
  281. data/spec/rspec/shared_spec_matchers.rb +407 -365
  282. data/spec/rspec/views_spec.rb +3 -3
  283. data/spec/rspec_matchers_spec.rb +35 -10
  284. data/spec/rspec_spec.rb +63 -41
  285. data/spec/sauce_spec_chrome.rb +43 -0
  286. data/spec/selector_spec.rb +334 -89
  287. data/spec/selenium_spec_chrome.rb +176 -62
  288. data/spec/selenium_spec_chrome_remote.rb +54 -14
  289. data/spec/selenium_spec_edge.rb +41 -8
  290. data/spec/selenium_spec_firefox.rb +228 -0
  291. data/spec/selenium_spec_firefox_remote.rb +94 -0
  292. data/spec/selenium_spec_ie.rb +129 -11
  293. data/spec/selenium_spec_safari.rb +162 -0
  294. data/spec/server_spec.rb +171 -97
  295. data/spec/session_spec.rb +34 -18
  296. data/spec/shared_selenium_node.rb +79 -0
  297. data/spec/shared_selenium_session.rb +344 -80
  298. data/spec/spec_helper.rb +124 -2
  299. data/spec/whitespace_normalizer_spec.rb +54 -0
  300. data/spec/xpath_builder_spec.rb +93 -0
  301. metadata +326 -28
  302. data/lib/capybara/rspec/compound.rb +0 -94
  303. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -31
  304. data/lib/capybara/selenium/nodes/marionette_node.rb +0 -31
  305. data/lib/capybara/spec/session/has_style_spec.rb +0 -25
  306. data/lib/capybara/spec/session/source_spec.rb +0 -0
  307. data/lib/capybara/spec/views/with_title.erb +0 -5
  308. data/spec/selenium_spec_marionette.rb +0 -167
data/lib/capybara.rb CHANGED
@@ -5,6 +5,7 @@ require 'nokogiri'
5
5
  require 'xpath'
6
6
  require 'forwardable'
7
7
  require 'capybara/config'
8
+ require 'capybara/registration_container'
8
9
 
9
10
  module Capybara
10
11
  class CapybaraError < StandardError; end
@@ -38,6 +39,8 @@ module Capybara
38
39
  # See {Capybara.configure}
39
40
  # @!method javascript_driver
40
41
  # See {Capybara.configure}
42
+ # @!method use_html5_parsing
43
+ # See {Capybara.configure}
41
44
  Config::OPTIONS.each do |method|
42
45
  def_delegators :config, method, "#{method}="
43
46
  end
@@ -64,32 +67,49 @@ module Capybara
64
67
  # config.app_host = 'http://www.google.com'
65
68
  # end
66
69
  #
67
- # === Configurable options
68
- #
69
- # [app_host = String/nil] The default host to use when giving a relative URL to visit, must be a valid URL e.g. http://www.example.com
70
- # [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL unless another port is explicitly specified (Default: false)
71
- # [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
72
- # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
73
- # [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
74
- # [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [StandardError])
75
- # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
76
- # [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
77
- # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
78
- # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
79
- # [save_path = String] Where to put pages saved through save_(page|screenshot), save_and_open_(page|screenshot) (Default: Dir.pwd)
80
- # [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
81
- # [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
82
- # [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
83
- # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
84
- # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
85
- # [default_set_options = Hash] The default options passed to Node::set (Default: {})
86
- #
87
- # === DSL Options
88
- #
89
- # when using capybara/dsl, the following options are also available:
90
- #
91
- # [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
92
- # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
70
+ # #### Configurable options
71
+ #
72
+ # - **use_html5_parsing** (Boolean = `false`) - When Nokogiri >= 1.12.0 or `nokogumbo` is installed, whether HTML5 parsing will be used for HTML strings.
73
+ # - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
74
+ # unless another port is explicitly specified.
75
+ # - **app_host** (String, `nil`) - The default host to use when giving a relative URL to visit, must be a valid URL e.g. `http://www.example.com`.
76
+ # - **asset_host** (String = `nil`) - Where dynamic assets are hosted - will be prepended to relative asset locations if present.
77
+ # - **automatic_label_click** (Boolean = `false`) - Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check},
78
+ # {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated `<label>` element if the checkbox/radio button are non-visible.
79
+ # - **automatic_reload** (Boolean = `true`) - Whether to automatically reload elements as Capybara is waiting.
80
+ # - **default_max_wait_time** (Numeric = `2`) - The maximum number of seconds to wait for asynchronous processes to finish.
81
+ # - **default_normalize_ws** (Boolean = `false`) - Whether text predicates and matchers use normalize whitespace behavior.
82
+ # - **default_retry_interval** (Numeric = `0.01`) - The number of seconds to delay the next check in asynchronous processes.
83
+ # - **default_selector** (`:css`, `:xpath` = `:css`) - Methods which take a selector use the given type by default. See also {Capybara::Selector}.
84
+ # - **default_set_options** (Hash = `{}`) - The default options passed to {Capybara::Node::Element#set Element#set}.
85
+ # - **enable_aria_label** (Boolean = `false`) - Whether fields, links, and buttons will match against `aria-label` attribute.
86
+ # - **enable_aria_role** (Boolean = `false`) - Selectors will check for relevant aria role (currently only `button`).
87
+ # - **exact** (Boolean = `false`) - Whether locators are matched exactly or with substrings. Only affects selector conditions
88
+ # written using the `XPath#is` method.
89
+ # - **exact_text** (Boolean = `false`) - Whether the text matchers and `:text` filter match exactly or on substrings.
90
+ # - **ignore_hidden_elements** (Boolean = `true`) - Whether to ignore hidden elements on the page.
91
+ # - **match** (`:one`, `:first`, `:prefer_exact`, `:smart` = `:smart`) - The matching strategy to find nodes.
92
+ # - **predicates_wait** (Boolean = `true`) - Whether Capybara's predicate matchers use waiting behavior by default.
93
+ # - **raise_server_errors** (Boolean = `true`) - Should errors raised in the server be raised in the tests?
94
+ # - **reuse_server** (Boolean = `true`) - Whether to reuse the server thread between multiple sessions using the same app object.
95
+ # - **run_server** (Boolean = `true`) - Whether to start a Rack server for the given Rack app.
96
+ # - **save_path** (String = `Dir.pwd`) - Where to put pages saved through {Capybara::Session#save_page save_page}, {Capybara::Session#save_screenshot save_screenshot},
97
+ # {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
98
+ # - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
99
+ # - **server_port** (Integer) - The port Capybara will run the application server on, if not specified a random port will be used.
100
+ # - **server_host** (String = "127.0.0.1") - The IP address Capybara will bind the application server to. If the test application is to be accessed from an external host, you will want to change this to "0.0.0.0" or to a more specific IP address that your test client can reach.
101
+ # - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
102
+ # and {configure raise_server_errors} is `true`.
103
+ # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
104
+ # - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually.
105
+ # - **w3c_click_offset** (Boolean = 'true') - Whether click offsets should be from element center (true) or top left (false)
106
+ #
107
+ # #### DSL Options
108
+ #
109
+ # When using `capybara/dsl`, the following options are also available:
110
+ #
111
+ # - **default_driver** (Symbol = `:rack_test`) - The name of the driver to use by default.
112
+ # - **javascript_driver** (Symbol = `:selenium`) - The name of a driver to use for JavaScript enabled tests.
93
113
  #
94
114
  def configure
95
115
  yield config
@@ -109,7 +129,7 @@ module Capybara
109
129
  # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
110
130
  #
111
131
  def register_driver(name, &block)
112
- drivers[name] = block
132
+ drivers.send(:register, name, block)
113
133
  end
114
134
 
115
135
  ##
@@ -128,7 +148,7 @@ module Capybara
128
148
  # @yieldparam host The host/ip to bind to
129
149
  #
130
150
  def register_server(name, &block)
131
- servers[name.to_sym] = block
151
+ servers.send(:register, name.to_sym, block)
132
152
  end
133
153
 
134
154
  ##
@@ -159,8 +179,8 @@ module Capybara
159
179
  # @param [Symbol] name The name of the selector to add
160
180
  # @yield A block executed in the context of the new {Capybara::Selector}
161
181
  #
162
- def add_selector(name, &block)
163
- Capybara::Selector.add(name, &block)
182
+ def add_selector(name, **options, &block)
183
+ Capybara::Selector.add(name, **options, &block)
164
184
  end
165
185
 
166
186
  ##
@@ -170,7 +190,7 @@ module Capybara
170
190
  # button style (a class) might look like this
171
191
  #
172
192
  # Capybara.modify_selector(:button) do
173
- # filter (:style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
193
+ # filter (:btn_style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
174
194
  # end
175
195
  #
176
196
  #
@@ -182,11 +202,11 @@ module Capybara
182
202
  end
183
203
 
184
204
  def drivers
185
- @drivers ||= {}
205
+ @drivers ||= RegistrationContainer.new
186
206
  end
187
207
 
188
208
  def servers
189
- @servers ||= {}
209
+ @servers ||= RegistrationContainer.new
190
210
  end
191
211
 
192
212
  # Wraps the given string, which should contain an HTML document or fragment
@@ -195,15 +215,13 @@ module Capybara
195
215
  # any string containing HTML in the exact same way you would query the current document in a Capybara
196
216
  # session.
197
217
  #
198
- # Example: A single element
199
- #
218
+ # @example A single element
200
219
  # node = Capybara.string('<a href="foo">bar</a>')
201
220
  # anchor = node.first('a')
202
221
  # anchor[:href] #=> 'foo'
203
222
  # anchor.text #=> 'bar'
204
223
  #
205
- # Example: Multiple elements
206
- #
224
+ # @example Multiple elements
207
225
  # node = Capybara.string <<-HTML
208
226
  # <ul>
209
227
  # <li id="home">Home</li>
@@ -242,7 +260,7 @@ module Capybara
242
260
  #
243
261
  def current_driver
244
262
  if threadsafe
245
- Thread.current['capybara_current_driver']
263
+ Thread.current.thread_variable_get :capybara_current_driver
246
264
  else
247
265
  @current_driver
248
266
  end || default_driver
@@ -251,7 +269,7 @@ module Capybara
251
269
 
252
270
  def current_driver=(name)
253
271
  if threadsafe
254
- Thread.current['capybara_current_driver'] = name
272
+ Thread.current.thread_variable_set :capybara_current_driver, name
255
273
  else
256
274
  @current_driver = name
257
275
  end
@@ -291,12 +309,12 @@ module Capybara
291
309
 
292
310
  ##
293
311
  #
294
- # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver
312
+ # The current {Capybara::Session} based on what is set as {app} and {current_driver}.
295
313
  #
296
314
  # @return [Capybara::Session] The currently used session
297
315
  #
298
316
  def current_session
299
- session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
317
+ specified_session || session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
300
318
  end
301
319
 
302
320
  ##
@@ -318,7 +336,8 @@ module Capybara
318
336
  #
319
337
  def session_name
320
338
  if threadsafe
321
- Thread.current['capybara_session_name'] ||= :default
339
+ Thread.current.thread_variable_get(:capybara_session_name) ||
340
+ Thread.current.thread_variable_set(:capybara_session_name, :default)
322
341
  else
323
342
  @session_name ||= :default
324
343
  end
@@ -326,7 +345,7 @@ module Capybara
326
345
 
327
346
  def session_name=(name)
328
347
  if threadsafe
329
- Thread.current['capybara_session_name'] = name
348
+ Thread.current.thread_variable_set :capybara_session_name, name
330
349
  else
331
350
  @session_name = name
332
351
  end
@@ -334,22 +353,31 @@ module Capybara
334
353
 
335
354
  ##
336
355
  #
337
- # Yield a block using a specific session name.
356
+ # Yield a block using a specific session name or {Capybara::Session} instance.
338
357
  #
339
- def using_session(name)
358
+ def using_session(name_or_session, &block)
359
+ previous_session = current_session
340
360
  previous_session_info = {
361
+ specified_session: specified_session,
341
362
  session_name: session_name,
342
363
  current_driver: current_driver,
343
364
  app: app
344
365
  }
345
- self.session_name = name
346
- yield
347
- ensure
348
- self.session_name = previous_session_info[:session_name]
349
- if threadsafe
350
- self.current_driver = previous_session_info[:current_driver]
351
- self.app = previous_session_info[:app]
366
+ self.specified_session = self.session_name = nil
367
+ if name_or_session.is_a? Capybara::Session
368
+ self.specified_session = name_or_session
369
+ else
370
+ self.session_name = name_or_session
371
+ end
372
+
373
+ if block.arity.zero?
374
+ yield
375
+ else
376
+ yield current_session, previous_session
352
377
  end
378
+ ensure
379
+ self.session_name, self.specified_session = previous_session_info.values_at(:session_name, :specified_session)
380
+ self.current_driver, self.app = previous_session_info.values_at(:current_driver, :app) if threadsafe
353
381
  end
354
382
 
355
383
  ##
@@ -360,9 +388,21 @@ module Capybara
360
388
  # @return [Nokogiri::HTML::Document] HTML document
361
389
  #
362
390
  def HTML(html) # rubocop:disable Naming/MethodName
363
- Nokogiri::HTML(html).tap do |document|
391
+ # Nokogiri >= 1.12.0 or Nokogumbo installed and allowed for use
392
+ html_parser, using_html5 = if defined?(Nokogiri::HTML5) && Capybara.use_html5_parsing
393
+ [Nokogiri::HTML5, true]
394
+ else
395
+ [defined?(Nokogiri::HTML4) ? Nokogiri::HTML4 : Nokogiri::HTML, false]
396
+ end
397
+
398
+ html_parser.parse(html).tap do |document|
399
+ document.xpath('//template').each do |template|
400
+ # template elements content is not part of the document
401
+ template.inner_html = ''
402
+ end
364
403
  document.xpath('//textarea').each do |textarea|
365
- textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/, '')
404
+ # The Nokogiri HTML5 parser already returns spec compliant contents
405
+ textarea['_capybara_raw_value'] = using_html5 ? textarea.content : textarea.content.delete_prefix("\n")
366
406
  end
367
407
  end
368
408
  end
@@ -378,7 +418,25 @@ module Capybara
378
418
  end
379
419
 
380
420
  def session_pool
381
- @session_pool ||= {}
421
+ @session_pool ||= Hash.new do |hash, name|
422
+ hash[name] = Capybara::Session.new(current_driver, app)
423
+ end
424
+ end
425
+
426
+ def specified_session
427
+ if threadsafe
428
+ Thread.current.thread_variable_get :capybara_specified_session
429
+ else
430
+ @specified_session ||= nil
431
+ end
432
+ end
433
+
434
+ def specified_session=(session)
435
+ if threadsafe
436
+ Thread.current.thread_variable_set :capybara_specified_session, session
437
+ else
438
+ @specified_session = session
439
+ end
382
440
  end
383
441
  end
384
442
 
@@ -407,6 +465,7 @@ module Capybara
407
465
  require 'capybara/queries/ancestor_query'
408
466
  require 'capybara/queries/sibling_query'
409
467
  require 'capybara/queries/style_query'
468
+ require 'capybara/queries/active_element_query'
410
469
 
411
470
  require 'capybara/node/finders'
412
471
  require 'capybara/node/matchers'
@@ -424,45 +483,14 @@ module Capybara
424
483
  require 'capybara/rack_test/node'
425
484
  require 'capybara/rack_test/form'
426
485
  require 'capybara/rack_test/browser'
427
- require 'capybara/rack_test/css_handlers.rb'
486
+ require 'capybara/rack_test/css_handlers'
428
487
 
429
488
  require 'capybara/selenium/node'
430
- require 'capybara/selenium/nodes/marionette_node'
431
489
  require 'capybara/selenium/driver'
432
490
  end
433
491
 
434
- Capybara.register_server :default do |app, port, _host|
435
- Capybara.run_default_server(app, port)
436
- end
437
-
438
- Capybara.register_server :webrick do |app, port, host, **options|
439
- require 'rack/handler/webrick'
440
- Rack::Handler::WEBrick.run(app, { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options))
441
- end
442
-
443
- Capybara.register_server :puma do |app, port, host, **options|
444
- begin
445
- require 'rack/handler/puma'
446
- rescue LoadError
447
- raise LoadError, "Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`."
448
- end
449
- # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
450
- # Therefore construct and run the Server instance ourselves.
451
- # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
452
-
453
- conf = Rack::Handler::Puma.config(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
454
- events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
455
-
456
- events.log "Capybara starting Puma..."
457
- events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
458
- events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
459
-
460
- Puma::Server.new(conf.app, events, conf.options).tap do |s|
461
- s.binder.parse conf.options[:binds], s.events
462
- s.min_threads = conf.options[:min_threads]
463
- s.max_threads = conf.options[:max_threads]
464
- end.run.join
465
- end
492
+ require 'capybara/registrations/servers'
493
+ require 'capybara/registrations/drivers'
466
494
 
467
495
  Capybara.configure do |config|
468
496
  config.always_include_port = false
@@ -470,37 +498,24 @@ Capybara.configure do |config|
470
498
  config.server = :default
471
499
  config.default_selector = :css
472
500
  config.default_max_wait_time = 2
501
+ config.default_retry_interval = 0.01
473
502
  config.ignore_hidden_elements = true
474
- config.default_host = "http://www.example.com"
503
+ config.default_host = 'http://www.example.com'
475
504
  config.automatic_reload = true
476
505
  config.match = :smart
477
506
  config.exact = false
478
507
  config.exact_text = false
479
508
  config.raise_server_errors = true
480
- config.server_errors = [StandardError]
509
+ config.server_errors = [Exception]
481
510
  config.visible_text_only = false
482
511
  config.automatic_label_click = false
483
512
  config.enable_aria_label = false
513
+ config.enable_aria_role = false
484
514
  config.reuse_server = true
485
515
  config.default_set_options = {}
486
- end
487
-
488
- Capybara.register_driver :rack_test do |app|
489
- Capybara::RackTest::Driver.new(app)
490
- end
491
-
492
- Capybara.register_driver :selenium do |app|
493
- Capybara::Selenium::Driver.new(app)
494
- end
495
-
496
- Capybara.register_driver :selenium_chrome do |app|
497
- Capybara::Selenium::Driver.new(app, browser: :chrome)
498
- end
499
-
500
- Capybara.register_driver :selenium_chrome_headless do |app|
501
- Capybara::Selenium::Driver.load_selenium
502
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
503
- browser_options.args << '--headless'
504
- browser_options.args << '--disable-gpu' if Gem.win_platform?
505
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
516
+ config.test_id = nil
517
+ config.predicates_wait = true
518
+ config.default_normalize_ws = false
519
+ config.use_html5_parsing = false
520
+ config.w3c_click_offset = true
506
521
  end
@@ -3,9 +3,10 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara do
6
+ include Capybara::RSpecMatchers
6
7
  describe '.string' do
7
8
  let :string do
8
- Capybara.string <<-STRING
9
+ described_class.string <<-STRING
9
10
  <html>
10
11
  <head>
11
12
  <title>simple_node</title>
@@ -46,97 +47,121 @@ RSpec.describe Capybara do
46
47
  STRING
47
48
  end
48
49
 
49
- it "allows using matchers" do
50
+ it 'allows using matchers' do
50
51
  expect(string).to have_css('#page')
51
52
  expect(string).not_to have_css('#does-not-exist')
52
53
  end
53
54
 
54
- it "allows using custom matchers" do
55
- Capybara.add_selector :lifeform do
55
+ it 'allows using custom matchers' do
56
+ described_class.add_selector :lifeform do
56
57
  xpath { |name| ".//option[contains(.,'#{name}')]" }
57
58
  end
58
- expect(string).to have_selector(:id, "page")
59
+ expect(string).to have_selector(:id, 'page')
59
60
  expect(string).not_to have_selector(:id, 'does-not-exist')
60
- expect(string).to have_selector(:lifeform, "Monkey")
61
- expect(string).not_to have_selector(:lifeform, "Gorilla")
61
+ expect(string).to have_selector(:lifeform, 'Monkey')
62
+ expect(string).not_to have_selector(:lifeform, 'Gorilla')
62
63
  end
63
64
 
64
65
  it 'allows custom matcher using css' do
65
- Capybara.add_selector :section do
66
+ described_class.add_selector :section do
66
67
  css { |css_class| "section .#{css_class}" }
67
68
  end
68
69
  expect(string).to have_selector(:section, 'subsection')
69
70
  expect(string).not_to have_selector(:section, 'section_8')
70
71
  end
71
72
 
72
- it "allows using matchers with text option" do
73
+ it 'allows using matchers with text option' do
73
74
  expect(string).to have_css('h1', text: 'Totally awesome')
74
75
  expect(string).not_to have_css('h1', text: 'Not so awesome')
75
76
  end
76
77
 
77
- it "allows finding only visible nodes" do
78
+ it 'allows finding only visible nodes' do
78
79
  expect(string.all(:css, '#secret', visible: true)).to be_empty
79
80
  expect(string.all(:css, '#secret', visible: false).size).to eq(1)
80
81
  end
81
82
 
82
- it "allows finding elements and extracting text from them" do
83
+ it 'allows finding elements and extracting text from them' do
83
84
  expect(string.find('//h1').text).to eq('Totally awesome')
84
85
  end
85
86
 
86
- it "allows finding elements and extracting attributes from them" do
87
+ it 'allows finding elements and extracting attributes from them' do
87
88
  expect(string.find('//h1')[:data]).to eq('fantastic')
88
89
  end
89
90
 
90
- it "allows finding elements and extracting the tag name from them" do
91
+ it 'allows finding elements and extracting the tag name from them' do
91
92
  expect(string.find('//h1').tag_name).to eq('h1')
92
93
  end
93
94
 
94
- it "allows finding elements and extracting the path" do
95
+ it 'allows finding elements and extracting the path' do
95
96
  expect(string.find('//h1').path).to eq('/html/body/div/div[1]/h1')
96
97
  end
97
98
 
98
- it "allows finding elements and extracting the value" do
99
+ it 'allows finding elements and extracting the value' do
99
100
  expect(string.find('//div/input').value).to eq('bar')
100
101
  expect(string.find('//select').value).to eq('Capybara')
101
102
  end
102
103
 
103
- it "allows finding elements and checking if they are visible" do
104
+ it 'allows finding elements and checking if they are visible' do
104
105
  expect(string.find('//h1')).to be_visible
105
- expect(string.find(:css, "#secret", visible: false)).not_to be_visible
106
+ expect(string.find(:css, '#secret', visible: false)).not_to be_visible
106
107
  end
107
108
 
108
- it "allows finding elements and checking if they are disabled" do
109
+ it 'allows finding elements and checking if they are disabled' do
109
110
  expect(string.find('//form/input[@name="bleh"]')).to be_disabled
110
111
  expect(string.find('//form/input[@name="meh"]')).not_to be_disabled
111
112
  end
112
113
 
113
- describe "#title" do
114
- it "returns the page title" do
115
- expect(string.title).to eq("simple_node")
114
+ it 'allows finding siblings' do
115
+ h1 = string.find(:css, 'h1')
116
+ expect(h1).to have_sibling(:css, 'p', text: 'Yes it is')
117
+ expect(h1).not_to have_sibling(:css, 'p', text: 'Jonas Nicklas')
118
+ end
119
+
120
+ it 'allows finding ancestor' do
121
+ h1 = string.find(:css, 'h1')
122
+ expect(h1).to have_ancestor(:css, '#content')
123
+ expect(h1).not_to have_ancestor(:css, '#footer')
124
+ end
125
+
126
+ it 'drops illegal fragments when using gumbo' do
127
+ skip 'libxml is less strict than Gumbo' unless Nokogiri.respond_to?(:HTML5)
128
+ described_class.use_html5_parsing = true
129
+ expect(described_class.string('<td>1</td>')).not_to have_css('td')
130
+ end
131
+
132
+ it 'can disable use of HTML5 parsing' do
133
+ skip "Test doesn't make sense unlesss HTML5 parsing is loaded (Nokogumbo or Nokogiri >= 1.12.0)" unless Nokogiri.respond_to?(:HTML5)
134
+ described_class.use_html5_parsing = false
135
+ expect(described_class.string('<td>1</td>')).to have_css('td')
136
+ end
137
+
138
+ describe '#title' do
139
+ it 'returns the page title' do
140
+ expect(string.title).to eq('simple_node')
116
141
  end
117
142
  end
118
143
 
119
- describe "#has_title?" do
120
- it "returns whether the page has the given title" do
121
- expect(string.has_title?('simple_node')).to be_truthy
122
- expect(string.has_title?('monkey')).to be_falsey
144
+ describe '#has_title?' do
145
+ it 'returns whether the page has the given title' do
146
+ expect(string.has_title?('simple_node')).to be true
147
+ expect(string.has_title?('monkey')).to be false
123
148
  end
124
149
 
125
- it "allows regexp matches" do
126
- expect(string.has_title?(/s[a-z]+_node/)).to be_truthy
127
- expect(string.has_title?(/monkey/)).to be_falsey
150
+ it 'allows regexp matches' do
151
+ expect(string.has_title?(/s[a-z]+_node/)).to be true
152
+ expect(string.has_title?(/monkey/)).to be false
128
153
  end
129
154
  end
130
155
 
131
156
  describe '#has_no_title?' do
132
- it "returns whether the page does not have the given title" do
133
- expect(string.has_no_title?('simple_node')).to be_falsey
134
- expect(string.has_no_title?('monkey')).to be_truthy
157
+ it 'returns whether the page does not have the given title' do
158
+ expect(string.has_no_title?('simple_node')).to be false
159
+ expect(string.has_no_title?('monkey')).to be true
135
160
  end
136
161
 
137
- it "allows regexp matches" do
138
- expect(string.has_no_title?(/s[a-z]+_node/)).to be_falsey
139
- expect(string.has_no_title?(/monkey/)).to be_truthy
162
+ it 'allows regexp matches' do
163
+ expect(string.has_no_title?(/s[a-z]+_node/)).to be false
164
+ expect(string.has_no_title?(/monkey/)).to be true
140
165
  end
141
166
  end
142
167
  end