capybara 2.7.0 → 3.35.3

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 (318) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +1 -0
  3. data/History.md +1147 -11
  4. data/License.txt +1 -1
  5. data/README.md +252 -131
  6. data/lib/capybara/config.rb +92 -0
  7. data/lib/capybara/cucumber.rb +3 -3
  8. data/lib/capybara/driver/base.rb +52 -21
  9. data/lib/capybara/driver/node.rb +48 -14
  10. data/lib/capybara/dsl.rb +16 -9
  11. data/lib/capybara/helpers.rb +72 -81
  12. data/lib/capybara/minitest/spec.rb +267 -0
  13. data/lib/capybara/minitest.rb +385 -0
  14. data/lib/capybara/node/actions.rb +337 -89
  15. data/lib/capybara/node/base.rb +50 -32
  16. data/lib/capybara/node/document.rb +19 -3
  17. data/lib/capybara/node/document_matchers.rb +22 -24
  18. data/lib/capybara/node/element.rb +388 -125
  19. data/lib/capybara/node/finders.rb +231 -121
  20. data/lib/capybara/node/matchers.rb +503 -217
  21. data/lib/capybara/node/simple.rb +64 -27
  22. data/lib/capybara/queries/ancestor_query.rb +27 -0
  23. data/lib/capybara/queries/base_query.rb +87 -11
  24. data/lib/capybara/queries/current_path_query.rb +24 -24
  25. data/lib/capybara/queries/match_query.rb +15 -10
  26. data/lib/capybara/queries/selector_query.rb +675 -81
  27. data/lib/capybara/queries/sibling_query.rb +26 -0
  28. data/lib/capybara/queries/style_query.rb +45 -0
  29. data/lib/capybara/queries/text_query.rb +88 -20
  30. data/lib/capybara/queries/title_query.rb +9 -11
  31. data/lib/capybara/rack_test/browser.rb +63 -39
  32. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  33. data/lib/capybara/rack_test/driver.rb +26 -16
  34. data/lib/capybara/rack_test/errors.rb +6 -0
  35. data/lib/capybara/rack_test/form.rb +73 -58
  36. data/lib/capybara/rack_test/node.rb +187 -67
  37. data/lib/capybara/rails.rb +4 -8
  38. data/lib/capybara/registration_container.rb +44 -0
  39. data/lib/capybara/registrations/drivers.rb +42 -0
  40. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  41. data/lib/capybara/registrations/servers.rb +45 -0
  42. data/lib/capybara/result.rb +142 -14
  43. data/lib/capybara/rspec/features.rb +17 -42
  44. data/lib/capybara/rspec/matcher_proxies.rb +82 -0
  45. data/lib/capybara/rspec/matchers/base.rb +111 -0
  46. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  47. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  48. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  49. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  50. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  51. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  52. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  53. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  54. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  55. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  56. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  57. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  58. data/lib/capybara/rspec/matchers.rb +143 -244
  59. data/lib/capybara/rspec.rb +10 -12
  60. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  61. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  62. data/lib/capybara/selector/css.rb +102 -0
  63. data/lib/capybara/selector/definition/button.rb +63 -0
  64. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  65. data/lib/capybara/selector/definition/css.rb +10 -0
  66. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  67. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  68. data/lib/capybara/selector/definition/element.rb +28 -0
  69. data/lib/capybara/selector/definition/field.rb +40 -0
  70. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  71. data/lib/capybara/selector/definition/file_field.rb +13 -0
  72. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  73. data/lib/capybara/selector/definition/frame.rb +17 -0
  74. data/lib/capybara/selector/definition/id.rb +6 -0
  75. data/lib/capybara/selector/definition/label.rb +62 -0
  76. data/lib/capybara/selector/definition/link.rb +54 -0
  77. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  78. data/lib/capybara/selector/definition/option.rb +27 -0
  79. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  80. data/lib/capybara/selector/definition/select.rb +81 -0
  81. data/lib/capybara/selector/definition/table.rb +109 -0
  82. data/lib/capybara/selector/definition/table_row.rb +21 -0
  83. data/lib/capybara/selector/definition/xpath.rb +5 -0
  84. data/lib/capybara/selector/definition.rb +278 -0
  85. data/lib/capybara/selector/filter.rb +3 -46
  86. data/lib/capybara/selector/filter_set.rb +124 -0
  87. data/lib/capybara/selector/filters/base.rb +77 -0
  88. data/lib/capybara/selector/filters/expression_filter.rb +22 -0
  89. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  90. data/lib/capybara/selector/filters/node_filter.rb +31 -0
  91. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  92. data/lib/capybara/selector/selector.rb +155 -0
  93. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  94. data/lib/capybara/selector.rb +232 -369
  95. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  96. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  98. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  99. data/lib/capybara/selenium/driver.rb +380 -142
  100. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
  101. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
  102. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
  103. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  104. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  105. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  106. data/lib/capybara/selenium/extensions/find.rb +110 -0
  107. data/lib/capybara/selenium/extensions/html5_drag.rb +228 -0
  108. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  109. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  110. data/lib/capybara/selenium/logger_suppressor.rb +40 -0
  111. data/lib/capybara/selenium/node.rb +528 -97
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +104 -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/action_pauser.rb +26 -0
  118. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  119. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  120. data/lib/capybara/selenium/patches/logs.rb +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 +63 -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 +74 -71
  127. data/lib/capybara/session/config.rb +126 -0
  128. data/lib/capybara/session/matchers.rb +44 -27
  129. data/lib/capybara/session.rb +500 -297
  130. data/lib/capybara/spec/fixtures/no_extension +1 -0
  131. data/lib/capybara/spec/public/jquery.js +5 -5
  132. data/lib/capybara/spec/public/offset.js +6 -0
  133. data/lib/capybara/spec/public/test.js +168 -14
  134. data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
  135. data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
  136. data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
  137. data/lib/capybara/spec/session/all_spec.rb +179 -59
  138. data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
  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_spec.rb +93 -0
  145. data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
  146. data/lib/capybara/spec/session/body_spec.rb +12 -13
  147. data/lib/capybara/spec/session/check_spec.rb +168 -41
  148. data/lib/capybara/spec/session/choose_spec.rb +75 -23
  149. data/lib/capybara/spec/session/click_button_spec.rb +243 -175
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
  151. data/lib/capybara/spec/session/click_link_spec.rb +100 -53
  152. data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
  153. data/lib/capybara/spec/session/current_url_spec.rb +61 -35
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
  162. data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
  163. data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
  164. data/lib/capybara/spec/session/find_button_spec.rb +37 -18
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
  166. data/lib/capybara/spec/session/find_field_spec.rb +57 -34
  167. data/lib/capybara/spec/session/find_link_spec.rb +47 -10
  168. data/lib/capybara/spec/session/find_spec.rb +290 -144
  169. data/lib/capybara/spec/session/first_spec.rb +91 -48
  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 +116 -0
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
  174. data/lib/capybara/spec/session/go_back_spec.rb +3 -2
  175. data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +76 -19
  180. data/lib/capybara/spec/session/has_css_spec.rb +277 -131
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
  182. data/lib/capybara/spec/session/has_field_spec.rb +177 -107
  183. data/lib/capybara/spec/session/has_link_spec.rb +13 -12
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
  185. data/lib/capybara/spec/session/has_select_spec.rb +191 -95
  186. data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +172 -5
  189. data/lib/capybara/spec/session/has_text_spec.rb +126 -60
  190. data/lib/capybara/spec/session/has_title_spec.rb +35 -12
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
  192. data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
  193. data/lib/capybara/spec/session/html_spec.rb +14 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  195. data/lib/capybara/spec/session/node_spec.rb +1028 -131
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  197. data/lib/capybara/spec/session/refresh_spec.rb +34 -0
  198. data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
  199. data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +11 -15
  202. data/lib/capybara/spec/session/save_page_spec.rb +42 -55
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  206. data/lib/capybara/spec/session/select_spec.rb +112 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +71 -8
  208. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  209. data/lib/capybara/spec/session/text_spec.rb +38 -23
  210. data/lib/capybara/spec/session/title_spec.rb +17 -5
  211. data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
  212. data/lib/capybara/spec/session/unselect_spec.rb +44 -43
  213. data/lib/capybara/spec/session/visit_spec.rb +99 -32
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
  216. data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
  217. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +39 -30
  218. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
  219. data/lib/capybara/spec/session/window/window_spec.rb +121 -73
  220. data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
  221. data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
  222. data/lib/capybara/spec/session/within_spec.rb +76 -43
  223. data/lib/capybara/spec/spec_helper.rb +67 -33
  224. data/lib/capybara/spec/test_app.rb +85 -36
  225. data/lib/capybara/spec/views/animated.erb +49 -0
  226. data/lib/capybara/spec/views/buttons.erb +1 -1
  227. data/lib/capybara/spec/views/fieldsets.erb +1 -1
  228. data/lib/capybara/spec/views/form.erb +227 -20
  229. data/lib/capybara/spec/views/frame_child.erb +10 -2
  230. data/lib/capybara/spec/views/frame_one.erb +2 -1
  231. data/lib/capybara/spec/views/frame_parent.erb +2 -2
  232. data/lib/capybara/spec/views/frame_two.erb +1 -1
  233. data/lib/capybara/spec/views/header_links.erb +1 -1
  234. data/lib/capybara/spec/views/host_links.erb +1 -1
  235. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  236. data/lib/capybara/spec/views/obscured.erb +47 -0
  237. data/lib/capybara/spec/views/offset.erb +32 -0
  238. data/lib/capybara/spec/views/path.erb +1 -1
  239. data/lib/capybara/spec/views/popup_one.erb +1 -1
  240. data/lib/capybara/spec/views/popup_two.erb +1 -1
  241. data/lib/capybara/spec/views/postback.erb +1 -1
  242. data/lib/capybara/spec/views/react.erb +45 -0
  243. data/lib/capybara/spec/views/scroll.erb +20 -0
  244. data/lib/capybara/spec/views/spatial.erb +31 -0
  245. data/lib/capybara/spec/views/tables.erb +69 -2
  246. data/lib/capybara/spec/views/with_animation.erb +82 -0
  247. data/lib/capybara/spec/views/with_base_tag.erb +1 -1
  248. data/lib/capybara/spec/views/with_count.erb +1 -1
  249. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  250. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  251. data/lib/capybara/spec/views/with_hover.erb +7 -1
  252. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  253. data/lib/capybara/spec/views/with_html.erb +100 -10
  254. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  255. data/lib/capybara/spec/views/with_html_entities.erb +1 -1
  256. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  257. data/lib/capybara/spec/views/with_js.erb +49 -3
  258. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  259. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  260. data/lib/capybara/spec/views/with_scope.erb +1 -1
  261. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  262. data/lib/capybara/spec/views/with_simple_html.erb +1 -1
  263. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  264. data/lib/capybara/spec/views/with_title.erb +1 -1
  265. data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
  266. data/lib/capybara/spec/views/with_windows.erb +7 -1
  267. data/lib/capybara/spec/views/within_frames.erb +6 -3
  268. data/lib/capybara/version.rb +2 -1
  269. data/lib/capybara/window.rb +39 -21
  270. data/lib/capybara.rb +208 -186
  271. data/spec/basic_node_spec.rb +52 -39
  272. data/spec/capybara_spec.rb +72 -50
  273. data/spec/css_builder_spec.rb +101 -0
  274. data/spec/css_splitter_spec.rb +38 -0
  275. data/spec/dsl_spec.rb +81 -61
  276. data/spec/filter_set_spec.rb +46 -0
  277. data/spec/fixtures/capybara.csv +1 -0
  278. data/spec/fixtures/certificate.pem +25 -0
  279. data/spec/fixtures/key.pem +27 -0
  280. data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
  281. data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
  282. data/spec/minitest_spec.rb +164 -0
  283. data/spec/minitest_spec_spec.rb +162 -0
  284. data/spec/per_session_config_spec.rb +68 -0
  285. data/spec/rack_test_spec.rb +189 -96
  286. data/spec/regexp_dissassembler_spec.rb +250 -0
  287. data/spec/result_spec.rb +143 -13
  288. data/spec/rspec/features_spec.rb +38 -32
  289. data/spec/rspec/scenarios_spec.rb +9 -7
  290. data/spec/rspec/shared_spec_matchers.rb +959 -0
  291. data/spec/rspec/views_spec.rb +9 -3
  292. data/spec/rspec_matchers_spec.rb +62 -0
  293. data/spec/rspec_spec.rb +127 -30
  294. data/spec/sauce_spec_chrome.rb +43 -0
  295. data/spec/selector_spec.rb +458 -37
  296. data/spec/selenium_spec_chrome.rb +196 -9
  297. data/spec/selenium_spec_chrome_remote.rb +100 -0
  298. data/spec/selenium_spec_edge.rb +47 -0
  299. data/spec/selenium_spec_firefox.rb +210 -0
  300. data/spec/selenium_spec_firefox_remote.rb +80 -0
  301. data/spec/selenium_spec_ie.rb +150 -0
  302. data/spec/selenium_spec_safari.rb +148 -0
  303. data/spec/server_spec.rb +200 -101
  304. data/spec/session_spec.rb +91 -0
  305. data/spec/shared_selenium_node.rb +83 -0
  306. data/spec/shared_selenium_session.rb +558 -0
  307. data/spec/spec_helper.rb +94 -2
  308. data/spec/xpath_builder_spec.rb +93 -0
  309. metadata +420 -60
  310. data/lib/capybara/query.rb +0 -7
  311. data/lib/capybara/spec/session/assert_current_path.rb +0 -60
  312. data/lib/capybara/spec/session/assert_selector.rb +0 -148
  313. data/lib/capybara/spec/session/assert_text.rb +0 -196
  314. data/lib/capybara/spec/session/assert_title.rb +0 -70
  315. data/lib/capybara/spec/session/source_spec.rb +0 -0
  316. data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
  317. data/spec/rspec/matchers_spec.rb +0 -827
  318. data/spec/selenium_spec.rb +0 -151
