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,31 +5,67 @@ Capybara::SpecHelper.spec '#within' do
5
5
  @session.visit('/with_scope')
6
6
  end
7
7
 
8
- context "with CSS selector" do
9
- it "should click links in the given scope" do
10
- @session.within(:css, "#for_bar li:first-child") do
8
+ context 'with CSS selector' do
9
+ it 'should click links in the given scope' do
10
+ @session.within(:css, '#for_bar li:first-child') do
11
11
  @session.click_link('Go')
12
12
  end
13
13
  expect(@session).to have_content('Bar')
14
14
  end
15
15
 
16
- it "should assert content in the given scope" do
17
- @session.within(:css, "#for_foo") do
16
+ it 'should assert content in the given scope' do
17
+ @session.within(:css, '#for_foo') do
18
18
  expect(@session).not_to have_content('First Name')
19
19
  end
20
20
  expect(@session).to have_content('First Name')
21
21
  end
22
22
 
23
- it "should accept additional options" do
24
- @session.within(:css, "#for_bar li", text: 'With Simple HTML') do
23
+ it 'should accept additional options' do
24
+ @session.within(:css, '#for_bar li', text: 'With Simple HTML') do
25
25
  @session.click_link('Go')
26
26
  end
27
27
  expect(@session).to have_content('Bar')
28
28
  end
29
+
30
+ it 'should reload the node if the page is changed' do
31
+ @session.within(:css, '#for_foo') do
32
+ @session.visit('/with_scope_other')
33
+ expect(@session).to have_content('Different text')
34
+ end
35
+ end
36
+
37
+ it 'should reload multiple nodes if the page is changed' do
38
+ @session.within(:css, '#for_bar') do
39
+ @session.within(:css, 'form[action="/redirect"]') do
40
+ @session.refresh
41
+ expect(@session).to have_content('First Name')
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'should error if the page is changed and a matching node no longer exists' do
47
+ @session.within(:css, '#for_foo') do
48
+ @session.visit('/')
49
+ expect { @session.text }.to raise_error(StandardError)
50
+ end
51
+ end
52
+
53
+ it 'should pass scope element to the block' do
54
+ @session.within(:css, '#another_foo') do |scope|
55
+ expect(scope).to match_css('#another_foo')
56
+ end
57
+ end
58
+
59
+ it 'should scope click', requires: [:js] do
60
+ @session.within(:css, '#another_foo') do |scope|
61
+ @session.click
62
+ expect(scope).to have_text('I was clicked')
63
+ end
64
+ end
29
65
  end
30
66
 
