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,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  RSpec.describe Capybara do
6
+ include Capybara::RSpecMatchers
5
7
  describe '.string' do
6
8
  let :string do
7
- Capybara.string <<-STRING
9
+ described_class.string <<-STRING
8
10
  <html>
9
11
  <head>
10
12
  <title>simple_node</title>
@@ -45,97 +47,121 @@ RSpec.describe Capybara do
45
47
  STRING
46
48
  end
47
49
 
48
- it "allows using matchers" do
50
+ it 'allows using matchers' do
49
51
  expect(string).to have_css('#page')
50
52
  expect(string).not_to have_css('#does-not-exist')
51
53
  end
52
54
 
53
- it "allows using custom matchers" do
54
- Capybara.add_selector :lifeform do
55
+ it 'allows using custom matchers' do
56
+ described_class.add_selector :lifeform do
55
57
  xpath { |name| ".//option[contains(.,'#{name}')]" }
56
58
  end
57
- expect(string).to have_selector(:id, "page")
59
+ expect(string).to have_selector(:id, 'page')
58
60
  expect(string).not_to have_selector(:id, 'does-not-exist')
59
- expect(string).to have_selector(:lifeform, "Monkey")
60
- 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')
61
63
  end
62
64
 
63
65
  it 'allows custom matcher using css' do
64
- Capybara.add_selector :section do
66
+ described_class.add_selector :section do
65
67
  css { |css_class| "section .#{css_class}" }
66
68
  end
67
69
  expect(string).to have_selector(:section, 'subsection')
68
70
  expect(string).not_to have_selector(:section, 'section_8')
69
71
  end
70
72
 
71
- it "allows using matchers with text option" do
73
+ it 'allows using matchers with text option' do
72
74
  expect(string).to have_css('h1', text: 'Totally awesome')
73
75
  expect(string).not_to have_css('h1', text: 'Not so awesome')
74
76
  end
75
77
 
76
- it "allows finding only visible nodes" do
78
+ it 'allows finding only visible nodes' do
77
79
  expect(string.all(:css, '#secret', visible: true)).to be_empty
78
80
  expect(string.all(:css, '#secret', visible: false).size).to eq(1)
79
81
  end
80
82
 
81
- it "allows finding elements and extracting text from them" do
83
+ it 'allows finding elements and extracting text from them' do
82
84
  expect(string.find('//h1').text).to eq('Totally awesome')
83
85
  end
84
86
 
85
- it "allows finding elements and extracting attributes from them" do
87
+ it 'allows finding elements and extracting attributes from them' do
86
88
  expect(string.find('//h1')[:data]).to eq('fantastic')
87
89
  end
88
90
 
89
- 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
90
92
  expect(string.find('//h1').tag_name).to eq('h1')
91
93
  end
92
94
 
93
- it "allows finding elements and extracting the path" do
95
+ it 'allows finding elements and extracting the path' do
94
96
  expect(string.find('//h1').path).to eq('/html/body/div/div[1]/h1')
95
97
  end
96
98
 
97
- it "allows finding elements and extracting the path" do
99
+ it 'allows finding elements and extracting the value' do
98
100
  expect(string.find('//div/input').value).to eq('bar')
99
101
  expect(string.find('//select').value).to eq('Capybara')
100
102
  end
101
103
 
102
- it "allows finding elements and checking if they are visible" do
104
+ it 'allows finding elements and checking if they are visible' do
103
105
  expect(string.find('//h1')).to be_visible
104
- expect(string.find(:css, "#secret", visible: false)).not_to be_visible
106
+ expect(string.find(:css, '#secret', visible: false)).not_to be_visible
105
107
  end
106
108
 
107
- it "allows finding elements and checking if they are disabled" do
109
+ it 'allows finding elements and checking if they are disabled' do
108
110
  expect(string.find('//form/input[@name="bleh"]')).to be_disabled
109
111
  expect(string.find('//form/input[@name="meh"]')).not_to be_disabled
110
112
  end
111
113
 
