capybara 3.0.0 → 3.36.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 -1
  3. data/History.md +777 -10
  4. data/License.txt +1 -1
  5. data/README.md +75 -58
  6. data/lib/capybara/config.rb +29 -10
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +22 -4
  9. data/lib/capybara/driver/node.rb +34 -9
  10. data/lib/capybara/dsl.rb +14 -6
  11. data/lib/capybara/helpers.rb +52 -7
  12. data/lib/capybara/minitest/spec.rb +173 -84
  13. data/lib/capybara/minitest.rb +250 -144
  14. data/lib/capybara/node/actions.rb +248 -124
  15. data/lib/capybara/node/base.rb +34 -20
  16. data/lib/capybara/node/document.rb +14 -2
  17. data/lib/capybara/node/document_matchers.rb +13 -15
  18. data/lib/capybara/node/element.rb +339 -113
  19. data/lib/capybara/node/finders.rb +95 -82
  20. data/lib/capybara/node/matchers.rb +338 -157
  21. data/lib/capybara/node/simple.rb +54 -15
  22. data/lib/capybara/queries/active_element_query.rb +18 -0
  23. data/lib/capybara/queries/ancestor_query.rb +9 -10
  24. data/lib/capybara/queries/base_query.rb +25 -18
  25. data/lib/capybara/queries/current_path_query.rb +16 -6
  26. data/lib/capybara/queries/match_query.rb +11 -0
  27. data/lib/capybara/queries/selector_query.rb +600 -103
  28. data/lib/capybara/queries/sibling_query.rb +9 -7
  29. data/lib/capybara/queries/style_query.rb +45 -0
  30. data/lib/capybara/queries/text_query.rb +40 -22
  31. data/lib/capybara/queries/title_query.rb +2 -2
  32. data/lib/capybara/rack_test/browser.rb +47 -28
  33. data/lib/capybara/rack_test/driver.rb +12 -3
  34. data/lib/capybara/rack_test/errors.rb +6 -0
  35. data/lib/capybara/rack_test/form.rb +53 -50
  36. data/lib/capybara/rack_test/node.rb +114 -37
  37. data/lib/capybara/rails.rb +1 -1
  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 +86 -52
  43. data/lib/capybara/rspec/features.rb +8 -10
  44. data/lib/capybara/rspec/matcher_proxies.rb +39 -18
  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 +138 -316
  59. data/lib/capybara/rspec.rb +3 -2
  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 +89 -12
  63. data/lib/capybara/selector/definition/button.rb +68 -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 +279 -0
  85. data/lib/capybara/selector/filter.rb +1 -0
  86. data/lib/capybara/selector/filter_set.rb +72 -27
  87. data/lib/capybara/selector/filters/base.rb +45 -2
  88. data/lib/capybara/selector/filters/expression_filter.rb +5 -6
  89. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  90. data/lib/capybara/selector/filters/node_filter.rb +18 -4
  91. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  92. data/lib/capybara/selector/selector.rb +85 -200
  93. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  94. data/lib/capybara/selector.rb +226 -537
  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 +296 -238
  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 +436 -166
  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 +69 -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 +58 -67
  127. data/lib/capybara/session/config.rb +38 -6
  128. data/lib/capybara/session/matchers.rb +26 -19
  129. data/lib/capybara/session.rb +258 -190
  130. data/lib/capybara/spec/public/jquery.js +5 -5
  131. data/lib/capybara/spec/public/offset.js +6 -0
  132. data/lib/capybara/spec/public/test.js +122 -8
  133. data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
  134. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  135. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  136. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  137. data/lib/capybara/spec/session/all_spec.rb +135 -42
  138. data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
  140. data/lib/capybara/spec/session/{assert_current_path.rb → assert_current_path_spec.rb} +20 -18
  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.rb → assert_text_spec.rb} +62 -38
  144. data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +12 -12
  145. data/lib/capybara/spec/session/attach_file_spec.rb +120 -72
  146. data/lib/capybara/spec/session/body_spec.rb +11 -13
  147. data/lib/capybara/spec/session/check_spec.rb +111 -51
  148. data/lib/capybara/spec/session/choose_spec.rb +62 -30
  149. data/lib/capybara/spec/session/click_button_spec.rb +227 -161
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -30
  151. data/lib/capybara/spec/session/click_link_spec.rb +78 -55
  152. data/lib/capybara/spec/session/current_scope_spec.rb +7 -7
  153. data/lib/capybara/spec/session/current_url_spec.rb +44 -37
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +8 -6
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +70 -56
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
  162. data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
  163. data/lib/capybara/spec/session/fill_in_spec.rb +104 -44
  164. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +8 -8
  166. data/lib/capybara/spec/session/find_field_spec.rb +33 -31
  167. data/lib/capybara/spec/session/find_link_spec.rb +32 -14
  168. data/lib/capybara/spec/session/find_spec.rb +236 -141
  169. data/lib/capybara/spec/session/first_spec.rb +44 -43
  170. data/lib/capybara/spec/session/frame/frame_title_spec.rb +6 -6
  171. data/lib/capybara/spec/session/frame/frame_url_spec.rb +6 -6
  172. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +32 -20
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +44 -19
  174. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  175. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +18 -18
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +92 -12
  180. data/lib/capybara/spec/session/has_css_spec.rb +271 -137
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +48 -33
  182. data/lib/capybara/spec/session/has_field_spec.rb +137 -58
  183. data/lib/capybara/spec/session/has_link_spec.rb +30 -6
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +26 -24
  185. data/lib/capybara/spec/session/has_select_spec.rb +75 -47
  186. data/lib/capybara/spec/session/has_selector_spec.rb +102 -69
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +170 -4
  189. data/lib/capybara/spec/session/has_text_spec.rb +108 -52
  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.rb → 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 +35 -0
  195. data/lib/capybara/spec/session/node_spec.rb +871 -122
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +15 -12
  197. data/lib/capybara/spec/session/refresh_spec.rb +9 -7
  198. data/lib/capybara/spec/session/reset_session_spec.rb +52 -37
  199. data/lib/capybara/spec/session/{response_code.rb → 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 +5 -4
  202. data/lib/capybara/spec/session/save_page_spec.rb +41 -38
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +13 -11
  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 +102 -76
  207. data/lib/capybara/spec/session/selectors_spec.rb +51 -18
  208. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  209. data/lib/capybara/spec/session/text_spec.rb +26 -24
  210. data/lib/capybara/spec/session/title_spec.rb +8 -6
  211. data/lib/capybara/spec/session/uncheck_spec.rb +40 -21
  212. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  213. data/lib/capybara/spec/session/visit_spec.rb +59 -53
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +22 -19
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +4 -3
  216. data/lib/capybara/spec/session/window/open_new_window_spec.rb +4 -3
  217. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +25 -21
  218. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +10 -5
  219. data/lib/capybara/spec/session/window/window_spec.rb +88 -54
  220. data/lib/capybara/spec/session/window/windows_spec.rb +10 -7
  221. data/lib/capybara/spec/session/window/within_window_spec.rb +17 -16
  222. data/lib/capybara/spec/session/within_spec.rb +69 -44
  223. data/lib/capybara/spec/spec_helper.rb +41 -53
  224. data/lib/capybara/spec/test_app.rb +79 -40
  225. data/lib/capybara/spec/views/animated.erb +49 -0
  226. data/lib/capybara/spec/views/form.erb +134 -42
  227. data/lib/capybara/spec/views/frame_child.erb +4 -3
  228. data/lib/capybara/spec/views/frame_one.erb +2 -1
  229. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  230. data/lib/capybara/spec/views/frame_two.erb +1 -1
  231. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  232. data/lib/capybara/spec/views/layout.erb +10 -0
  233. data/lib/capybara/spec/views/obscured.erb +47 -0
  234. data/lib/capybara/spec/views/offset.erb +33 -0
  235. data/lib/capybara/spec/views/path.erb +2 -2
  236. data/lib/capybara/spec/views/popup_one.erb +1 -1
  237. data/lib/capybara/spec/views/popup_two.erb +1 -1
  238. data/lib/capybara/spec/views/react.erb +45 -0
  239. data/lib/capybara/spec/views/scroll.erb +21 -0
  240. data/lib/capybara/spec/views/spatial.erb +31 -0
  241. data/lib/capybara/spec/views/tables.erb +68 -1
  242. data/lib/capybara/spec/views/with_animation.erb +81 -0
  243. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  244. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  245. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  246. data/lib/capybara/spec/views/with_hover.erb +3 -2
  247. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  248. data/lib/capybara/spec/views/with_html.erb +43 -10
  249. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  250. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  251. data/lib/capybara/spec/views/with_js.erb +30 -5
  252. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  253. data/lib/capybara/spec/views/with_namespace.erb +21 -0
  254. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  255. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  256. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  257. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  258. data/lib/capybara/spec/views/with_windows.erb +1 -1
  259. data/lib/capybara/spec/views/within_frames.erb +1 -1
  260. data/lib/capybara/version.rb +1 -1
  261. data/lib/capybara/window.rb +31 -25
  262. data/lib/capybara.rb +120 -100
  263. data/spec/basic_node_spec.rb +59 -34
  264. data/spec/capybara_spec.rb +54 -52
  265. data/spec/css_builder_spec.rb +101 -0
  266. data/spec/css_splitter_spec.rb +38 -0
  267. data/spec/dsl_spec.rb +80 -53
  268. data/spec/filter_set_spec.rb +24 -7
  269. data/spec/fixtures/certificate.pem +25 -0
  270. data/spec/fixtures/key.pem +27 -0
  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 +38 -5
  274. data/spec/minitest_spec_spec.rb +88 -62
  275. data/spec/per_session_config_spec.rb +5 -5
  276. data/spec/rack_test_spec.rb +169 -115
  277. data/spec/regexp_dissassembler_spec.rb +250 -0
  278. data/spec/result_spec.rb +86 -33
  279. data/spec/rspec/features_spec.rb +26 -23
  280. data/spec/rspec/scenarios_spec.rb +8 -4
  281. data/spec/rspec/shared_spec_matchers.rb +393 -363
  282. data/spec/rspec/views_spec.rb +4 -3
  283. data/spec/rspec_matchers_spec.rb +10 -10
  284. data/spec/rspec_spec.rb +109 -85
  285. data/spec/sauce_spec_chrome.rb +43 -0
  286. data/spec/selector_spec.rb +391 -61
  287. data/spec/selenium_spec_chrome.rb +180 -41
  288. data/spec/selenium_spec_chrome_remote.rb +101 -0
  289. data/spec/selenium_spec_edge.rb +28 -8
  290. data/spec/selenium_spec_firefox.rb +211 -0
  291. data/spec/selenium_spec_firefox_remote.rb +80 -0
  292. data/spec/selenium_spec_ie.rb +127 -11
  293. data/spec/selenium_spec_safari.rb +156 -0
  294. data/spec/server_spec.rb +177 -78
  295. data/spec/session_spec.rb +52 -16
  296. data/spec/shared_selenium_node.rb +79 -0
  297. data/spec/shared_selenium_session.rb +455 -123
  298. data/spec/spec_helper.rb +91 -2
  299. data/spec/xpath_builder_spec.rb +93 -0
  300. metadata +343 -42
  301. data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
  302. data/.yard/templates_custom/default/class/html/setup.rb +0 -17
  303. data/.yard/yard_extensions.rb +0 -78
  304. data/lib/capybara/rspec/compound.rb +0 -90
  305. data/lib/capybara/spec/session/assert_selector.rb +0 -149
  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 -143
@@ -1,11 +1,13 @@
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
+
10
+ Capybara.save_path = File.join(Dir.pwd, 'save_path_tmp')
9
11
 
10
12
  module Capybara
11
13
  module SpecHelper
@@ -14,8 +16,7 @@ module Capybara
14
16
  config.filter_run_excluding requires: method(:filter).to_proc
15
17
  config.before { Capybara::SpecHelper.reset! }
16
18
  config.after { Capybara::SpecHelper.reset! }
17
- # Test in 3.5+ where metadata doesn't autotrigger shared context inclusion - will be only behavior in RSpec 4
18
- config.shared_context_metadata_behavior = :apply_to_host_groups if RSpec::Core::Version::STRING.to_f >= 3.5
19
+ config.shared_context_metadata_behavior = :apply_to_host_groups
19
20
  end
20
21
 
21
22
  def reset!
@@ -29,11 +30,19 @@ module Capybara
29
30
  Capybara.visible_text_only = false
30
31
  Capybara.match = :smart
31
32
  Capybara.enable_aria_label = false
33
+ Capybara.enable_aria_role = false
34
+ Capybara.default_set_options = {}
35
+ Capybara.disable_animation = false
36
+ Capybara.test_id = nil
37
+ Capybara.predicates_wait = true
38
+ Capybara.default_normalize_ws = false
39
+ Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil?
40
+ Capybara.w3c_click_offset = false
32
41
  reset_threadsafe
33
42
  end
34
43
 
35
44
  def filter(requires, metadata)
36
- if requires and metadata[:capybara_skip]
45
+ if requires && metadata[:capybara_skip]
37
46
  requires.any? do |require|
38
47
  metadata[:capybara_skip].include?(require)
39
48
  end
@@ -47,25 +56,27 @@ module Capybara
47
56
  @specs << [name, options, block]
48
57
  end
49
58
 
50
- def run_specs(session, name, **options)
59
+ def run_specs(session, name, **options, &filter_block)
51
60
  specs = @specs
52
61
  RSpec.describe Capybara::Session, name, options do
53
62
  include Capybara::SpecHelper
54
63
  include Capybara::RSpecMatchers
55
- before do
64
+
65
+ before do |example|
56
66
  @session = session
67
+ instance_exec(example, &filter_block) if filter_block
57
68
  end
58
69
 
59
70
  after do
60
- @session.reset_session!
71
+ session.reset_session!
61
72
  end
62
73
 
63
74
  before :each, psc: true do
64
- SpecHelper.reset_threadsafe(true, @session)
75
+ SpecHelper.reset_threadsafe(bool: true, session: session)
65
76
  end
66
77
 
67
78
  after psc: true do
68
- SpecHelper.reset_threadsafe(false, @session)
79
+ SpecHelper.reset_threadsafe(session: session)
69
80
  end
70
81
 
71
82
  before :each, :exact_false do
@@ -80,68 +91,45 @@ module Capybara
80
91
  end
81
92
  end
82
93
 
83
- def reset_threadsafe(bool = false, session = nil)
84
- Capybara::Session.class_variable_set(:@@instance_created, false) # Work around limit on when threadsafe can be changed
94
+ def reset_threadsafe(bool: false, session: nil)
95
+ # Work around limit on when threadsafe can be changed
96
+ Capybara::Session.class_variable_set(:@@instance_created, false) # rubocop:disable Style/ClassVars
85
97
  Capybara.threadsafe = bool
86
98
  session = session.current_session if session.respond_to?(:current_session)
87
- session.instance_variable_set(:@config, nil) if session
99
+ session&.instance_variable_set(:@config, nil)
88
100
  end
89
101
  end
90
102
 
91
103
  def silence_stream(stream)
92
104
  old_stream = stream.dup
93
- stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null')
105
+ stream.reopen(RbConfig::CONFIG['host_os'].match?(/rmswin|mingw/) ? 'NUL:' : '/dev/null')
94
106
  stream.sync = true
95
107
  yield
96
108
  ensure
97
109
  stream.reopen(old_stream)
98
110
  end
99
111
 
100
- def quietly
101
- silence_stream(STDOUT) do
102
- silence_stream(STDERR) do
103
- yield
104
- end
112
+ def quietly(&block)
113
+ silence_stream($stdout) do
114
+ silence_stream($stderr, &block)
105
115
  end
106
116
  end
107
117
 
108
118
  def extract_results(session)
109
119
  expect(session).to have_xpath("//pre[@id='results']")
110
- YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
111
- end
112
-
113
- def marionette?(session)
114
- session.respond_to?(:driver) && session.driver.respond_to?(:marionette?, true) && session.driver.send(:marionette?)
115
- end
116
-
117
- def marionette_lt?(version, session)
118
- marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f < version)
119
- end
120
-
121
- def marionette_gte?(version, session)
122
- marionette?(session) && (session.driver.browser.capabilities[:browser_version].to_f >= version)
123
- end
124
-
125
- def chrome?(session)
126
- session.respond_to?(:driver) && session.driver.respond_to?(:chrome?, true) && session.driver.send(:chrome?)
127
- end
128
-
129
- def chrome_lt?(version, session)
130
- chrome?(session) && (session.driver.browser.capabilities[:version].to_f < version)
131
- end
132
-
133
- def chrome_gte?(version, session)
134
- chrome?(session) && (session.driver.browser.capabilities[:version].to_f >= version)
120
+ perms = [(::Sinatra::IndifferentHash if defined? ::Sinatra::IndifferentHash)].compact
121
+ results = Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
122
+ YAML.safe_load results, permitted_classes: perms
135
123
  end