31
- context "with XPath selector" do
32
- it "should click links in the given scope" do
67
+ context 'with XPath selector' do
68
+ it 'should click links in the given scope' do
33
69
  @session.within(:xpath, "//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do
34
70
  @session.click_link('Go')
35
71
  end
@@ -37,8 +73,8 @@ Capybara::SpecHelper.spec '#within' do
37
73
  end
38
74
  end
39
75
 
40
- context "with the default selector" do
41
- it "should use XPath" do
76
+ context 'with the default selector' do
77
+ it 'should use XPath' do
42
78
  @session.within("//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do
43
79
  @session.click_link('Go')
44
80
  end
@@ -46,9 +82,9 @@ Capybara::SpecHelper.spec '#within' do
46
82
  end
47
83
  end
48
84
 
49
- context "with Node rather than selector" do
50
- it "should click links in the given scope" do
51
- node_of_interest = @session.find(:css, "#for_bar li", text: 'With Simple HTML')
85
+ context 'with Node rather than selector' do
86
+ it 'should click links in the given scope' do
87
+ node_of_interest = @session.find(:css, '#for_bar li', text: 'With Simple HTML')
52
88
 
53
89
  @session.within(node_of_interest) do
54
90
  @session.click_link('Go')
@@ -57,20 +93,21 @@ Capybara::SpecHelper.spec '#within' do
57
93
  end
58
94
  end
59
95
 
60
- context "with the default selector set to CSS" do
96
+ context 'with the default selector set to CSS' do
61
97
  before { Capybara.default_selector = :css }
62
98
 
63
- it "should use CSS" do
64
- @session.within("#for_bar li", text: 'With Simple HTML') do
99
+ after { Capybara.default_selector = :xpath }
100
+
101
+ it 'should use CSS' do
102
+ @session.within('#for_bar li', text: 'With Simple HTML') do
65
103
  @session.click_link('Go')
66
104
  end
67
105
  expect(@session).to have_content('Bar')
68
106
  end
69
- after { Capybara.default_selector = :xpath }
70
107
  end
71
108
 
72
- context "with nested scopes" do
73
- it "should respect the inner scope" do
109
+ context 'with nested scopes' do
110
+ it 'should respect the inner scope' do
74
111
  @session.within("//div[@id='for_bar']") do
75
112
  @session.within(".//li[contains(.,'Bar')]") do
76
113
  @session.click_link('Go')
@@ -79,7 +116,7 @@ Capybara::SpecHelper.spec '#within' do
79
116
  expect(@session).to have_content('Another World')
80
117
  end
81
118
 
82
- it "should respect the outer scope" do
119
+ it 'should respect the outer scope' do
83
120
  @session.within("//div[@id='another_foo']") do
84
121
  @session.within(".//li[contains(.,'With Simple HTML')]") do
85
122
  @session.click_link('Go')
@@ -89,14 +126,14 @@ Capybara::SpecHelper.spec '#within' do
89
126
  end
90
127
  end
91
128
 
92
- it "should raise an error if the scope is not found on the page" do
129
+ it 'should raise an error if the scope is not found on the page' do
93
130
  expect do
94
131
  @session.within("//div[@id='doesnotexist']") do
95
132
  end
96
133
  end.to raise_error(Capybara::ElementNotFound)
97
134
  end
98
135
 
99
- it "should restore the scope when an error is raised" do
136
+ it 'should restore the scope when an error is raised' do
100
137
  expect do
101
138
  @session.within("//div[@id='for_bar']") do
102
139
  expect do
@@ -109,7 +146,7 @@ Capybara::SpecHelper.spec '#within' do
109
146
  end.not_to change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true)
110
147
  end
111
148
 
112
- it "should fill in a field and click a button" do
149
+ it 'should fill in a field and click a button' do
113
150
  @session.within("//li[contains(.,'Bar')]") do
114
151
  @session.click_button('Go')
115
152
  end
@@ -122,9 +159,9 @@ Capybara::SpecHelper.spec '#within' do
122
159
  expect(extract_results(@session)['first_name']).to eq('Dagobert')
123
160
  end
124
161
 
125
- it "should have #within_element as an alias" do
162
+ it 'should have #within_element as an alias' do
126
163
  expect(Capybara::Session.instance_method(:within)).to eq Capybara::Session.instance_method(:within_element)
127
- @session.within_element(:css, "#for_foo") do
164
+ @session.within_element(:css, '#for_foo') do
128
165
  expect(@session).not_to have_content('First Name')
129
166
  end
130
167
  end
@@ -135,18 +172,18 @@ Capybara::SpecHelper.spec '#within_fieldset' do
135
172
  @session.visit('/fieldsets')
136
173
  end
137
174
 
138
- it "should restrict scope to a fieldset given by id" do
139
- @session.within_fieldset("villain_fieldset") do
140
- @session.fill_in("Name", with: 'Goldfinger')
141
- @session.click_button("Create")
175
+ it 'should restrict scope to a fieldset given by id' do
176
+ @session.within_fieldset('villain_fieldset') do
177
+ @session.fill_in('Name', with: 'Goldfinger')
178
+ @session.click_button('Create')
142
179
  end
143
180
  expect(extract_results(@session)['villain_name']).to eq('Goldfinger')
144
181
  end
145
182
 
146
- it "should restrict scope to a fieldset given by legend" do
147
- @session.within_fieldset("Villain") do
148
- @session.fill_in("Name", with: 'Goldfinger')
149
- @session.click_button("Create")
183
+ it 'should restrict scope to a fieldset given by legend' do
184
+ @session.within_fieldset('Villain') do
185
+ @session.fill_in('Name', with: 'Goldfinger')
186
+ @session.click_button('Create')
150
187
  end
151
188
  expect(extract_results(@session)['villain_name']).to eq('Goldfinger')
152
189
  end
@@ -157,18 +194,18 @@ Capybara::SpecHelper.spec '#within_table' do
157
194
  @session.visit('/tables')
158
195
  end
159
196
 
160
- it "should restrict scope to a fieldset given by id" do
161
- @session.within_table("girl_table") do
162
- @session.fill_in("Name", with: 'Christmas')
163
- @session.click_button("Create")
197
+ it 'should restrict scope to a fieldset given by id' do
198
+ @session.within_table('girl_table') do
199
+ @session.fill_in('Name', with: 'Christmas')
200
+ @session.click_button('Create')
164
201
  end
165
202
  expect(extract_results(@session)['girl_name']).to eq('Christmas')
166
203
  end
167
204
 
168
- it "should restrict scope to a fieldset given by legend" do
169
- @session.within_table("Villain") do
170
- @session.fill_in("Name", with: 'Quantum')
171
- @session.click_button("Create")
205
+ it 'should restrict scope to a fieldset given by legend' do
206
+ @session.within_table('Villain') do
207
+ @session.fill_in('Name', with: 'Quantum')
208
+ @session.click_button('Create')
172
209
  end
173
210
  expect(extract_results(@session)['villain_name']).to eq('Quantum')
174
211
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rspec"
4
- require "rspec/expectations"
5
- require "capybara"
6
- require "capybara/rspec" # Required here instead of in rspec_spec to avoid RSpec deprecation warning
7
- require "capybara/spec/test_app"
8
- require "nokogiri"
3
+ require 'rspec'
4
+ require 'rspec/expectations'
5
+ require 'capybara'
6
+ require 'capybara/rspec' # Required here instead of in rspec_spec to avoid RSpec deprecation warning
7
+ require 'capybara/spec/test_app'
8
+ require 'nokogiri'
9
9
 
10
10
  Capybara.save_path = File.join(Dir.pwd, 'save_path_tmp')
11
11
 
@@ -16,8 +16,7 @@ module Capybara
16
16
  config.filter_run_excluding requires: method(:filter).to_proc
17
17
  config.before { Capybara::SpecHelper.reset! }
18
18
  config.after { Capybara::SpecHelper.reset! }
19
- # Test in 3.5+ where metadata doesn't autotrigger shared context inclusion - will be only behavior in RSpec 4
20
- config.shared_context_metadata_behavior = :apply_to_host_groups if config.respond_to?(:shared_context_metadata_behavior=)
19
+ config.shared_context_metadata_behavior = :apply_to_host_groups
21
20
  end
22
21
 
23
22
  def reset!
@@ -25,14 +24,21 @@ module Capybara
25
24
  Capybara.app_host = nil
26
25
  Capybara.default_selector = :xpath
27
26
  Capybara.default_max_wait_time = 1
27
+ Capybara.default_retry_interval = 0.01
28
28
  Capybara.ignore_hidden_elements = true
29
29
  Capybara.exact = false
30
30
  Capybara.raise_server_errors = true
31
31
  Capybara.visible_text_only = false
32
32
  Capybara.match = :smart
33
33
  Capybara.enable_aria_label = false
34
+ Capybara.enable_aria_role = false
34
35
  Capybara.default_set_options = {}
35
36
  Capybara.disable_animation = false
37
+ Capybara.test_id = nil
38
+ Capybara.predicates_wait = true
39
+ Capybara.default_normalize_ws = false
40
+ Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil?
41
+ Capybara.w3c_click_offset = true
36
42
  reset_threadsafe
37
43
  end
38
44
 
@@ -51,43 +57,44 @@ module Capybara
51
57
  @specs << [name, options, block]
52
58
  end
53
59
 
54
- def run_specs(session, name, **options)
60
+ def run_specs(session, name, **options, &filter_block)
55
61
  specs = @specs
56
- RSpec.describe Capybara::Session, name, options do # rubocop:disable RSpec/EmptyExampleGroup
62
+ RSpec.describe Capybara::Session, name, options do
57
63
  include Capybara::SpecHelper
58
64
  include Capybara::RSpecMatchers
59
- # rubocop:disable RSpec/ScatteredSetup
60
- before do
65
+
66
+ before do |example|
61
67
  @session = session
68
+ instance_exec(example, &filter_block) if filter_block
62
69
  end
63
70
 
64
71
  after do
65
72
  session.reset_session!
66
73
  end
67
74
 
68
- before :each, psc: true do
69
- SpecHelper.reset_threadsafe(true, session)
75
+ before :each, :psc do
76
+ SpecHelper.reset_threadsafe(bool: true, session: session)
70
77
  end
71
78
 
72
79
  after psc: true do
73
- SpecHelper.reset_threadsafe(false, session)
80
+ SpecHelper.reset_threadsafe(session: session)
74
81
  end
75
82
 
76
83
  before :each, :exact_false do
77
84
  Capybara.exact = false
78
85
  end
79
- # rubocop:enable RSpec/ScatteredSetup
80
86
 
81
87
  specs.each do |spec_name, spec_options, block|
82
- describe spec_name, *spec_options do # rubocop:disable RSpec/EmptyExampleGroup
88
+ describe spec_name, *spec_options do
83
89
  class_eval(&block)
84
90
  end
85
91
  end
86
92
  end
87
93
  end
88
94
 
89
- def reset_threadsafe(bool = false, session = nil)
90
- Capybara::Session.class_variable_set(:@@instance_created, false) # Work around limit on when threadsafe can be changed
95
+ def reset_threadsafe(bool: false, session: nil)
96
+ # Work around limit on when threadsafe can be changed
97
+ Capybara::Session.class_variable_set(:@@instance_created, false) # rubocop:disable Style/ClassVars
91
98
  Capybara.threadsafe = bool
92
99
  session = session.current_session if session.respond_to?(:current_session)
93
100
  session&.instance_variable_set(:@config, nil)
@@ -96,58 +103,39 @@ module Capybara
96
103
 
97
104
  def silence_stream(stream)
98
105
  old_stream = stream.dup
99
- stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null')
106
+ stream.reopen(RbConfig::CONFIG['host_os'].match?(/rmswin|mingw/) ? 'NUL:' : '/dev/null')
100
107
  stream.sync = true
101
108
  yield
102
109
  ensure
103
110
  stream.reopen(old_stream)
104
111
  end
105
112
 
106
- def quietly
107
- silence_stream(STDOUT) do
108
- silence_stream(STDERR) do
109
- yield
110
- end
113
+ def quietly(&block)
114
+ silence_stream($stdout) do
115
+ silence_stream($stderr, &block)
111
116
  end
112
117
  end
113
118
 
114
119
  def extract_results(session)
115
120
  expect(session).to have_xpath("//pre[@id='results']")
116
- YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
117
- end
118
-
119
- def marionette?(session)
120
- session.respond_to?(:driver) && session.driver.respond_to?(:marionette?, true) && session.driver.send(:marionette?)
121
- end
122
-
123
- def marionette_lt?(version, session)
124
- marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f < version)
125
- end
126
-
127
- def marionette_gte?(version, session)
128
- marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f >= version)
129
- end
130
-
131
- def chrome?(session)
132
- session.respond_to?(:driver) && session.driver.respond_to?(:chrome?, true) && session.driver.send(:chrome?)
133
- end
134
-
135
- def chrome_lt?(version, session)
136
- chrome?(session) && (session.driver.browser.capabilities[:version].to_f < version)
121
+ perms = [(::Sinatra::IndifferentHash if defined? ::Sinatra::IndifferentHash)].compact
122
+ results = Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
123
+ YAML.safe_load results, permitted_classes: perms
137
124
  end
138
125
 
139
- def chrome_gte?(version, session)
140
- chrome?(session) && (session.driver.browser.capabilities[:version].to_f >= version)
126
+ def extract_content_type(session)
127
+ expect(session).to have_xpath("//pre[@id='content_type']")
128
+ Capybara::HTML(session.body).xpath("//pre[@id='content_type']").first.text
141
129
  end
142
130
 
143
- def edge?(session)
144
- session.respond_to?(:driver) && session.driver.respond_to?(:edge?, true) && session.driver.send(:edge?)
131
+ def be_an_invalid_element_error(session)
132
+ satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
145
133
  end
146
134
 
147
- def ie?(session)
148
- session.respond_to?(:driver) && session.driver.respond_to?(:ie?, true) && session.driver.send(:ie?)
135
+ def with_os_path_separators(path)
136
+ Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
149
137
  end
150
138
  end
151
139
  end
152
140
 
153
- Dir[File.dirname(__FILE__) + "/session/**/*.rb"].each { |file| require_relative file }
141
+ Dir["#{File.dirname(__FILE__)}/session/**/*.rb"].each { |file| require_relative file }