112
- describe "#title" do
113
- it "returns the page title" do
114
- 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')
115
141
  end
116
142
  end
117
143
 
118
- describe "#has_title?" do
119
- it "returns whether the page has the given title" do
120
- expect(string.has_title?('simple_node')).to be_truthy
121
- 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
122
148
  end
123
149
 
124
- it "allows regexp matches" do
125
- expect(string.has_title?(/s[a-z]+_node/)).to be_truthy
126
- 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
127
153
  end
128
154
  end
129
155
 
130
156
  describe '#has_no_title?' do
131
- it "returns whether the page does not have the given title" do
132
- expect(string.has_no_title?('simple_node')).to be_falsey
133
- 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
134
160
  end
135
161
 
136
- it "allows regexp matches" do
137
- expect(string.has_no_title?(/s[a-z]+_node/)).to be_falsey
138
- 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
139
165
  end
140
166
  end
141
167
  end
@@ -1,149 +1,124 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  RSpec.describe Capybara do
5
6
  describe 'default_max_wait_time' do
6
- after do
7
- Capybara.default_max_wait_time = @previous_default_time
8
- end
7
+ before { @previous_default_time = described_class.default_max_wait_time }
9
8
 
10
- it "should be changeable" do
11
- @previous_default_time = Capybara.default_max_wait_time
12
- Capybara.default_max_wait_time = 5
13
- expect(Capybara.default_max_wait_time).to eq(5)
9
+ after { described_class.default_max_wait_time = @previous_default_time } # rubocop:disable RSpec/InstanceVariable
10
+
11
+ it 'should be changeable' do
12
+ expect(described_class.default_max_wait_time).not_to eq(5)
13
+ described_class.default_max_wait_time = 5
14
+ expect(described_class.default_max_wait_time).to eq(5)
14
15
  end
16
+ end
15
17
 
16
- it "should be accesible as the deprecated default_wait_time" do
17
- expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time= is deprecated, please use #default_max_wait_time= instead')
18
- expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time is deprecated, please use #default_max_wait_time instead')
19
- @previous_default_time = Capybara.default_max_wait_time
20
- Capybara.default_wait_time = 5
21
- expect(Capybara.default_wait_time).to eq(5)
22
- expect(Capybara.default_max_wait_time).to eq(5)
18
+ describe 'default_retry_interval' do
19
+ before { @previous_default_interval = described_class.default_retry_interval }
20
+
21
+ after { described_class.default_retry_interval = @previous_default_interval } # rubocop:disable RSpec/InstanceVariable
22
+
23
+ it 'should be changeable' do
24
+ expect(described_class.default_retry_interval).not_to eq(0.1)
25
+ described_class.default_retry_interval = 0.1
26
+ expect(described_class.default_retry_interval).to eq(0.1)
23
27
  end
24
28
  end
25
29
 
26
30
  describe '.register_driver' do
27
- it "should add a new driver" do
28
- Capybara.register_driver :schmoo do |app|
31
+ it 'should add a new driver' do
32
+ described_class.register_driver :schmoo do |app|
29
33
  Capybara::RackTest::Driver.new(app)
30
34
  end
31
35
  session = Capybara::Session.new(:schmoo, TestApp)
32
36
  session.visit('/')
33
- expect(session.body).to include("Hello world!")
37
+ expect(session.body).to include('Hello world!')
34
38
  end
35
39
  end
36
40
 
37
41
  describe '.register_server' do
38
- it "should add a new server" do
39
- handler = double("handler")
40
- Capybara.register_server :blob do |app, port, host|
41
- handler.run
42
+ it 'should add a new server' do
43
+ described_class.register_server :blob do |_app, _port, _host|
44
+ # do nothing
42
45
  end
43
46
 
44
- expect(Capybara.servers).to have_key(:blob)
47
+ expect(described_class.servers[:blob]).to be_truthy
45
48
  end
46
49
  end
47
50
 
48
- describe ".server" do
49
- before do
50
- @old_server = Capybara.server
51
+ describe '.server' do
52
+ after do
53
+ described_class.server = :default
51
54
  end