@@ -1,53 +1,55 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
3
- let(:alternative_path) { File.join(Dir.pwd, "save_screenshot_tmp") }
4
+ let(:alternative_path) { File.join(Dir.pwd, 'save_screenshot_tmp') }
4
5
  before do
6
+ @old_save_path = Capybara.save_path
7
+ Capybara.save_path = nil
5
8
  @session.visit '/foo'
6
9
  end
7
10
 
8
11
  after do
9
- Capybara.save_and_open_page_path = nil
10
- Capybara.save_path = nil
12
+ Capybara.save_path = @old_save_path
11
13
  FileUtils.rm_rf alternative_path
12
14
  end
13
15
 
14
- it "generates sensible filename" do
16
+ it 'generates sensible filename' do
15
17
  allow(@session.driver).to receive(:save_screenshot)
16
18
 
17
19
  @session.save_screenshot
18
20
 
19
- regexp = Regexp.new(File.expand_path('capybara-\d+\.png'))
20
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
21
+ regexp = Regexp.new(File.join(Dir.pwd, 'capybara-\d+\.png'))
22
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
21
23
  end
22
24
 
23
- it "allows to specify another path" do
25
+ it 'allows to specify another path' do
24
26
  allow(@session.driver).to receive(:save_screenshot)
25
27
 