136
124
 
137
- def edge?(session)
138
- session.respond_to?(:driver) && session.driver.respond_to?(:edge?, true) && session.driver.send(:edge?)
125
+ def be_an_invalid_element_error(session)
126
+ satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
139
127
  end
140
128
 
141
- def ie?(session)
142
- session.respond_to?(:driver) && session.driver.respond_to?(:ie?, true) && session.driver.send(:ie?)
129
+ def with_os_path_separators(path)
130
+ Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
143
131
  end
144
132
  end
145
133
  end
146
134
 
147
- Dir[File.dirname(__FILE__) + "/session/**/*.rb"].each { |file| require_relative file }
135
+ Dir["#{File.dirname(__FILE__)}/session/**/*.rb"].each { |file| require_relative file }
@@ -6,9 +6,11 @@ require 'rack'
6
6
  require 'yaml'
7
7
 
8
8
  class TestApp < Sinatra::Base
9
- class TestAppError < StandardError; end
10
- class TestAppOtherError < StandardError
9
+ class TestAppError < Exception; end # rubocop:disable Lint/InheritException
10
+
11
+ class TestAppOtherError < Exception # rubocop:disable Lint/InheritException
11
12
  def initialize(string1, msg)
13
+ super()
12
14
  @something = string1
13
15
  @message = msg