52
55
 
53
- after do
54
- Capybara.server(&@old_server)
56
+ it 'should default to a proc that calls run_default_server' do
57
+ mock_app = Object.new
58
+ allow(described_class).to receive(:run_default_server).and_return(true)
59
+ described_class.server.call(mock_app, 8000)
60
+ expect(described_class).to have_received(:run_default_server).with(mock_app, 8000)
55
61
  end
56
62
 
57
- it "should default to a proc that calls run_default_server" do
58
- mock_app = double('app')
59
- expect(Capybara).to receive(:run_default_server).with(mock_app, 8000)
60
- Capybara.server.call(mock_app, 8000)
63
+ it 'should return a custom server proc' do
64
+ server = ->(_app, _port) {}
65
+ described_class.register_server :custom, &server
66
+ described_class.server = :custom
67
+ expect(described_class.server).to eq(server)
61
68
  end
62
69
 
63
- it "should return a custom server proc" do
64
- server = lambda {|app, port|}
65
- Capybara.server(&server)
66
- expect(Capybara.server).to eq(server)
70
+ it 'should have :webrick registered' do
71
+ expect(described_class.servers[:webrick]).not_to be_nil
67
72
  end
68
73
 
69
- it "should have :webrick registered" do
70
- require 'rack/handler/webrick'
71
- mock_app = double('app')
72
- Capybara.server = :webrick
73
- expect(Rack::Handler::WEBrick).to receive(:run)
74
- Capybara.server.call(mock_app, 8000)
74
+ it 'should have :puma registered' do
75
+ expect(described_class.servers[:puma]).not_to be_nil
75
76
  end
77
+ end
76
78
 
77
- it "should have :puma registered" do
78
- require 'rack/handler/puma'
79
- mock_app = double('app')
80
- Capybara.server = :puma
81
- expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 8000))
82
- Capybara.server.call(mock_app, 8000)
79
+ describe 'server=' do
80
+ after do
81
+ described_class.server = :default
83
82
  end
84
83
 
85
- it "should pass options to server" do
86
- require 'rack/handler/puma'
87
- mock_app = double('app')
88
- Capybara.server = :puma, { Silent: true }
89
- expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 9000, Silent: true))
90
- Capybara.server.call(mock_app, 9000)
84
+ it 'accepts a proc' do
85
+ server = ->(_app, _port) {}
86
+ described_class.server = server
87
+ expect(described_class.server).to eq server
91
88
  end
92
89
  end
93
90
 
94
91
  describe 'app_host' do
95
92
  after do
96
- Capybara.app_host = nil
93
+ described_class.app_host = nil
97
94
  end
98
95
 
99
- it "should warn if not a valid URL" do
100
- expect { Capybara.app_host = "www.example.com" }.to raise_error(ArgumentError, /Capybara\.app_host should be set to a url/)
96
+ it 'should warn if not a valid URL' do
97
+ expect { described_class.app_host = 'www.example.com' }.to raise_error(ArgumentError, /Capybara\.app_host should be set to a url/)
101
98
  end
102
99
 
103
- it "should not warn if a valid URL" do
104
- expect { Capybara.app_host = "http://www.example.com" }.not_to raise_error
100
+ it 'should not warn if a valid URL' do
101
+ expect { described_class.app_host = 'http://www.example.com' }.not_to raise_error
105
102
  end
106
103
 
107
- it "should not warn if nil" do
108
- expect { Capybara.app_host = nil }.not_to raise_error
104
+ it 'should not warn if nil' do
105
+ expect { described_class.app_host = nil }.not_to raise_error
109
106
  end
110
107
  end
111
108
 
112
109
  describe 'default_host' do
113
110
  around do |test|
114
- old_default = Capybara.default_host
111
+ old_default = described_class.default_host
115
112
  test.run
116
- Capybara.default_host = old_default
117
- end
118
-
119
- it "should warn if not a valid URL" do
120
- expect { Capybara.default_host = "www.example.com" }.to raise_error(ArgumentError, /Capybara\.default_host should be set to a url/)
113
+ described_class.default_host = old_default
121
114
  end