26
28
  custom_path = 'screenshots/1.png'
27
29
  @session.save_screenshot(custom_path)
28
30
 
29
- expect(@session.driver).to have_received(:save_screenshot).with(/#{custom_path}$/, {})
31
+ expect(@session.driver).to have_received(:save_screenshot).with(/#{custom_path}$/, any_args)
30
32
  end
31
33
 
32
- context "with Capybara.save_path" do
33
- it "file is generated in the correct location" do
34
+ context 'with Capybara.save_path' do
35
+ it 'file is generated in the correct location' do
34
36
  Capybara.save_path = alternative_path
35
37
  allow(@session.driver).to receive(:save_screenshot)
36
38
 
37
39
  @session.save_screenshot
38
40
 
39
- regexp = Regexp.new(File.expand_path('capybara-\d+\.png', alternative_path))
40
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
41
+ regexp = Regexp.new(File.join(alternative_path, 'capybara-\d+\.png'))
42
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
41
43
  end
42
44
 
43
- it "relative paths are relative to save_path" do
45
+ it 'relative paths are relative to save_path' do
44
46
  Capybara.save_path = alternative_path
45
47
  allow(@session.driver).to receive(:save_screenshot)
46
48
 
47
49
  custom_path = 'screenshots/2.png'
48
50
  @session.save_screenshot(custom_path)
49
51
 
50
- expect(@session.driver).to have_received(:save_screenshot).with(File.expand_path(custom_path, alternative_path), {})
52
+ expect(@session.driver).to have_received(:save_screenshot).with(File.expand_path(custom_path, alternative_path), any_args)
51
53
  end
52
54
  end
53
55
  end
@@ -1,14 +1,14 @@
1
1
  # coding: US-ASCII
2
2
  # frozen_string_literal: true
3
3
 
4
- Capybara::SpecHelper.spec "#save_screenshot" do
4
+ Capybara::SpecHelper.spec '#save_screenshot' do
5
5
  let(:image_path) { File.join(Dir.tmpdir, 'capybara-screenshot.png') }
6
6
 
7
7
  before do
8
8
  @session.visit '/'
9
9
  end
10
10
 
11
- it "should generate PNG file", :requires => [:screenshot] do
11
+ it 'should generate PNG file', requires: [:screenshot] do
12
12
  path = @session.save_screenshot image_path
13
13
 
14
14
  magic = File.read(image_path, 4)
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
4
+ before do
5
+ @session.visit('/scroll')
6
+ end
7
+
8
+ it 'can scroll an element to the top of the viewport' do
9
+ el = @session.find(:css, '#scroll')
10
+ @session.scroll_to(el, align: :top)
11
+ expect(el.evaluate_script('this.getBoundingClientRect().top')).to be_within(1).of(0)
12
+ end
13
+
14
+ it 'can scroll an element to the bottom of the viewport' do
15
+ el = @session.find(:css, '#scroll')
16
+ @session.scroll_to(el, align: :bottom)
17
+ el_bottom = el.evaluate_script('this.getBoundingClientRect().bottom')
18
+ viewport_bottom = el.evaluate_script('document.body.clientHeight')
19
+ expect(el_bottom).to be_within(1).of(viewport_bottom)
20
+ end
21
+
22
+ it 'can scroll an element to the center of the viewport' do
23
+ el = @session.find(:css, '#scroll')
24
+ @session.scroll_to(el, align: :center)
25
+ el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
26
+ viewport_bottom = el.evaluate_script('document.body.clientHeight')
27
+ expect(el_center).to be_within(2).of(viewport_bottom / 2)
28
+ end
29
+
30
+ it 'can scroll the window to the vertical top' do
31
+ @session.scroll_to :bottom
32
+ @session.scroll_to :top
33
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, 0]
34
+ end
35
+
36
+ it 'can scroll the window to the vertical bottom' do
37
+ @session.scroll_to :bottom
38
+ max_scroll = @session.evaluate_script('document.body.scrollHeight - document.body.clientHeight')
39
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll]
40
+ end
41
+
42
+ it 'can scroll the window to the vertical center' do
43
+ @session.scroll_to :center
44
+ max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.body.clientHeight')
45
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll / 2]
46
+ end
47
+
48
+ it 'can scroll the window to specific location' do
49
+ @session.scroll_to 100, 100
50
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [100, 100]
51
+ end
52
+
53
+ it 'can scroll an element to the top of the scrolling element' do
54
+ scrolling_element = @session.find(:css, '#scrollable')
55
+ el = scrolling_element.find(:css, '#inner')
56
+ scrolling_element.scroll_to(el, align: :top)
57
+ scrolling_element_top = scrolling_element.evaluate_script('this.getBoundingClientRect().top')
58
+ expect(el.evaluate_script('this.getBoundingClientRect().top')).to be_within(3).of(scrolling_element_top)
59
+ end
60
+
61
+ it 'can scroll an element to the bottom of the scrolling element' do
62
+ scrolling_element = @session.find(:css, '#scrollable')
63
+ el = scrolling_element.find(:css, '#inner')
64
+ scrolling_element.scroll_to(el, align: :bottom)
65
+ el_bottom = el.evaluate_script('this.getBoundingClientRect().bottom')
66
+ scroller_bottom = scrolling_element.evaluate_script('this.getBoundingClientRect().top + this.clientHeight')
67
+ expect(el_bottom).to be_within(1).of(scroller_bottom)
68
+ end
69
+
70
+ it 'can scroll an element to the center of the scrolling element' do
71
+ scrolling_element = @session.find(:css, '#scrollable')
72
+ el = scrolling_element.find(:css, '#inner')
73
+ scrolling_element.scroll_to(el, align: :center)
74
+ el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
75
+ scrollable_center = scrolling_element.evaluate_script('(this.clientHeight / 2) + this.getBoundingClientRect().top')
76
+ expect(el_center).to be_within(1).of(scrollable_center)
77
+ end
78
+
79
+ it 'can scroll the scrolling element to the top' do
80
+ scrolling_element = @session.find(:css, '#scrollable')
81
+ scrolling_element.scroll_to :bottom
82
+ scrolling_element.scroll_to :top
83
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, 0]
84
+ end
85
+
86
+ it 'can scroll the scrolling element to the bottom' do
87
+ scrolling_element = @session.find(:css, '#scrollable')
88
+ scrolling_element.scroll_to :bottom
89
+ max_scroll = scrolling_element.evaluate_script('this.scrollHeight - this.clientHeight')
90
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, max_scroll]
91
+ end
92
+
93
+ it 'can scroll the scrolling element to the vertical center' do
94
+ scrolling_element = @session.find(:css, '#scrollable')
95
+ scrolling_element.scroll_to :center
96
+ max_scroll = scrolling_element.evaluate_script('this.scrollHeight - this.clientHeight')
97
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, max_scroll / 2]
98
+ end
99
+
100
+ it 'can scroll the scrolling element to specific location' do
101
+ scrolling_element = @session.find(:css, '#scrollable')
102
+ scrolling_element.scroll_to 100, 100
103
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [100, 100]
104
+ end
105
+
106
+ it 'can scroll the window by a specific amount' do
107
+ @session.scroll_to(:current, offset: [50, 75])
108
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [50, 75]
109
+ end
110
+
111
+ it 'can scroll the scroll the scrolling element by a specific amount' do
112
+ scrolling_element = @session.find(:css, '#scrollable')
113
+ scrolling_element.scroll_to 100, 100
114
+ scrolling_element.scroll_to(:current, offset: [-50, 50])
115
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [50, 150]
116
+ end
117
+ end
@@ -1,202 +1,229 @@
1
1
  # frozen_string_literal: true
