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
@@ -11,13 +11,13 @@ Capybara::SpecHelper.spec '#assert_title' do
11
11
  end.not_to raise_error
12
12
  end
13
13
 
14
- it "should not raise when given an empty string" do
14
+ it 'should not raise when given an empty string' do
15
15
  expect do
16
16
  @session.assert_title('')
17
17
  end.not_to raise_error
18
18
  end
19
19
 
20
- it "should allow regexp matches" do
20
+ it 'should allow regexp matches' do
21
21
  expect do
22
22
  @session.assert_title(/w[a-z]{3}_js/)
23
23
  end.not_to raise_error
@@ -27,10 +27,10 @@ Capybara::SpecHelper.spec '#assert_title' do
27
27
  end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" to match /w[a-z]{10}_js/')
28
28
  end
29
29
 
30
- it "should wait for title", requires: [:js] do
31
- @session.click_link("Change title")
30
+ it 'should wait for title', requires: [:js] do
31
+ @session.click_link('Change title')
32
32
  expect do
33
- @session.assert_title("changed title", wait: 3)
33
+ @session.assert_title('changed title', wait: 3)
34
34
  end.not_to raise_error
35
35
  end
36
36
 
@@ -40,12 +40,12 @@ Capybara::SpecHelper.spec '#assert_title' do
40
40
  end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" to include "monkey"')
41
41
  end
42
42
 
43
- it "should not normalize given title" do
43
+ it 'should not normalize given title' do
44
44
  @session.visit('/with_js')
45
45
  expect { @session.assert_title(' with_js ') }.to raise_error(Capybara::ExpectationNotMet)
46
46
  end
47
47
 
48
- it "should match correctly normalized title" do
48
+ it 'should match correctly normalized title' do
49
49
  uri = Addressable::URI.parse('/with_title')
50
50
  uri.query_values = { title: '   with space  title ' }
51
51
  @session.visit(uri.to_s)
@@ -53,7 +53,7 @@ Capybara::SpecHelper.spec '#assert_title' do
53
53
  expect { @session.assert_title('with space title') }.to raise_error(Capybara::ExpectationNotMet)
54
54
  end
55
55
 
56
- it "should not normalize given title in error message" do
56
+ it 'should not normalize given title in error message' do
57
57
  expect do
58
58
  @session.assert_title(2)
59
59
  end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" to include "2"')
@@ -65,21 +65,21 @@ Capybara::SpecHelper.spec '#assert_no_title' do
65
65
  @session.visit('/with_js')
66
66
  end
67
67
 
68
- it "should raise error if the title contains the given string" do
68
+ it 'should raise error if the title contains the given string' do
69
69
  expect do
70
70
  @session.assert_no_title('with_j')
71
71
  end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" not to include "with_j"')
72
72
  end
73
73
 
74
- it "should allow regexp matches" do
74
+ it 'should allow regexp matches' do
75
75
  expect do
76
76
  @session.assert_no_title(/w[a-z]{3}_js/)
77
77
  end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" not to match /w[a-z]{3}_js/')
78
78
  @session.assert_no_title(/monkey/)
79
79
  end
80
80
 
81
- it "should wait for title to disappear", requires: [:js] do
82
- @session.click_link("Change title")
81
+ it 'should wait for title to disappear', requires: [:js] do
82
+ @session.click_link('Change title')
83
83
  expect do
84
84
  @session.assert_no_title('with_js', wait: 3)
85
85
  end.not_to raise_error
@@ -1,168 +1,222 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Capybara::SpecHelper.spec "#attach_file" do
3
+ Capybara::SpecHelper.spec '#attach_file' do
4
+ let(:test_file_path) { File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__)) }
5
+ let(:another_test_file_path) { File.expand_path('../fixtures/another_test_file.txt', File.dirname(__FILE__)) }
6
+ let(:test_jpg_file_path) { File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__)) }
7
+ let(:no_extension_file_path) { File.expand_path('../fixtures/no_extension', File.dirname(__FILE__)) }
8
+
4
9
  before do
5
- @test_file_path = File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__))
6
- @another_test_file_path = File.expand_path('../fixtures/another_test_file.txt', File.dirname(__FILE__))
7
- @test_jpg_file_path = File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))
8
- @no_extension_file_path = File.expand_path('../fixtures/no_extension', File.dirname(__FILE__))
9
10
  @session.visit('/form')
10
11
  end
11
12
 