122
115
 
123
- it "should not warn if a valid URL" do
124
- expect { Capybara.default_host = "http://www.example.com" }.not_to raise_error
116
+ it 'should raise if not a valid URL' do
117
+ expect { described_class.default_host = 'www.example.com' }.to raise_error(ArgumentError, /Capybara\.default_host should be set to a url/)
125
118
  end
126
- end
127
-
128
- describe "configure" do
129
- it 'deprecates calling non configuration option methods in configure' do
130
- expect_any_instance_of(Kernel).to receive(:warn).
131
- with('Calling register_driver from Capybara.configure is deprecated - please call it on Capybara directly ( Capybara.register_driver(...) )')
132
- Capybara.configure do |config|
133
- config.register_driver(:random_name) do
134
- #just a random block
135
- end
136
- end
137
- end
138
- end
139
- end
140
119
 
141
- RSpec.describe Capybara::Session do
142
- context 'with nonexistent driver' do
143
- it "should raise an error" do
144
- expect {
145
- Capybara::Session.new(:quox, TestApp).driver
146
- }.to raise_error(Capybara::DriverNotFoundError)
120
+ it 'should not warn if a valid URL' do
121
+ expect { described_class.default_host = 'http://www.example.com' }.not_to raise_error
147
122
  end
148
123
  end