2
- Capybara::SpecHelper.spec "#select" do
2
+
3
+ Capybara::SpecHelper.spec '#select' do
3
4
  before do
4
5
  @session.visit('/form')
5
6
  end
6
7
 
7
- it "should return value of the first option" do
8
+ it 'should return value of the first option' do
8
9
  expect(@session.find_field('Title').value).to eq('Mrs')
9
10
  end
10
11
 
11
- it "should return value of the selected option" do
12
- @session.select("Miss", :from => 'Title')
12
+ it 'should return value of the selected option' do
13
+ @session.select('Miss', from: 'Title')
13
14
  expect(@session.find_field('Title').value).to eq('Miss')
14
15
  end
15
16
 
16
- it "should allow selecting options where there are inexact matches" do
17
- @session.select("Mr", :from => 'Title')
17
+ it 'should allow selecting exact options where there are inexact matches', :exact_false do
18
+ @session.select('Mr', from: 'Title')
18
19
  expect(@session.find_field('Title').value).to eq('Mr')
19
20
  end
20
21
 
21
- it "should allow selecting options where they are the only inexact match" do
22
- @session.select("Mis", :from => 'Title')
22
+ it 'should allow selecting options where they are the only inexact match', :exact_false do
23
+ @session.select('Mis', from: 'Title')
23
24
  expect(@session.find_field('Title').value).to eq('Miss')