14
16
  end
@@ -18,7 +20,6 @@ class TestApp < Sinatra::Base
18
20
  set :raise_errors, true
19
21
  set :show_exceptions, false
20
22
 
21
- @@form_post_count = 0
22
23
  # Also check lib/capybara/spec/views/*.erb for pages not listed here
23
24
 
24
25
  get '/' do
@@ -34,14 +35,26 @@ class TestApp < Sinatra::Base
34
35
  redirect '/redirect_again'
35
36
  end
36
37
 
38
+ get '/redirect_with_fragment' do
39
+ redirect '/landed#with_fragment'
40
+ end
41
+
37
42
  get '/redirect_again' do
38
43
  redirect '/landed'
39
44
  end
40
45
 
46
+ post '/redirect_307' do
47
+ redirect '/landed', 307
48
+ end
49
+
50
+ post '/redirect_308' do
51
+ redirect '/landed', 308
52
+ end
53
+
41
54
  get '/referer_base' do
42
55
  '<a href="/get_referer">direct link</a>' \
43
- '<a href="/redirect_to_get_referer">link via redirect</a>' \
44
- '<form action="/get_referer" method="get"><input type="submit"></form>'
56
+ '<a href="/redirect_to_get_referer">link via redirect</a>' \
57
+ '<form action="/get_referer" method="get"><input type="submit"></form>'
45
58
  end