149
124
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Capybara::Server::Middleware::Counter do
6
+ let(:counter) { described_class.new }
7
+ let(:uri) { '/example' }
8
+
9
+ describe '#increment' do
10
+ it 'successfully' do
11
+ counter.increment(uri)
12
+ expect(counter).to be_positive
13
+ end
14
+ end
15
+
16
+ describe '#decrement' do
17
+ before do
18
+ counter.increment(uri)
19
+ end
20
+
21
+ context 'successfully' do
22
+ it 'with same uri' do
23
+ expect(counter).to be_positive
24
+ counter.decrement(uri)
25
+ expect(counter).not_to be_positive
26
+ end
27
+
28
+ it 'with changed uri' do
29
+ expect(counter).to be_positive
30
+ counter.decrement('/')
31
+ expect(counter).not_to be_positive
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # rubocop:disable RSpec/InstanceVariable
6
+ RSpec.describe Capybara::Selector::CSSBuilder do
7
+ let :builder do
8
+ described_class.new(@css)
9
+ end
10
+
11
+ context 'add_attribute_conditions' do
12
+ it 'adds a single string condition to a single selector' do
13
+ @css = 'div'
14
+ selector = builder.add_attribute_conditions(random: 'abc')
15
+ expect(selector).to eq %(div[random='abc'])
16
+ end
17
+
18
+ it 'adds multiple string conditions to a single selector' do
19
+ @css = 'div'
20
+ selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
21
+ expect(selector).to eq %(div[random='abc'][other='def'])
22
+ end
23
+
24
+ it 'adds a single string condition to a multiple selector' do
25
+ @css = 'div, ul'
26
+ selector = builder.add_attribute_conditions(random: 'abc')
27
+ expect(selector).to eq %(div[random='abc'], ul[random='abc'])
28
+ end
29
+
30
+ it 'adds multiple string conditions to a multiple selector' do
31
+ @css = 'div, ul'
32
+ selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
33
+ expect(selector).to eq %(div[random='abc'][other='def'], ul[random='abc'][other='def'])
34
+ end
35
+
36
+ it 'adds simple regexp conditions to a single selector' do
37
+ @css = 'div'
38
+ selector = builder.add_attribute_conditions(random: /abc/, other: /def/)
39
+ expect(selector).to eq %(div[random*='abc'][other*='def'])
40
+ end
41
+
42
+ it 'adds wildcard regexp conditions to a single selector' do
43
+ @css = 'div'
44
+ selector = builder.add_attribute_conditions(random: /abc.*def/, other: /def.*ghi/)
45
+ expect(selector).to eq %(div[random*='abc'][random*='def'][other*='def'][other*='ghi'])
46
+ end
47
+
48
+ it 'adds alternated regexp conditions to a single selector' do
49
+ @css = 'div'
50
+ selector = builder.add_attribute_conditions(random: /abc|def/, other: /def|ghi/)
51
+ expect(selector).to eq %(div[random*='abc'][other*='def'], div[random*='abc'][other*='ghi'], div[random*='def'][other*='def'], div[random*='def'][other*='ghi'])
52
+ end
53
+
54
+ it 'adds alternated regexp conditions to a multiple selector' do
55
+ @css = 'div,ul'
56
+ selector = builder.add_attribute_conditions(other: /def.*ghi|jkl/)
57
+ expect(selector).to eq %(div[other*='def'][other*='ghi'], div[other*='jkl'], ul[other*='def'][other*='ghi'], ul[other*='jkl'])
58
+ end
59
+
60
+ it "returns original selector when regexp can't be substringed" do
61
+ @css = 'div'
62
+ selector = builder.add_attribute_conditions(other: /.+/)
63
+ expect(selector).to eq 'div'
64
+ end
65
+
66
+ context ':class' do
67
+ it 'handles string with CSS .' do
68
+ @css = 'a'
69
+ selector = builder.add_attribute_conditions(class: 'my_class')
70
+ expect(selector).to eq 'a.my_class'
71
+ end
72
+
73
+ it 'handles negated string with CSS .' do
74
+ @css = 'a'
75
+ selector = builder.add_attribute_conditions(class: '!my_class')
76
+ expect(selector).to eq 'a:not(.my_class)'
77
+ end
78
+
79
+ it 'handles array of string with CSS .' do
80
+ @css = 'a'
81
+ selector = builder.add_attribute_conditions(class: %w[my_class my_other_class])
82
+ expect(selector).to eq 'a.my_class.my_other_class'
83
+ end
84
+
85
+ it 'handles array of string with CSS . when negated included' do
86
+ @css = 'a'
87
+ selector = builder.add_attribute_conditions(class: %w[my_class !my_other_class])
88
+ expect(selector).to eq 'a.my_class:not(.my_other_class)'
89
+ end
90
+ end
91
+
92
+ context ':id' do
93
+ it 'handles string with CSS #' do
94
+ @css = 'ul'
95
+ selector = builder.add_attribute_conditions(id: 'my_id')
96
+ expect(selector).to eq 'ul#my_id'
97
+ end
98
+ end
99
+ end
100
+ end
101
+ # rubocop:enable RSpec/InstanceVariable
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Capybara::Selector::CSS::Splitter do
6
+ let :splitter do
7
+ described_class.new
8
+ end
9
+
10
+ context 'split not needed' do
11
+ it 'normal CSS selector' do
12
+ css = 'div[id="abc"]'
13
+ expect(splitter.split(css)).to eq [css]
14
+ end
15
+
16
+ it 'comma in strings' do
17
+ css = 'div[id="a,bc"]'
18
+ expect(splitter.split(css)).to eq [css]
19
+ end
20
+
21
+ it 'comma in pseudo-selector' do
22
+ css = 'div.class1:not(.class1, .class2)'
23
+ expect(splitter.split(css)).to eq [css]
24
+ end
25
+ end
26
+
27
+ context 'split needed' do
28
+ it 'root level comma' do
29
+ css = 'div.class1, span, p.class2'
30
+ expect(splitter.split(css)).to eq ['div.class1', 'span', 'p.class2']
31
+ end
32
+
33
+ it 'root level comma when quotes and pseudo selectors' do
34
+ css = 'div.class1[id="abc\\"def,ghi"]:not(.class3, .class4), span[id=\'a"c\\\'de\'], section, #abc\\,def'
35
+ expect(splitter.split(css)).to eq ['div.class1[id="abc\\"def,ghi"]:not(.class3, .class4)', 'span[id=\'a"c\\\'de\']', 'section', '#abc\\,def']
36
+ end
37
+ end
38
+ end