24
25
  end
25
26
 
26
- it "should not allow selecting options where they are the only inexact match if `Capybara.exact_options = true`" do
27
- Capybara.exact_options = true
27
+ it 'should not allow selecting options where they are the only inexact match if `exact: true` is specified' do
28
+ sel = @session.find(:select, 'Title')
28
29
  expect do
29
- @session.select("Mis", :from => 'Title')
30
+ sel.select('Mis', exact: true)
30
31
  end.to raise_error(Capybara::ElementNotFound)
31
32
  end
32
33
 
33
- it "should not allow selecting an option if the match is ambiguous" do
34
+ it 'should not allow selecting an option if the match is ambiguous', :exact_false do
34
35
  expect do
35
- @session.select("M", :from => 'Title')
36
+ @session.select('M', from: 'Title')
36
37
  end.to raise_error(Capybara::Ambiguous)
37
38
  end
38
39
 
39
- it "should return the value attribute rather than content if present" do
40
+ it 'should return the value attribute rather than content if present' do
40
41
  expect(@session.find_field('Locale').value).to eq('en')
41
42
  end
42
43
 
43
- it "should select an option from a select box by id" do
44
- @session.select("Finish", :from => 'form_locale')
44
+ it 'should select an option from a select box by id' do
45
+ @session.select('Finnish', from: 'form_locale')
45
46
  @session.click_button('awesome')
