capybara 3.3.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 (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
@@ -5,17 +5,17 @@ class NodeWrapper
5
5
  def to_capybara_node(); @element end
6
6
  end
7
7
 
8
- Capybara::SpecHelper.spec "#to_capybara_node" do
8
+ Capybara::SpecHelper.spec '#to_capybara_node' do
9
9
  before do
10
10
  @session.visit('/with_html')
11
11
  end
12
12
 
13
- it "should support have_xxx expectations" do
13
+ it 'should support have_xxx expectations' do
14
14
  para = NodeWrapper.new(@session.find(:css, '#first'))
15
- expect(para).to have_link("ullamco")
15
+ expect(para).to have_link('ullamco')
16
16
  end
17
17
 
18
- it "should support within" do
18
+ it 'should support within' do
19
19
  para = NodeWrapper.new(@session.find(:css, '#first'))
20
20
  expect(@session).to have_css('#second')
21
21
  @session.within(para) do
@@ -24,13 +24,16 @@ Capybara::SpecHelper.spec "#to_capybara_node" do
24
24
  end
25
25
  end
26
26
 
27
- it "should generate correct errors" do
27
+ it 'should generate correct errors' do
28
28
  para = NodeWrapper.new(@session.find(:css, '#first'))
29
29
  expect do
30
- expect(para).to have_text("Header Class Test One")
30
+ expect(para).to have_text('Header Class Test One')
31
31
  end.to raise_error(/^expected to find text "Header Class Test One" in "Lore/)
32
32
  expect do
33
33
  expect(para).to have_css('#second')
34
- end.to raise_error(/^expected to find visible css "#second" within #<Capybara::Node::Element/)
34
+ end.to raise_error(/^expected to find css "#second" within #<Capybara::Node::Element/)
35
+ expect do
36
+ expect(para).to have_link(href: %r{/without_simple_html})
37
+ end.to raise_error(%r{^expected to find link with href matching /\\/without_simple_html/ within #<Capybara::Node::Element})
35
38
  end
36
39
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # NOTE: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
4
+ # because of the methods being tested. In tests using Capybara this type of behavior should be implemented
5
+ # using Capybara provided assertions with builtin waiting behavior.
6
+
3
7
  Capybara::SpecHelper.spec '#refresh' do
4
- it "reload the page" do
8
+ it 'reload the page' do
5
9
  @session.visit('/form')
6
10
  expect(@session).to have_select('form_locale', selected: 'English')
7
11
  @session.select('Swedish', from: 'form_locale')
@@ -10,20 +14,18 @@ Capybara::SpecHelper.spec '#refresh' do
10
14
  expect(@session).to have_select('form_locale', selected: 'English')
11
15
  end
12
16
 
13
- it "raises any errors caught inside the server", requires: [:server] do
14
- quietly { @session.visit("/error") }
17
+ it 'raises any errors caught inside the server', requires: [:server] do
18
+ quietly { @session.visit('/error') }
15
19
  expect do
16
20
  @session.refresh
17
21
  end.to raise_error(TestApp::TestAppError)
18
22
  end
19
23
 
20
- it "it reposts" do
21
- if marionette?(@session) || edge?(@session) || ie?(@session)
22
- skip "Firefox and Edge insist on prompting without providing a way to suppress"
23
- end
24
+ it 'it reposts' do
24
25
  @session.visit('/form')
25
26
  @session.select('Sweden', from: 'form_region')
26
27
  @session.click_button('awesome')
28
+ sleep 2
27
29
  expect do
28
30
  @session.refresh
29
31
  sleep 2
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara::SpecHelper.spec '#reset_session!' do
4
- it "removes cookies" do
4
+ it 'removes cookies from current domain' do
5
5
  @session.visit('/set_cookie')
6
6
  @session.visit('/get_cookie')
7
7
  expect(@session).to have_content('test_cookie')
@@ -11,7 +11,21 @@ Capybara::SpecHelper.spec '#reset_session!' do
11
11
  expect(@session.body).not_to include('test_cookie')
12
12
  end
13
13
 
14
- it "resets current url, host, path" do
14
+ it 'removes ALL cookies', requires: [:server] do
15
+ domains = ['localhost', '127.0.0.1']
16
+ domains.each do |domain|
17
+ @session.visit("http://#{domain}:#{@session.server.port}/set_cookie")
18
+ @session.visit("http://#{domain}:#{@session.server.port}/get_cookie")
19
+ expect(@session).to have_content('test_cookie')
20
+ end
21
+ @session.reset_session!
22
+ domains.each do |domain|
23
+ @session.visit("http://#{domain}:#{@session.server.port}/get_cookie")
24
+ expect(@session.body).not_to include('test_cookie')
25
+ end
26
+ end
27
+
28
+ it 'resets current url, host, path' do
15
29
  @session.visit '/foo'
16
30
  expect(@session.current_url).not_to be_empty
17
31
  expect(@session.current_host).not_to be_empty
@@ -23,7 +37,7 @@ Capybara::SpecHelper.spec '#reset_session!' do
23
37
  expect(@session.current_host).to be_nil
24
38
  end
25
39
 
26
- it "resets page body" do
40
+ it 'resets page body' do
27
41
  @session.visit('/with_html')
28
42
  expect(@session).to have_content('This is a test')
29
43
  expect(@session.find('.//h1').text).to include('This is a test')
@@ -33,37 +47,37 @@ Capybara::SpecHelper.spec '#reset_session!' do
33
47
  expect(@session).to have_no_selector('.//h1')
34
48
  end
35
49
 
36
- it "is synchronous" do
37
- @session.visit("/with_slow_unload")
50
+ it 'is synchronous' do
51
+ @session.visit('/with_slow_unload')
38
52
  expect(@session).to have_selector(:css, 'div')
39
53
  @session.reset_session!
40
- expect(@session).to have_no_selector :xpath, "/html/body/*", wait: false
54
+ expect(@session).to have_no_selector :xpath, '/html/body/*', wait: false
41
55
  end
42
56
 
43
- it "handles modals during unload", requires: [:modals] do
57
+ it 'handles modals during unload', requires: [:modals] do
44
58
  @session.visit('/with_unload_alert')
45
59
  expect(@session).to have_selector(:css, 'div')
46
60
  expect { @session.reset_session! }.not_to raise_error
47
- expect(@session).to have_no_selector :xpath, "/html/body/*", wait: false
61
+ expect(@session).to have_no_selector :xpath, '/html/body/*', wait: false
48
62
  end
49
63
 
50
- it "handles already open modals", requires: [:modals] do
64
+ it 'handles already open modals', requires: [:modals] do
51
65
  @session.visit('/with_unload_alert')
52
66
  @session.click_link('Go away')
53
67
  expect { @session.reset_session! }.not_to raise_error
54
- expect(@session).to have_no_selector :xpath, "/html/body/*", wait: false
68
+ expect(@session).to have_no_selector :xpath, '/html/body/*', wait: false
55
69
  end
56
70
 
57
- it "raises any standard errors caught inside the server", requires: [:server] do
58
- quietly { @session.visit("/error") }
71
+ it 'raises any standard errors caught inside the server', requires: [:server] do
72
+ quietly { @session.visit('/error') }
59
73
  expect do
60
74
  @session.reset_session!
61
75
  end.to raise_error(TestApp::TestAppError)
62
- @session.visit("/")
63
- expect(@session.current_path).to eq("/")
76
+ @session.visit('/')
77
+ expect(@session.current_path).to eq('/')
64
78
  end
65
79
 
66
- it "closes extra windows", requires: [:windows] do
80
+ it 'closes extra windows', requires: [:windows] do
67
81
  @session.visit('/with_html')
68
82
  @session.open_new_window
69
83
  @session.open_new_window
@@ -72,7 +86,7 @@ Capybara::SpecHelper.spec '#reset_session!' do
72
86
  expect(@session.windows.size).to eq 1
73
87
  end
74
88
 
75
- it "closes extra windows when not on the first window", requires: [:windows] do
89
+ it 'closes extra windows when not on the first window', requires: [:windows] do
76
90
  @session.visit('/with_html')
77
91
  @session.switch_to_window(@session.open_new_window)
78
92
  @session.open_new_window
@@ -81,41 +95,55 @@ Capybara::SpecHelper.spec '#reset_session!' do
81
95
  expect(@session.windows.size).to eq 1
82
96
  end
83
97
 
84
- context "When reuse_server == false" do
98
+ it 'does not block opening a new window after a frame was switched to and not switched back', requires: [:windows] do
99
+ @session.visit('/with_iframe?id=test_iframe&url=/')
100
+ @session.switch_to_frame(@session.find(:frame, 'test_iframe'))
101
+ within_window_test = lambda do
102
+ @session.within_window(@session.open_new_window) do
103
+ @session.visit('/')
104
+ end
105
+ end
106
+ expect(&within_window_test).to raise_error(Capybara::ScopeError)
107
+ @session.reset_session!
108
+ expect(&within_window_test).not_to raise_error
109
+ end
110
+
111
+ context 'When reuse_server == false' do
112
+ let!(:orig_reuse_server) { Capybara.reuse_server }
113
+
85
114
  before do
86
- @reuse_server = Capybara.reuse_server
87
115
  Capybara.reuse_server = false
88
116
  end
89
117
 
90
- it "raises any standard errors caught inside the server during a second session", requires: [:server] do
118
+ after do
119
+ Capybara.reuse_server = orig_reuse_server
120
+ end
121
+
122
+ it 'raises any standard errors caught inside the server during a second session', requires: [:server] do
91
123
  Capybara.using_driver(@session.mode) do
92
124
  Capybara.using_session(:another_session) do
93
- @another_session = Capybara.current_session
94
- quietly { @another_session.visit("/error") }
125
+ another_session = Capybara.current_session
126
+ quietly { another_session.visit('/error') }
95
127
  expect do
96
- @another_session.reset_session!
128
+ another_session.reset_session!
97
129
  end.to raise_error(TestApp::TestAppError)
98
- @another_session.visit("/")
99
- expect(@another_session.current_path).to eq("/")
130
+ another_session.visit('/')
131
+ expect(another_session.current_path).to eq('/')
100
132
  end
101
133
  end
102
134
  end
103
-
104
- after do
105
- Capybara.reuse_server = @reuse_server
106
- end
107
135
  end
108
136
 
109
- it "raises configured errors caught inside the server", requires: [:server] do
137
+ it 'raises configured errors caught inside the server', requires: [:server] do
110
138
  prev_errors = Capybara.server_errors.dup
111
139
 
112
140
  Capybara.server_errors = [LoadError]
113
- quietly { @session.visit("/error") }
141
+ quietly { @session.visit('/error') }
114
142
  expect do
115
143
  @session.reset_session!
116
144
  end.not_to raise_error
117
145
 
118
- quietly { @session.visit("/load_error") }
146
+ quietly { @session.visit('/load_error') }
119
147
  expect do
120
148
  @session.reset_session!
121
149
  end.to raise_error(LoadError)
@@ -123,11 +151,11 @@ Capybara::SpecHelper.spec '#reset_session!' do
123
151
  Capybara.server_errors = prev_errors
124
152
  end
125
153
 
126
- it "ignores server errors when `Capybara.raise_server_errors = false`", requires: [:server] do
154
+ it 'ignores server errors when `Capybara.raise_server_errors = false`', requires: [:server] do
127
155
  Capybara.raise_server_errors = false
128
- quietly { @session.visit("/error") }
156
+ quietly { @session.visit('/error') }
129
157
  @session.reset_session!
130
- @session.visit("/")
131
- expect(@session.current_path).to eq("/")
158
+ @session.visit('/')
159
+ expect(@session.current_path).to eq('/')
132
160
  end
133
161
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara::SpecHelper.spec '#status_code' do
4
- it "should return response codes", requires: [:status_code] do
4
+ it 'should return response codes', requires: [:status_code] do
5
5
  @session.visit('/with_simple_html')
6
6
  expect(@session.status_code).to eq(200)
7
7
  end
@@ -8,12 +8,12 @@ Capybara::SpecHelper.spec '#save_and_open_page' do
8
8
  end
9
9
 
10
10
  after do
11
- Dir.glob("capybara-*.html").each do |file|
11
+ Dir.glob('capybara-*.html').each do |file|
12
12
  FileUtils.rm(file)
13
13
  end
14
14
  end
15
15
 
16
- it "sends open method to launchy" do
16
+ it 'sends open method to launchy' do
17
17
  allow(Launchy).to receive(:open)
18
18
  @session.save_and_open_page
19
19
  expect(Launchy).to have_received(:open).with(/capybara-\d+\.html/)
@@ -15,7 +15,7 @@ Capybara::SpecHelper.spec '#save_and_open_screenshot' do
15
15
  @session.save_and_open_screenshot
16
16
 
17
17
  expect(@session.driver).to have_received(:save_screenshot)
18
- .with(expected_file_regex, {})
18
+ .with(expected_file_regex, any_args)
19
19
  expect(Launchy).to have_received(:open).with(expected_file_regex)
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ Capybara::SpecHelper.spec '#save_and_open_screenshot' do
27
27
  @session.save_and_open_screenshot(custom_path)
28
28
 
29
29
  expect(@session.driver).to have_received(:save_screenshot)
30
- .with(/#{custom_path}$/, {})
30
+ .with(/#{custom_path}$/, any_args)
31
31
  expect(Launchy).to have_received(:open).with(/#{custom_path}$/)
32
32
  end
33
33
 
@@ -1,79 +1,79 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara::SpecHelper.spec '#save_page' do
4
- let(:alternative_path) { File.join(Dir.pwd, "save_and_open_page_tmp") }
4
+ let(:alternative_path) { File.join(Dir.pwd, 'save_and_open_page_tmp') }
5
5
  before do
6
6
  @old_save_path = Capybara.save_path
7
7
  Capybara.save_path = nil
8
- @session.visit("/foo")
8
+ @session.visit('/foo')
9
9
  end
10
10
 
11
11
  after do
12
12
  Capybara.save_path = @old_save_path
13
- Dir.glob("capybara-*.html").each do |file|
13
+ Dir.glob('capybara-*.html').each do |file|
14
14
  FileUtils.rm(file)
15
15
  end
16
16
  FileUtils.rm_rf alternative_path
17
17
  end
18
18
 
19
- it "saves the page in the root directory" do
19
+ it 'saves the page in the root directory' do
20
20
  @session.save_page
21
- path = Dir.glob("capybara-*.html").first
22
- expect(File.read(path)).to include("Another World")
21
+ path = Dir.glob('capybara-*.html').first
22
+ expect(File.read(path)).to include('Another World')
23
23
  end
24
24
 
25
- it "generates a sensible filename" do
25
+ it 'generates a sensible filename' do
26
26
  @session.save_page
27
- filename = Dir.glob("capybara-*.html").first
27
+ filename = Dir.glob('capybara-*.html').first
28
28
  expect(filename).to match(/^capybara-\d+\.html$/)
29
29
  end
30
30
 
31
- it "can store files in a specified directory" do
31
+ it 'can store files in a specified directory' do
32
32
  Capybara.save_path = alternative_path
33
33
  @session.save_page
34
- path = Dir.glob(alternative_path + "/capybara-*.html").first
35
- expect(File.read(path)).to include("Another World")
34
+ path = Dir.glob("#{alternative_path}/capybara-*.html").first
35
+ expect(File.read(path)).to include('Another World')
36
36
  end
37
37
 
38
- it "uses the given filename" do
39
- @session.save_page("capybara-001122.html")
40
- expect(File.read("capybara-001122.html")).to include("Another World")
38
+ it 'uses the given filename' do
39
+ @session.save_page('capybara-001122.html')
40
+ expect(File.read('capybara-001122.html')).to include('Another World')
41
41
  end
42
42
 
43
- it "can store files in a specified directory with a given filename" do
43
+ it 'can store files in a specified directory with a given filename' do
44
44
  Capybara.save_path = alternative_path
45
- @session.save_page("capybara-001133.html")
46
- path = alternative_path + "/capybara-001133.html"
47
- expect(File.read(path)).to include("Another World")
45
+ @session.save_page('capybara-001133.html')
46
+ path = "#{alternative_path}/capybara-001133.html"
47
+ expect(File.read(path)).to include('Another World')
48
48
  end
49
49
 
50
- it "can store files in a specified directory with a given relative filename" do
50
+ it 'can store files in a specified directory with a given relative filename' do
51
51
  Capybara.save_path = alternative_path
52
- @session.save_page("tmp/capybara-001144.html")
53
- path = alternative_path + "/tmp/capybara-001144.html"
54
- expect(File.read(path)).to include("Another World")
52
+ @session.save_page('tmp/capybara-001144.html')
53
+ path = "#{alternative_path}/tmp/capybara-001144.html"
54
+ expect(File.read(path)).to include('Another World')
55
55
  end
56
56
 
57
- it "returns an absolute path in pwd" do
57
+ it 'returns an absolute path in pwd' do
58
58
  result = @session.save_page
59
- path = File.expand_path(Dir.glob("capybara-*.html").first, Dir.pwd)
59
+ path = File.expand_path(Dir.glob('capybara-*.html').first, Dir.pwd)
60
60
  expect(result).to eq(path)
61
61
  end
62
62
 
63
- it "returns an absolute path in given directory" do
63
+ it 'returns an absolute path in given directory' do
64
64
  Capybara.save_path = alternative_path
65
65
  result = @session.save_page
66
- path = File.expand_path(Dir.glob(alternative_path + "/capybara-*.html").first, alternative_path)
66
+ path = File.expand_path(Dir.glob("#{alternative_path}/capybara-*.html").first, alternative_path)
67
67
  expect(result).to eq(path)
68
68
  end
69
69
 
70
- context "asset_host contains a string" do
71
- before { Capybara.asset_host = "http://example.com" }
70
+ context 'asset_host contains a string' do
71
+ before { Capybara.asset_host = 'http://example.com' }
72
72
 
73
73
  after { Capybara.asset_host = nil }
74
74
 
75
- it "prepends base tag with value from asset_host to the head" do
76
- @session.visit("/with_js")
75
+ it 'prepends base tag with value from asset_host to the head' do
76
+ @session.visit('/with_js')
77
77
  path = @session.save_page
78
78
 
79
79
  result = File.read(path)
@@ -82,29 +82,29 @@ Capybara::SpecHelper.spec '#save_page' do
82
82
 
83
83
  it "doesn't prepend base tag to pages when asset_host is nil" do
84
84
  Capybara.asset_host = nil
85
- @session.visit("/with_js")
85
+ @session.visit('/with_js')
86
86
  path = @session.save_page
87
87
 
88
88
  result = File.read(path)
89
89
  expect(result).to include('<html')
90
- expect(result).not_to include("http://example.com")
90
+ expect(result).not_to include('http://example.com')
91
91
  end
92
92
 
93
93
  it "doesn't prepend base tag to pages which already have it" do
94
- @session.visit("/with_base_tag")
94
+ @session.visit('/with_base_tag')
95
95
  path = @session.save_page
96
96
 
97
97
  result = File.read(path)
98
98
  expect(result).to include('<html')
99
- expect(result).not_to include("http://example.com")
99
+ expect(result).not_to include('http://example.com')
100
100
  end
101
101
 
102
- it "executes successfully even if the page is missing a <head>" do
103
- @session.visit("/with_simple_html")
102
+ it 'executes successfully even if the page is missing a <head>' do
103
+ @session.visit('/with_simple_html')
104
104
  path = @session.save_page
105
105
 
106
106
  result = File.read(path)
107
- expect(result).to include("Bar")
107
+ expect(result).to include('Bar')
108
108
  end
109
109
  end
110
110
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
4
- let(:alternative_path) { File.join(Dir.pwd, "save_screenshot_tmp") }
4
+ let(:alternative_path) { File.join(Dir.pwd, 'save_screenshot_tmp') }
5
5
  before do
6
6
  @old_save_path = Capybara.save_path
7
7
  Capybara.save_path = nil
@@ -13,43 +13,43 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
13
13
  FileUtils.rm_rf alternative_path
14
14
  end
15
15
 
16
- it "generates sensible filename" do
16
+ it 'generates sensible filename' do
17
17
  allow(@session.driver).to receive(:save_screenshot)
18
18
 
19
19
  @session.save_screenshot
20
20
 
21
21
  regexp = Regexp.new(File.join(Dir.pwd, 'capybara-\d+\.png'))
22
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
22
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
23
23
  end
24
24
 
25
- it "allows to specify another path" do
25
+ it 'allows to specify another path' do
26
26
  allow(@session.driver).to receive(:save_screenshot)
27
27
 
28
28
  custom_path = 'screenshots/1.png'
29
29
  @session.save_screenshot(custom_path)
30
30
 
31
- 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)
32
32
  end
33
33
 
34
- context "with Capybara.save_path" do
35
- 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
36
36
  Capybara.save_path = alternative_path
37
37
  allow(@session.driver).to receive(:save_screenshot)
38
38
 
39
39
  @session.save_screenshot
40
40
 
41
41
  regexp = Regexp.new(File.join(alternative_path, 'capybara-\d+\.png'))
42
- expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
42
+ expect(@session.driver).to have_received(:save_screenshot).with(regexp, any_args)
43
43
  end
44
44
 
45
- it "relative paths are relative to save_path" do
45
+ it 'relative paths are relative to save_path' do
46
46
  Capybara.save_path = alternative_path
47
47
  allow(@session.driver).to receive(:save_screenshot)
48
48
 
49
49
  custom_path = 'screenshots/2.png'
50
50
  @session.save_screenshot(custom_path)
51
51
 
52
- 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)
53
53
  end
54
54
  end
55
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,119 @@
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.documentElement.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.documentElement.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.documentElement.scrollHeight - document.documentElement.clientHeight')
39
+ scrolled_location_x, scrolled_location_y = @session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')
40
+ expect(scrolled_location_x).to be_within(0.5).of(0)
41
+ expect(scrolled_location_y).to be_within(0.5).of(max_scroll)
42
+ end
43
+
44
+ it 'can scroll the window to the vertical center' do
45
+ @session.scroll_to :center
46
+ max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
47
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll / 2]
48
+ end
49
+
50
+ it 'can scroll the window to specific location' do
51
+ @session.scroll_to 100, 100
52
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [100, 100]
53
+ end
54
+
55
+ it 'can scroll an element to the top of the scrolling element' do
56
+ scrolling_element = @session.find(:css, '#scrollable')
57
+ el = scrolling_element.find(:css, '#inner')
58
+ scrolling_element.scroll_to(el, align: :top)
59
+ scrolling_element_top = scrolling_element.evaluate_script('this.getBoundingClientRect().top')
60
+ expect(el.evaluate_script('this.getBoundingClientRect().top')).to be_within(3).of(scrolling_element_top)
61
+ end
62
+
63
+ it 'can scroll an element to the bottom of the scrolling element' do
64
+ scrolling_element = @session.find(:css, '#scrollable')
65
+ el = scrolling_element.find(:css, '#inner')
66
+ scrolling_element.scroll_to(el, align: :bottom)
67
+ el_bottom = el.evaluate_script('this.getBoundingClientRect().bottom')
68
+ scroller_bottom = scrolling_element.evaluate_script('this.getBoundingClientRect().top + this.clientHeight')
69
+ expect(el_bottom).to be_within(1).of(scroller_bottom)
70
+ end
71
+
72
+ it 'can scroll an element to the center of the scrolling element' do
73
+ scrolling_element = @session.find(:css, '#scrollable')
74
+ el = scrolling_element.find(:css, '#inner')
75
+ scrolling_element.scroll_to(el, align: :center)
76
+ el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
77
+ scrollable_center = scrolling_element.evaluate_script('(this.clientHeight / 2) + this.getBoundingClientRect().top')
78
+ expect(el_center).to be_within(1).of(scrollable_center)
79
+ end
80
+
81
+ it 'can scroll the scrolling element to the top' do
82
+ scrolling_element = @session.find(:css, '#scrollable')
83
+ scrolling_element.scroll_to :bottom
84
+ scrolling_element.scroll_to :top
85
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, 0]
86
+ end
87
+
88
+ it 'can scroll the scrolling element to the bottom' do
89
+ scrolling_element = @session.find(:css, '#scrollable')
90
+ scrolling_element.scroll_to :bottom
91
+ max_scroll = scrolling_element.evaluate_script('this.scrollHeight - this.clientHeight')
92
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, max_scroll]
93
+ end
94
+
95
+ it 'can scroll the scrolling element to the vertical center' do
96
+ scrolling_element = @session.find(:css, '#scrollable')
97
+ scrolling_element.scroll_to :center
98
+ max_scroll = scrolling_element.evaluate_script('this.scrollHeight - this.clientHeight')
99
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [0, max_scroll / 2]
100
+ end
101
+
102
+ it 'can scroll the scrolling element to specific location' do
103
+ scrolling_element = @session.find(:css, '#scrollable')
104
+ scrolling_element.scroll_to 100, 100
105
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [100, 100]
106
+ end
107
+
108
+ it 'can scroll the window by a specific amount' do
109
+ @session.scroll_to(:current, offset: [50, 75])
110
+ expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [50, 75]
111
+ end
112
+
113
+ it 'can scroll the scroll the scrolling element by a specific amount' do
114
+ scrolling_element = @session.find(:css, '#scrollable')
115
+ scrolling_element.scroll_to 100, 100
116
+ scrolling_element.scroll_to(:current, offset: [-50, 50])
117
+ expect(scrolling_element.evaluate_script('[this.scrollLeft, this.scrollTop]')).to eq [50, 150]
118
+ end
119
+ end