12
- context "with normal form" do
13
- it "should set a file path by id" do
14
- @session.attach_file "form_image", with_os_path_separators(__FILE__)
13
+ context 'with normal form' do
14
+ it 'should set a file path by id' do
15
+ @session.attach_file 'form_image', with_os_path_separators(__FILE__)
15
16
  @session.click_button('awesome')
16
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
17
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
17
18
  end
18
19
 
19
- it "should set a file path by label" do
20
- @session.attach_file "Image", with_os_path_separators(__FILE__)
20
+ it 'should set a file path by label' do
21
+ @session.attach_file 'Image', with_os_path_separators(__FILE__)
21
22
  @session.click_button('awesome')
22
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
23
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
23
24
  end
24
25
 
25
- it "casts to string" do
26
+ it 'should be able to set on element if no locator passed' do
27
+ ff = @session.find(:file_field, 'Image')
28
+ ff.attach_file(with_os_path_separators(__FILE__))
29
+ @session.click_button('awesome')
30
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
31
+ end
32
+
33
+ it 'casts to string' do
26
34
  @session.attach_file :form_image, with_os_path_separators(__FILE__)
27
35
  @session.click_button('awesome')
28
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
36
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
29
37
  end
30
38
  end
31
39
 
32
- context "with multipart form" do
33
- it "should set a file path by id" do
34
- @session.attach_file "form_document", with_os_path_separators(@test_file_path)
40
+ context 'with multipart form' do
41
+ it 'should set a file path by id' do
42
+ @session.attach_file 'form_document', with_os_path_separators(test_file_path)
35
43
  @session.click_button('Upload Single')
36
- expect(@session).to have_content(File.read(@test_file_path))
44
+ expect(@session).to have_content(File.read(test_file_path))
37
45
  end
38
46
 
39
- it "should set a file path by label" do
40
- @session.attach_file "Single Document", with_os_path_separators(@test_file_path)
47
+ it 'should set a file path by label' do
48
+ @session.attach_file 'Single Document', with_os_path_separators(test_file_path)
41
49
  @session.click_button('Upload Single')
42
- expect(@session).to have_content(File.read(@test_file_path))
50
+ expect(@session).to have_content(File.read(test_file_path))
43
51
  end
44
52
 
45
- it "should not break if no file is submitted" do
53
+ it 'should not break if no file is submitted' do
46
54
  @session.click_button('Upload Single')
47
55
  expect(@session).to have_content('No file uploaded')
48
56
  end
49
57
 
50
- it "should send content type text/plain when uploading a text file" do
51
- @session.attach_file "Single Document", with_os_path_separators(@test_file_path)
58
+ it 'should send prior hidden field if no file submitted' do
59
+ @session.click_button('Upload Empty With Hidden')
60
+ expect(extract_results(@session)['document2']).to eq('hidden_field')
61
+ expect(extract_content_type(@session)).to start_with('multipart/form-data;')
62
+ end
63
+
64
+ it 'should send content type text/plain when uploading a text file' do
65
+ @session.attach_file 'Single Document', with_os_path_separators(test_file_path)
52
66
  @session.click_button 'Upload Single'
53
67
  expect(@session).to have_content('text/plain')
54
68
  end
55
69
 
56
- it "should send content type image/jpeg when uploading an image" do
57
- @session.attach_file "Single Document", with_os_path_separators(@test_jpg_file_path)
70
+ it 'should send content type image/jpeg when uploading an image' do
71
+ @session.attach_file 'Single Document', with_os_path_separators(test_jpg_file_path)
58
72
  @session.click_button 'Upload Single'
59
73
  expect(@session).to have_content('image/jpeg')
60
74
  end
61
75
 
62
- it "should not break when uploading a file without extension" do
63
- @session.attach_file "Single Document", with_os_path_separators(@no_extension_file_path)
76
+ it 'should not break when uploading a file without extension' do
77
+ @session.attach_file 'Single Document', with_os_path_separators(no_extension_file_path)
64
78
  @session.click_button 'Upload Single'
65
- expect(@session).to have_content(File.read(@no_extension_file_path))
79
+ expect(@session).to have_content(File.read(no_extension_file_path))
66
80
  end
67
81
 
68
- it "should not break when using HTML5 multiple file input" do
69
- @session.attach_file "Multiple Documents", with_os_path_separators(@test_file_path)
82
+ it 'should not break when using HTML5 multiple file input' do
83
+ @session.attach_file 'Multiple Documents', with_os_path_separators(test_file_path)
70
84
  @session.click_button('Upload Multiple')