46
47
  expect(extract_results(@session)['locale']).to eq('fi')
47
48
  end
48
49
 
49
- it "should select an option from a select box by label" do
50
- @session.select("Finish", :from => 'Locale')
50
+ it 'should select an option from a select box by label' do
51
+ @session.select('Finnish', from: 'Locale')
51
52
  @session.click_button('awesome')
52
53
  expect(extract_results(@session)['locale']).to eq('fi')
53
54
  end
54
55
 
55
- it "should select an option without giving a select box" do
56
- @session.select("Swedish")
56
+ it 'should select an option without giving a select box' do
57
+ @session.select('Swedish')
57
58
  @session.click_button('awesome')
58
59
  expect(extract_results(@session)['locale']).to eq('sv')
59
60
  end
60
61
 
61
- it "should escape quotes" do
62
- @session.select("John's made-up language", :from => 'Locale')
62
+ it 'should escape quotes' do
63
+ @session.select("John's made-up language", from: 'Locale')
63
64
  @session.click_button('awesome')
64
65
  expect(extract_results(@session)['locale']).to eq('jo')
65
66
  end
66
67
 
67
- it "should obey from" do
68
- @session.select("Miss", :from => "Other title")
68
+ it 'should obey from' do
69
+ @session.select('Miss', from: 'Other title')
69
70
  @session.click_button('awesome')
70
71
  results = extract_results(@session)