46
59
 
47
60
  get '/redirect_to_get_referer' do
@@ -49,7 +62,7 @@ class TestApp < Sinatra::Base
49
62
  end
50
63
 
51
64
  get '/get_referer' do
52
- request.referer.nil? ? "No referer" : "Got referer: #{request.referer}"
65
+ request.referer.nil? ? 'No referer' : "Got referer: #{request.referer}"
53
66
  end
54
67
 
55
68
  get '/host' do
@@ -59,14 +72,18 @@ class TestApp < Sinatra::Base
59
72
  get '/redirect/:times/times' do
60
73
  times = params[:times].to_i
61
74
  if times.zero?
62
- "redirection complete"
75
+ 'redirection complete'
63
76
  else
64
77
  redirect "/redirect/#{times - 1}/times"
65
78
  end
66
79
  end
67
80
 
68
81
  get '/landed' do
69
- "You landed"
82
+ 'You landed'
83
+ end
84
+
85
+ post '/landed' do
86
+ "You post landed: #{params.dig(:form, 'data')}"
70
87
  end
71
88
 
72
89
  get '/with-quotes' do
@@ -74,11 +91,11 @@ class TestApp < Sinatra::Base
74
91
  end
75
92
 
76
93
  get '/form/get' do
77
- '<pre id="results">' + params[:form].to_yaml + '</pre>'
94
+ %(<pre id="results">#{params[:form].to_yaml}</pre>)
78
95
  end
79
96
 
80
97
  post '/relative' do
81
- '<pre id="results">' + params[:form].to_yaml + '</pre>'
98
+ %(<pre id="results">#{params[:form].to_yaml}</pre>)
82
99
  end
83
100
 
84
101
  get '/favicon.ico' do
@@ -89,12 +106,12 @@ class TestApp < Sinatra::Base
89
106
  redirect '/redirect_again'
90
107
  end
91
108
 
92
- delete "/delete" do
93
- "The requested object was deleted"
109
+ delete '/delete' do
110
+ 'The requested object was deleted'
94
111
  end
95
112
 
96
- get "/delete" do
97
- "Not deleted"
113
+ get '/delete' do
114
+ 'Not deleted'
98
115
  end
99
116
 
100
117
  get '/redirect_back' do
@@ -129,11 +146,11 @@ class TestApp < Sinatra::Base
129
146
  end
130
147
 
131
148
  get '/error' do
132
- raise TestAppError, "some error"
149
+ raise TestAppError, 'some error'
133
150
  end
134
151
 
135
152
  get '/other_error' do
136
- raise TestAppOtherError.new("something", "other error")
153
+ raise TestAppOtherError.new('something', 'other error')
137
154
  end
138
155
 
139
156
  get '/load_error' do
@@ -146,20 +163,35 @@ class TestApp < Sinatra::Base
146
163
 
147
164
  get '/with_title' do
148
165
  <<-HTML
149
- <title>#{params[:title] || 'Test Title'}</title>
150
- <body>
151
- <svg><title>abcdefg</title></svg>
152
- </body>
166
+ <!DOCTYPE html>
167
+ <html lang="en">
168
+ <head>
169
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
170
+ <title>#{params[:title] || 'Test Title'}</title>
171
+ </head>
172
+
173
+ <body>
174
+ <svg><title>abcdefg</title></svg>
175
+ </body>
176
+ </html>
153
177
  HTML
154
178
  end
155
179
 
180
+ get '/download.csv' do
181
+ content_type 'text/csv'
182
+ 'This, is, comma, separated' \
183
+ 'Thomas, Walpole, was , here'
184
+ end
185
+
156
186
  get '/:view' do |view|
157
- erb view.to_sym, locals: { referrer: request.referrer }
187
+ view_template = "#{__dir__}/views/#{view}.erb"
188
+ has_layout = File.exist?(view_template) && File.open(view_template) { |f| f.first.downcase.include?('doctype') }
189
+ erb view.to_sym, locals: { referrer: request.referrer }, layout: !has_layout
158
190
  end
159
191
 
160
192
  post '/form' do
161
- @@form_post_count += 1
162
- '<pre id="results">' + params[:form].merge("post_count" => @@form_post_count).to_yaml + '</pre>'
193
+ self.class.form_post_count += 1
194
+ %(<pre id="results">#{params[:form].merge('post_count' => self.class.form_post_count).to_yaml}</pre>)
163
195
  end
164
196
 
165
197
  post '/upload_empty' do
@@ -171,28 +203,35 @@ class TestApp < Sinatra::Base
171
203
  end
172
204
 
173
205
  post '/upload' do
174
- begin
175
- buffer = []
176
- buffer << "Content-type: #{params[:form][:document][:type]}"
177
- buffer << "File content: #{params[:form][:document][:tempfile].read}"
178
- buffer.join(' | ')
179
- rescue
180
- 'No file uploaded'
181
- end
206
+ buffer = []
207
+ buffer << "Content-type: #{params.dig(:form, :document, :type)}"
208
+ buffer << "File content: #{params.dig(:form, :document, :tempfile).read}"
209
+ buffer.join(' | ')
210
+ rescue StandardError
211
+ 'No file uploaded'
182
212
  end
183
213
 
184
214
  post '/upload_multiple' do
185
- begin
186
- buffer = [params[:form][:multiple_documents].size.to_s]
187
- params[:form][:multiple_documents].each do |doc|
188
- buffer << "Content-type: #{doc[:type]}"
189
- buffer << "File content: #{doc[:tempfile].read}"
190
- end
191
- buffer.join(' | ')
192
- rescue
193
- 'No files uploaded'
215
+ docs = params.dig(:form, :multiple_documents)
216
+ buffer = [docs.size.to_s]
217
+ docs.each do |doc|
218
+ buffer << "Content-type: #{doc[:type]}"
219
+ buffer << "File content: #{doc[:tempfile].read}"
194
220
  end
221
+ buffer.join(' | ')
222
+ rescue StandardError
223
+ 'No files uploaded'
224
+ end
225
+
226
+ get '/apple-touch-icon-precomposed.png' do
227
+ halt(404)
228
+ end
229
+
230
+ class << self
231
+ attr_accessor :form_post_count
195
232
  end
233
+
234
+ @form_post_count = 0
196
235
  end
197
236
 
198
237
  Rack::Handler::Puma.run TestApp, Port: 8070 if $PROGRAM_NAME == __FILE__
@@ -0,0 +1,49 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
+ <title>with_animation</title>
6
+ <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
7
+ <script>
8
+ $(document).on('contextmenu', function(e){ e.preventDefault(); });
9
+ </script>
10
+ <style>
11
+ div {
12
+ width: 400px;
13
+ height: 400px;
14
+ position: absolute;
15
+ }
16
+ #obscured {
17
+ z-index: 1;
18
+ background-color: red;
19
+ }
20
+ #cover {
21
+ z-index: 2;
22
+ background-color: blue;
23
+ }
24
+ #offscreen {
25
+ top: 2000px;
26
+ left: 2000px;
27
+ background-color: green;
28
+ }
29
+ #offscreen_wrapper {
30
+ top: 2000px;
31
+ left: 2000px;
32
+ overflow-x: scroll;
33
+ background-color: yellow;
34
+ }
35
+ </style>
36
+ </head>
37
+
38
+ <body id="with_animation">
39
+ <div id="obscured">
40
+ <input id="obscured_input"/>
41
+ </div>
42
+ <div id="cover"></div>
43
+ <div id="offscreen_wrapper">
44
+ <div id="offscreen"></div>
45
+ </div>
46
+ </body>
47
+
48
+ <iframe id="frameOne" src="/frame_one"></iframe>
49
+ </html>