71
- expect(@session).to have_content(File.read(@test_file_path))
72
- expect(@session.body).to include("1 | ") # number of files
85
+ expect(@session).to have_content(File.read(test_file_path))
86
+ expect(@session.body).to include('1 | ') # number of files
73
87
  end
74
88
 
75
- it "should not break when using HTML5 multiple file input uploading multiple files" do
76
- @session.attach_file("Multiple Documents",
77
- [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
89
+ it 'should not break when using HTML5 multiple file input uploading multiple files' do
90
+ @session.attach_file('Multiple Documents',
91
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
78
92
  @session.click_button('Upload Multiple')
79
- expect(@session.body).to include("2 | ") # number of files
80
- expect(@session.body).to include(File.read(@test_file_path))
81
- expect(@session.body).to include(File.read(@another_test_file_path))
93
+ expect(@session).to have_content('2 | ') # number of files
94
+ expect(@session.body).to include(File.read(test_file_path))
95
+ expect(@session.body).to include(File.read(another_test_file_path))
82
96
  end
83
97
 
84
- it "should not send anything when attaching no files to a multiple upload field" do
98
+ it 'should not send anything when attaching no files to a multiple upload field' do
85
99
  @session.click_button('Upload Empty Multiple')
86
- expect(@session).to have_content("Successfully ignored empty file field")
100
+ expect(@session).to have_content('Successfully ignored empty file field')
87
101
  end
88
102
 
89
- it "should not append files to already attached" do
90
- @session.attach_file "Multiple Documents", with_os_path_separators(@test_file_path)
91
- @session.attach_file("Multiple Documents",
92
- [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
103
+ it 'should not append files to already attached' do
104
+ @session.attach_file 'Multiple Documents', with_os_path_separators(test_file_path)
105
+ @session.attach_file 'Multiple Documents', with_os_path_separators(another_test_file_path)
93
106
  @session.click_button('Upload Multiple')
94
- expect(@session.body).to include("2 | ") # number of files
95
- expect(@session.body).to include(File.read(@test_file_path))
96
- expect(@session.body).to include(File.read(@another_test_file_path))
107
+ expect(@session).to have_content('1 | ') # number of files
108
+ expect(@session.body).to include(File.read(another_test_file_path))
109
+ expect(@session.body).not_to include(File.read(test_file_path))
110
+ end
111
+
112
+ it 'should fire change once when uploading multiple files from empty', requires: [:js] do
113
+ @session.visit('with_js')
114
+ @session.attach_file('multiple-file',
115
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
116
+ expect(@session).to have_css('.file_change', count: 1)
117
+ end
118
+
119
+ it 'should fire change once for each set of files uploaded', requires: [:js] do
120
+ @session.visit('with_js')
121
+ @session.attach_file('multiple-file', [test_jpg_file_path].map { |f| with_os_path_separators(f) })
122
+ @session.attach_file('multiple-file',
123
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
124
+ expect(@session).to have_css('.file_change', count: 2)
97
125
  end
98
126
  end
99
127
 
100
128
  context "with a locator that doesn't exist" do
101
- it "should raise an error" do
102
- msg = "Unable to find visible file field \"does not exist\" that is not disabled"
129
+ it 'should raise an error' do
130
+ msg = /Unable to find file field "does not exist"/
103
131
  expect do
104
- @session.attach_file('does not exist', with_os_path_separators(@test_file_path))
132
+ @session.attach_file('does not exist', with_os_path_separators(test_file_path))
105
133
  end.to raise_error(Capybara::ElementNotFound, msg)
106
134
  end
107
135
  end
108
136
 
109
137
  context "with a path that doesn't exist" do
110
- it "should raise an error" do
138
+ it 'should raise an error' do
111
139
  expect { @session.attach_file('Image', '/no_such_file.png') }.to raise_error(Capybara::FileNotFound)
112
140
  end
113
141
  end
114
142
 
115
- context "with :exact option" do
116
- it "should set a file path by partial label when false" do
117
- @session.attach_file "Imag", with_os_path_separators(__FILE__), exact: false
143
+ context 'with :exact option' do
144
+ it 'should set a file path by partial label when false' do
145
+ @session.attach_file 'Imag', with_os_path_separators(__FILE__), exact: false
118
146
  @session.click_button('awesome')
119
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
147
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
120
148
  end
121
149
 
122
- it "should not allow partial matches when true" do
150
+ it 'should not allow partial matches when true' do
123
151
  expect do
124
- @session.attach_file "Imag", with_os_path_separators(__FILE__), exact: true
152
+ @session.attach_file 'Imag', with_os_path_separators(__FILE__), exact: true
125
153
  end.to raise_error(Capybara::ElementNotFound)
126
154
  end
127
155
  end
128
156
 
129
- context "with :make_visible option", requires: %i[js es_args] do
130
- it "applies a default style change when true" do
157
+ context 'with :make_visible option', requires: %i[js es_args] do
158
+ it 'applies a default style change when true' do
131
159
  @session.visit('/with_js')
132
160
  expect do
133
- @session.attach_file("hidden_file", with_os_path_separators(__FILE__))
161
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__))
134
162
  end.to raise_error Capybara::ElementNotFound
135
163
  expect do
136
- @session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: true)
164
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
137
165
  end.not_to raise_error
138
166
  end
139
167
 
140
- it "accepts a hash of styles to be applied" do
168
+ it 'accepts a hash of styles to be applied' do
141
169
  @session.visit('/with_js')
142
170
  expect do
143
- @session.attach_file("hidden_file",
171
+ @session.attach_file('hidden_file',
144
172
  with_os_path_separators(__FILE__),
145
173
  make_visible: { opacity: 1, display: 'block' })
146
174
  end.not_to raise_error
147
175
  end
148
176
 
149
- it "raises an error when the file input is not made visible" do
177
+ it 'raises an error when the file input is not made visible' do
150
178
  @session.visit('/with_js')
151
179
  expect do
152
- @session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: { color: 'red' })
180
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: { color: 'red' })
153
181
  end.to raise_error(Capybara::ExpectationNotMet)
154
182
  end
155
183
 
156
- it "resets the style when done" do
184
+ it 'resets the style when done' do
157
185
  @session.visit('/with_js')
158
- @session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: true)
159
- expect(@session.evaluate_script("arguments[0].style.display", @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
186
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
187
+ expect(@session.evaluate_script('arguments[0].style.display', @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
188
+ end
189
+
190
+ it 'should fire change' do
191
+ @session.visit('/with_js')
192
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
193
+ expect(@session).to have_css('.file_change')
160
194
  end
161
195
  end
162
196
 
163
- private
197
+ context 'with a block', requires: %i[js] do
198
+ it 'can upload by clicking the file input' do
199
+ @session.attach_file(with_os_path_separators(__FILE__)) do
200
+ @session.find(:file_field, 'form[image]').click
201
+ end
202
+ @session.click_button('awesome')
203
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
204
+ end
205
+
206
+ it 'can upload by clicking the label' do
207
+ @session.attach_file(with_os_path_separators(__FILE__)) do
208
+ @session.find(:label, 'Hidden Image').click
209
+ end
210
+ @session.click_button('awesome')
211
+ expect(extract_results(@session)['hidden_image']).to end_with(File.basename(__FILE__))
212
+ end
164
213
 
165
- def with_os_path_separators(path)
166
- Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
214
+ it 'should fire change' do
215
+ @session.visit('/with_js')
216
+ @session.attach_file(with_os_path_separators(__FILE__)) do
217
+ @session.find(:label, 'Label for hidden file input').click
218
+ end
219
+ expect(@session).to have_css('.file_change')
220
+ end
167
221
  end
168
222
  end
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara::SpecHelper.spec '#body' do
4
- it "should return the unmodified page body" do
4
+ it 'should return the unmodified page body' do
5
5
  @session.visit('/')
6
6
  expect(@session).to have_content('Hello world!') # wait for content to appear if visit is async
7
7
  expect(@session.body).to include('Hello world!')
8
8
  end
9
9
 
10
- context "encoding of response between ascii and utf8" do
11
- it "should be valid with html entities" do
10
+ context 'encoding of response between ascii and utf8' do
11
+ it 'should be valid with html entities' do
12
12
  @session.visit('/with_html_entities')
13
13
  expect(@session).to have_content('Encoding') # wait for content to appear if visit is async
14
- expect { @session.body.encode!("UTF-8") }.not_to raise_error
14
+ expect { @session.body.encode!('UTF-8') }.not_to raise_error
15
15
  end
16
16
 
17
- it "should be valid without html entities" do
17
+ it 'should be valid without html entities' do
18
18
  @session.visit('/with_html')
19
19
  expect(@session).to have_content('This is a test') # wait for content to appear if visit is async
20
- expect { @session.body.encode!("UTF-8") }.not_to raise_error
20
+ expect { @session.body.encode!('UTF-8') }.not_to raise_error
21
21
  end
22
22
  end
23
23
  end