71
- expect(results['other_title']).to eq("Miss")
72
- expect(results['title']).not_to eq("Miss")
72
+ expect(results['other_title']).to eq('Miss')
73
+ expect(results['title']).not_to eq('Miss')
73
74
  end
74
75
 
75
- it "show match labels with preceding or trailing whitespace" do
76
- @session.select("Lojban", :from => 'Locale')
76
+ it 'show match labels with preceding or trailing whitespace' do
77
+ @session.select('Lojban', from: 'Locale')
77
78
  @session.click_button('awesome')
78
79
  expect(extract_results(@session)['locale']).to eq('jbo')
79
80
  end
80
81
 
81
- it "casts to string" do
82
- @session.select(:"Miss", :from => :'Title')
82
+ it 'casts to string' do
83
+ @session.select(:Miss, from: :Title)
83
84
  expect(@session.find_field('Title').value).to eq('Miss')
84
85
  end
85
86
 
87
+ context 'input with datalist' do
88
+ it 'should select an option' do
89
+ @session.select('Audi', from: 'manufacturer')
90
+ @session.click_button('awesome')
91
+ expect(extract_results(@session)['manufacturer']).to eq('Audi')
92
+ end
93
+
94
+ it 'should not find an input without a datalist' do
95
+ expect do
96
+ @session.select('Thomas', from: 'form_first_name')
97
+ end.to raise_error(/Unable to find input box with datalist completion "form_first_name"/)
98
+ end
99
+
100
+ it "should not select an option that doesn't exist" do
101
+ expect do
102
+ @session.select('Tata', from: 'manufacturer')
103
+ end.to raise_error(/Unable to find datalist option "Tata"/)
104
+ end
105
+
106
+ it 'should not select a disabled option' do
107
+ expect do
108
+ @session.select('Mercedes', from: 'manufacturer')
109
+ end.to raise_error(/Unable to find datalist option "Mercedes"/)
110
+ end
111
+ end
112
+
86
113
  context "with a locator that doesn't exist" do
87
- it "should raise an error" do
88
- msg = "Unable to find select box \"does not exist\""
114
+ it 'should raise an error' do
115
+ msg = /Unable to find select box "does not exist"/
89
116
  expect do
90
- @session.select('foo', :from => 'does not exist')
117
+ @session.select('foo', from: 'does not exist')
91
118
  end.to raise_error(Capybara::ElementNotFound, msg)
92
119
  end
93
120
  end
94
121
 
95
122
  context "with an option that doesn't exist" do
96
- it "should raise an error" do
97
- msg = "Unable to find option \"Does not Exist\""
123
+ it 'should raise an error' do
124
+ msg = /^Unable to find option "Does not Exist" within/
98
125
  expect do
99
- @session.select('Does not Exist', :from => 'form_locale')
126
+ @session.select('Does not Exist', from: 'form_locale')
100
127
  end.to raise_error(Capybara::ElementNotFound, msg)
101
128
  end
102
129
  end
103
130
 
104
- context "on a disabled select" do
105
- it "should raise an error" do
131
+ context 'on a disabled select' do
132
+ it 'should raise an error' do
106
133
  expect do
107
- @session.select('Should not see me', :from => 'Disabled Select')
134
+ @session.select('Should not see me', from: 'Disabled Select')
108
135
  end.to raise_error(Capybara::ElementNotFound)
109
136
  end
110
137
  end
111
138
 
112
- context "on a disabled option" do
113
- it "should not select" do
114
- @session.select('Other', :from => 'form_title')
139
+ context 'on a disabled option' do
140
+ it 'should not select' do
141
+ @session.select('Other', from: 'form_title')
115
142
  expect(@session.find_field('form_title').value).not_to eq 'Other'
116
143
  end
117
-
118
- it "should warn" do
119
- expect_any_instance_of(Capybara::Node::Element).to receive(:warn).once
120
- @session.select('Other', :from => 'form_title')
121
- end
122
144
  end
123
145
 
124
- context "with multiple select" do
125
- it "should return an empty value" do
126
- expect(@session.find_field('Language').value).to eq([])
146
+ context 'with multiple select' do
147
+ it 'should return an empty value' do
148
+ expect(@session.find_field('Languages').value).to eq([])
127
149
  end
128
150
 
129
- it "should return value of the selected options" do
130
- @session.select("Ruby", :from => 'Language')
131
- @session.select("Javascript", :from => 'Language')
132
- expect(@session.find_field('Language').value).to include('Ruby', 'Javascript')
151
+ it 'should return value of the selected options' do
152
+ @session.select('Ruby', from: 'Languages')
153
+ @session.select('Javascript', from: 'Languages')
154
+ expect(@session.find_field('Languages').value).to include('Ruby', 'Javascript')
133
155
  end
134
156
 
135
- it "should select one option" do
136
- @session.select("Ruby", :from => 'Language')
157
+ it 'should select one option' do
158
+ @session.select('Ruby', from: 'Languages')
137
159
  @session.click_button('awesome')
138
160
  expect(extract_results(@session)['languages']).to eq(['Ruby'])
139
161
  end
140
162
 
141
- it "should select multiple options" do
142
- @session.select("Ruby", :from => 'Language')
143
- @session.select("Javascript", :from => 'Language')
163
+ it 'should select multiple options' do
164
+ @session.select('Ruby', from: 'Languages')
165
+ @session.select('Javascript', from: 'Languages')
144
166
  @session.click_button('awesome')
145
167
  expect(extract_results(@session)['languages']).to include('Ruby', 'Javascript')
146
168
  end
147
169
 
148
- it "should remain selected if already selected" do
149
- @session.select("Ruby", :from => 'Language')
150
- @session.select("Javascript", :from => 'Language')
151
- @session.select("Ruby", :from => 'Language')
170
+ it 'should remain selected if already selected' do
171
+ @session.select('Ruby', from: 'Languages')
172
+ @session.select('Javascript', from: 'Languages')
173
+ @session.select('Ruby', from: 'Languages')
152
174
  @session.click_button('awesome')
153
175
  expect(extract_results(@session)['languages']).to include('Ruby', 'Javascript')
154
176
  end
155
177
 
156
- it "should return value attribute rather than content if present" do
178
+ it 'should return value attribute rather than content if present' do
157
179
  expect(@session.find_field('Underwear').value).to include('thermal')
158
180
  end
159
181
  end
160
182
 
161
- context "with :exact option" do
162
- context "when `false`" do
163
- it "can match select box approximately" do
164
- @session.select("Finish", :from => "Loc", :exact => false)
165
- @session.click_button("awesome")
166
- expect(extract_results(@session)["locale"]).to eq("fi")
183
+ context 'with :exact option' do
184
+ context 'when `false`' do
185
+ it 'can match select box approximately' do
186
+ @session.select('Finnish', from: 'Loc', exact: false)
187
+ @session.click_button('awesome')
188
+ expect(extract_results(@session)['locale']).to eq('fi')
167
189
  end
168
190
 
169
- it "can match option approximately" do
170
- @session.select("Fin", :from => "Locale", :exact => false)
171
- @session.click_button("awesome")
172
- expect(extract_results(@session)["locale"]).to eq("fi")
191
+ it 'can match option approximately' do
192
+ @session.select('Fin', from: 'Locale', exact: false)
193
+ @session.click_button('awesome')
194
+ expect(extract_results(@session)['locale']).to eq('fi')
173
195
  end
174
196
 
175
- it "can match option approximately when :from not given" do
176
- @session.select("made-up language", :exact => false)
177
- @session.click_button("awesome")
178
- expect(extract_results(@session)["locale"]).to eq("jo")
197
+ it 'can match option approximately when :from not given' do
198
+ @session.select('made-up language', exact: false)
199
+ @session.click_button('awesome')
200
+ expect(extract_results(@session)['locale']).to eq('jo')
179
201
  end
180
202
  end
181
203
 
182
- context "when `true`" do
183
- it "can match select box approximately" do
204
+ context 'when `true`' do
205
+ it 'can match select box approximately' do
184
206
  expect do
185
- @session.select("Finish", :from => "Loc", :exact => true)
207
+ @session.select('Finnish', from: 'Loc', exact: true)
186
208
  end.to raise_error(Capybara::ElementNotFound)
187
209
  end
188
210
 
189
- it "can match option approximately" do
211
+ it 'can match option approximately' do
190
212
  expect do
191
- @session.select("Fin", :from => "Locale", :exact => true)
213
+ @session.select('Fin', from: 'Locale', exact: true)
192
214
  end.to raise_error(Capybara::ElementNotFound)
193
215
  end
194
216
 
195
- it "can match option approximately when :from not given" do
217
+ it 'can match option approximately when :from not given' do
196
218
  expect do
197
- @session.select("made-up language", :exact => true)
219
+ @session.select('made-up language', exact: true)
198
220
  end.to raise_error(Capybara::ElementNotFound)
199
221
  end
200
222
  end
201
223
  end
224
+
225
+ it 'should error when not passed a locator for :from option' do
226
+ select = @session.find(:select, 'Title')
227
+ expect { @session.select('Mr', from: select) }.to raise_error(ArgumentError, /does not take an element/)
228
+ end
202
229
  end