capybara 3.8.1 → 3.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +465 -0
  4. data/License.txt +1 -1
  5. data/README.md +58 -57
  6. data/lib/capybara/config.rb +10 -4
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +2 -2
  9. data/lib/capybara/driver/node.rb +26 -5
  10. data/lib/capybara/dsl.rb +12 -4
  11. data/lib/capybara/helpers.rb +8 -4
  12. data/lib/capybara/minitest/spec.rb +162 -85
  13. data/lib/capybara/minitest.rb +248 -148
  14. data/lib/capybara/node/actions.rb +149 -96
  15. data/lib/capybara/node/base.rb +27 -10
  16. data/lib/capybara/node/document.rb +12 -0
  17. data/lib/capybara/node/document_matchers.rb +9 -5
  18. data/lib/capybara/node/element.rb +254 -109
  19. data/lib/capybara/node/finders.rb +83 -76
  20. data/lib/capybara/node/matchers.rb +279 -141
  21. data/lib/capybara/node/simple.rb +25 -6
  22. data/lib/capybara/queries/ancestor_query.rb +5 -7
  23. data/lib/capybara/queries/base_query.rb +11 -5
  24. data/lib/capybara/queries/current_path_query.rb +3 -3
  25. data/lib/capybara/queries/match_query.rb +1 -0
  26. data/lib/capybara/queries/selector_query.rb +467 -103
  27. data/lib/capybara/queries/sibling_query.rb +5 -4
  28. data/lib/capybara/queries/style_query.rb +6 -2
  29. data/lib/capybara/queries/text_query.rb +17 -3
  30. data/lib/capybara/queries/title_query.rb +2 -2
  31. data/lib/capybara/rack_test/browser.rb +22 -15
  32. data/lib/capybara/rack_test/driver.rb +10 -1
  33. data/lib/capybara/rack_test/errors.rb +6 -0
  34. data/lib/capybara/rack_test/form.rb +33 -28
  35. data/lib/capybara/rack_test/node.rb +74 -6
  36. data/lib/capybara/registration_container.rb +44 -0
  37. data/lib/capybara/registrations/drivers.rb +36 -0
  38. data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
  39. data/lib/capybara/registrations/servers.rb +44 -0
  40. data/lib/capybara/result.rb +55 -23
  41. data/lib/capybara/rspec/features.rb +4 -4
  42. data/lib/capybara/rspec/matcher_proxies.rb +36 -15
  43. data/lib/capybara/rspec/matchers/base.rb +111 -0
  44. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  45. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  46. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  47. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  48. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  49. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  50. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  51. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  52. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  53. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  54. data/lib/capybara/rspec/matchers/match_style.rb +38 -0
  55. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  56. data/lib/capybara/rspec/matchers.rb +117 -311
  57. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  58. data/lib/capybara/selector/builders/xpath_builder.rb +69 -0
  59. data/lib/capybara/selector/css.rb +17 -15
  60. data/lib/capybara/selector/definition/button.rb +52 -0
  61. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  62. data/lib/capybara/selector/definition/css.rb +10 -0
  63. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  64. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  65. data/lib/capybara/selector/definition/element.rb +27 -0
  66. data/lib/capybara/selector/definition/field.rb +40 -0
  67. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  68. data/lib/capybara/selector/definition/file_field.rb +13 -0
  69. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  70. data/lib/capybara/selector/definition/frame.rb +17 -0
  71. data/lib/capybara/selector/definition/id.rb +6 -0
  72. data/lib/capybara/selector/definition/label.rb +62 -0
  73. data/lib/capybara/selector/definition/link.rb +54 -0
  74. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  75. data/lib/capybara/selector/definition/option.rb +27 -0
  76. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  77. data/lib/capybara/selector/definition/select.rb +81 -0
  78. data/lib/capybara/selector/definition/table.rb +109 -0
  79. data/lib/capybara/selector/definition/table_row.rb +21 -0
  80. data/lib/capybara/selector/definition/xpath.rb +5 -0
  81. data/lib/capybara/selector/definition.rb +277 -0
  82. data/lib/capybara/selector/filter.rb +1 -0
  83. data/lib/capybara/selector/filter_set.rb +26 -19
  84. data/lib/capybara/selector/filters/base.rb +24 -5
  85. data/lib/capybara/selector/filters/expression_filter.rb +3 -3
  86. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  87. data/lib/capybara/selector/filters/node_filter.rb +16 -2
  88. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  89. data/lib/capybara/selector/selector.rb +73 -367
  90. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  91. data/lib/capybara/selector.rb +221 -480
  92. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  93. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  94. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  95. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  96. data/lib/capybara/selenium/driver.rb +203 -86
  97. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +88 -14
  98. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
  99. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
  100. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  101. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  102. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  103. data/lib/capybara/selenium/extensions/find.rb +110 -0
  104. data/lib/capybara/selenium/extensions/html5_drag.rb +191 -22
  105. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  106. data/lib/capybara/selenium/extensions/scroll.rb +78 -0
  107. data/lib/capybara/selenium/logger_suppressor.rb +34 -0
  108. data/lib/capybara/selenium/node.rb +298 -93
  109. data/lib/capybara/selenium/nodes/chrome_node.rb +100 -8
  110. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  111. data/lib/capybara/selenium/nodes/firefox_node.rb +131 -0
  112. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  113. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  114. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  115. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  116. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  117. data/lib/capybara/selenium/patches/logs.rb +45 -0
  118. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -3
  119. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  120. data/lib/capybara/server/animation_disabler.rb +4 -3
  121. data/lib/capybara/server/checker.rb +6 -2
  122. data/lib/capybara/server/middleware.rb +23 -13
  123. data/lib/capybara/server.rb +30 -7
  124. data/lib/capybara/session/config.rb +14 -10
  125. data/lib/capybara/session/matchers.rb +11 -7
  126. data/lib/capybara/session.rb +152 -111
  127. data/lib/capybara/spec/public/offset.js +6 -0
  128. data/lib/capybara/spec/public/test.js +101 -10
  129. data/lib/capybara/spec/session/all_spec.rb +96 -6
  130. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  131. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +29 -0
  132. data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
  133. data/lib/capybara/spec/session/assert_selector_spec.rb +0 -10
  134. data/lib/capybara/spec/session/assert_style_spec.rb +4 -4
  135. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  136. data/lib/capybara/spec/session/attach_file_spec.rb +63 -36
  137. data/lib/capybara/spec/session/check_spec.rb +10 -4
  138. data/lib/capybara/spec/session/choose_spec.rb +8 -2
  139. data/lib/capybara/spec/session/click_button_spec.rb +117 -61
  140. data/lib/capybara/spec/session/click_link_or_button_spec.rb +16 -0
  141. data/lib/capybara/spec/session/click_link_spec.rb +17 -6
  142. data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
  143. data/lib/capybara/spec/session/evaluate_script_spec.rb +13 -0
  144. data/lib/capybara/spec/session/execute_script_spec.rb +1 -0
  145. data/lib/capybara/spec/session/fill_in_spec.rb +47 -6
  146. data/lib/capybara/spec/session/find_field_spec.rb +1 -1
  147. data/lib/capybara/spec/session/find_spec.rb +74 -4
  148. data/lib/capybara/spec/session/first_spec.rb +1 -1
  149. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +13 -1
  150. data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
  151. data/lib/capybara/spec/session/has_all_selectors_spec.rb +1 -1
  152. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  153. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  154. data/lib/capybara/spec/session/has_button_spec.rb +16 -0
  155. data/lib/capybara/spec/session/has_css_spec.rb +122 -12
  156. data/lib/capybara/spec/session/has_current_path_spec.rb +6 -4
  157. data/lib/capybara/spec/session/has_field_spec.rb +55 -0
  158. data/lib/capybara/spec/session/has_select_spec.rb +34 -6
  159. data/lib/capybara/spec/session/has_selector_spec.rb +11 -4
  160. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  161. data/lib/capybara/spec/session/has_table_spec.rb +166 -0
  162. data/lib/capybara/spec/session/has_text_spec.rb +48 -1
  163. data/lib/capybara/spec/session/has_xpath_spec.rb +17 -0
  164. data/lib/capybara/spec/session/html_spec.rb +7 -0
  165. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  166. data/lib/capybara/spec/session/node_spec.rb +643 -18
  167. data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
  168. data/lib/capybara/spec/session/refresh_spec.rb +4 -0
  169. data/lib/capybara/spec/session/reset_session_spec.rb +23 -8
  170. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  171. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  172. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  173. data/lib/capybara/spec/session/select_spec.rb +10 -10
  174. data/lib/capybara/spec/session/selectors_spec.rb +36 -5
  175. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  176. data/lib/capybara/spec/session/unselect_spec.rb +1 -1
  177. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  178. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +4 -0
  179. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +4 -0
  180. data/lib/capybara/spec/session/window/window_spec.rb +59 -58
  181. data/lib/capybara/spec/session/window/windows_spec.rb +4 -0
  182. data/lib/capybara/spec/session/within_spec.rb +23 -0
  183. data/lib/capybara/spec/spec_helper.rb +16 -6
  184. data/lib/capybara/spec/test_app.rb +28 -23
  185. data/lib/capybara/spec/views/animated.erb +49 -0
  186. data/lib/capybara/spec/views/form.erb +48 -7
  187. data/lib/capybara/spec/views/frame_child.erb +3 -2
  188. data/lib/capybara/spec/views/frame_one.erb +1 -0
  189. data/lib/capybara/spec/views/obscured.erb +47 -0
  190. data/lib/capybara/spec/views/offset.erb +32 -0
  191. data/lib/capybara/spec/views/react.erb +45 -0
  192. data/lib/capybara/spec/views/scroll.erb +20 -0
  193. data/lib/capybara/spec/views/spatial.erb +31 -0
  194. data/lib/capybara/spec/views/tables.erb +67 -0
  195. data/lib/capybara/spec/views/with_animation.erb +29 -1
  196. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  197. data/lib/capybara/spec/views/with_hover.erb +1 -0
  198. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  199. data/lib/capybara/spec/views/with_html.erb +32 -6
  200. data/lib/capybara/spec/views/with_js.erb +3 -1
  201. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  202. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  203. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  204. data/lib/capybara/version.rb +1 -1
  205. data/lib/capybara/window.rb +11 -11
  206. data/lib/capybara.rb +118 -111
  207. data/spec/basic_node_spec.rb +14 -3
  208. data/spec/capybara_spec.rb +29 -29
  209. data/spec/css_builder_spec.rb +101 -0
  210. data/spec/dsl_spec.rb +46 -21
  211. data/spec/filter_set_spec.rb +5 -5
  212. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  213. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  214. data/spec/minitest_spec.rb +18 -4
  215. data/spec/minitest_spec_spec.rb +59 -44
  216. data/spec/rack_test_spec.rb +117 -89
  217. data/spec/regexp_dissassembler_spec.rb +250 -0
  218. data/spec/result_spec.rb +51 -49
  219. data/spec/rspec/features_spec.rb +3 -0
  220. data/spec/rspec/shared_spec_matchers.rb +112 -97
  221. data/spec/rspec_spec.rb +35 -17
  222. data/spec/sauce_spec_chrome.rb +43 -0
  223. data/spec/selector_spec.rb +244 -28
  224. data/spec/selenium_spec_chrome.rb +125 -54
  225. data/spec/selenium_spec_chrome_remote.rb +26 -12
  226. data/spec/selenium_spec_edge.rb +23 -8
  227. data/spec/selenium_spec_firefox.rb +208 -0
  228. data/spec/selenium_spec_firefox_remote.rb +15 -18
  229. data/spec/selenium_spec_ie.rb +82 -13
  230. data/spec/selenium_spec_safari.rb +148 -0
  231. data/spec/server_spec.rb +118 -77
  232. data/spec/session_spec.rb +19 -3
  233. data/spec/shared_selenium_node.rb +83 -0
  234. data/spec/shared_selenium_session.rb +110 -65
  235. data/spec/spec_helper.rb +57 -9
  236. data/spec/xpath_builder_spec.rb +93 -0
  237. metadata +257 -17
  238. data/lib/capybara/rspec/compound.rb +0 -94
  239. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -49
  240. data/lib/capybara/selenium/nodes/marionette_node.rb +0 -121
  241. data/lib/capybara/spec/session/has_style_spec.rb +0 -25
  242. data/spec/selenium_spec_marionette.rb +0 -172
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
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
 
@@ -13,40 +14,40 @@ Capybara::SpecHelper.spec '#attach_file' do
13
14
  it 'should set a file path by id' do
14
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
20
  it 'should set a file path by label' do
20
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
26
  it 'should be able to set on element if no locator passed' do
26
27
  ff = @session.find(:file_field, 'Image')
27
28
  ff.attach_file(with_os_path_separators(__FILE__))
28
29
  @session.click_button('awesome')
29
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
30
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
30
31
  end
31
32
 
32
33
  it 'casts to string' do
33
34
  @session.attach_file :form_image, with_os_path_separators(__FILE__)
34
35
  @session.click_button('awesome')
35
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
36
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
36
37
  end
37
38
  end
38
39
 
39
40
  context 'with multipart form' do
40
41
  it 'should set a file path by id' do
41
- @session.attach_file 'form_document', with_os_path_separators(@test_file_path)
42
+ @session.attach_file 'form_document', with_os_path_separators(test_file_path)
42
43
  @session.click_button('Upload Single')
43
- expect(@session).to have_content(File.read(@test_file_path))
44
+ expect(@session).to have_content(File.read(test_file_path))
44
45
  end
45
46
 
46
47
  it 'should set a file path by label' do
47
- @session.attach_file 'Single Document', with_os_path_separators(@test_file_path)
48
+ @session.attach_file 'Single Document', with_os_path_separators(test_file_path)
48
49
  @session.click_button('Upload Single')
49
- expect(@session).to have_content(File.read(@test_file_path))
50
+ expect(@session).to have_content(File.read(test_file_path))
50
51
  end
51
52
 
52
53
  it 'should not break if no file is submitted' do
@@ -55,37 +56,37 @@ Capybara::SpecHelper.spec '#attach_file' do
55
56
  end
56
57
 
57
58
  it 'should send content type text/plain when uploading a text file' do
58
- @session.attach_file 'Single Document', with_os_path_separators(@test_file_path)
59
+ @session.attach_file 'Single Document', with_os_path_separators(test_file_path)
59
60
  @session.click_button 'Upload Single'
60
61
  expect(@session).to have_content('text/plain')
61
62
  end
62
63
 
63
64
  it 'should send content type image/jpeg when uploading an image' do
64
- @session.attach_file 'Single Document', with_os_path_separators(@test_jpg_file_path)
65
+ @session.attach_file 'Single Document', with_os_path_separators(test_jpg_file_path)
65
66
  @session.click_button 'Upload Single'
66
67
  expect(@session).to have_content('image/jpeg')
67
68
  end
68
69
 
69
70
  it 'should not break when uploading a file without extension' do
70
- @session.attach_file 'Single Document', with_os_path_separators(@no_extension_file_path)
71
+ @session.attach_file 'Single Document', with_os_path_separators(no_extension_file_path)
71
72
  @session.click_button 'Upload Single'
72
- expect(@session).to have_content(File.read(@no_extension_file_path))
73
+ expect(@session).to have_content(File.read(no_extension_file_path))
73
74
  end
74
75
 
75
76
  it 'should not break when using HTML5 multiple file input' do
76
- @session.attach_file 'Multiple Documents', with_os_path_separators(@test_file_path)
77
+ @session.attach_file 'Multiple Documents', with_os_path_separators(test_file_path)
77
78
  @session.click_button('Upload Multiple')
78
- expect(@session).to have_content(File.read(@test_file_path))
79
+ expect(@session).to have_content(File.read(test_file_path))
79
80
  expect(@session.body).to include('1 | ') # number of files
80
81
  end
81
82
 
82
83
  it 'should not break when using HTML5 multiple file input uploading multiple files' do
83
84
  @session.attach_file('Multiple Documents',
84
- [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
85
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
85
86
  @session.click_button('Upload Multiple')
86
- expect(@session.body).to include('2 | ') # number of files
87
- expect(@session.body).to include(File.read(@test_file_path))
88
- expect(@session.body).to include(File.read(@another_test_file_path))
87
+ expect(@session).to have_content('2 | ') # number of files
88
+ expect(@session.body).to include(File.read(test_file_path))
89
+ expect(@session.body).to include(File.read(another_test_file_path))
89
90
  end
90
91
 
91
92
  it 'should not send anything when attaching no files to a multiple upload field' do
@@ -94,35 +95,35 @@ Capybara::SpecHelper.spec '#attach_file' do
94
95
  end
95
96
 
96
97
  it 'should not append files to already attached' do
97
- @session.attach_file 'Multiple Documents', with_os_path_separators(@test_file_path)
98
- @session.attach_file 'Multiple Documents', with_os_path_separators(@another_test_file_path)
98
+ @session.attach_file 'Multiple Documents', with_os_path_separators(test_file_path)
99
+ @session.attach_file 'Multiple Documents', with_os_path_separators(another_test_file_path)
99
100
  @session.click_button('Upload Multiple')
100
- expect(@session.body).to include('1 | ') # number of files
101
- expect(@session.body).to include(File.read(@another_test_file_path))
102
- expect(@session.body).not_to include(File.read(@test_file_path))
101
+ expect(@session).to have_content('1 | ') # number of files
102
+ expect(@session.body).to include(File.read(another_test_file_path))
103
+ expect(@session.body).not_to include(File.read(test_file_path))
103
104
  end
104
105
 
105
106
  it 'should fire change once when uploading multiple files from empty', requires: [:js] do
106
107
  @session.visit('with_js')
107
108
  @session.attach_file('multiple-file',
108
- [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
109
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
109
110
  expect(@session).to have_css('.file_change', count: 1)
110
111
  end
111
112
 
112
113
  it 'should fire change once for each set of files uploaded', requires: [:js] do
113
114
  @session.visit('with_js')
114
- @session.attach_file('multiple-file', [@test_jpg_file_path].map { |f| with_os_path_separators(f) })
115
+ @session.attach_file('multiple-file', [test_jpg_file_path].map { |f| with_os_path_separators(f) })
115
116
  @session.attach_file('multiple-file',
116
- [@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
117
+ [test_file_path, another_test_file_path].map { |f| with_os_path_separators(f) })
117
118
  expect(@session).to have_css('.file_change', count: 2)
118
119
  end
119
120
  end
120
121
 
121
122
  context "with a locator that doesn't exist" do
122
123
  it 'should raise an error' do
123
- msg = 'Unable to find file field "does not exist"'
124
+ msg = /Unable to find file field "does not exist"/
124
125
  expect do
125
- @session.attach_file('does not exist', with_os_path_separators(@test_file_path))
126
+ @session.attach_file('does not exist', with_os_path_separators(test_file_path))
126
127
  end.to raise_error(Capybara::ElementNotFound, msg)
127
128
  end
128
129
  end
@@ -137,7 +138,7 @@ Capybara::SpecHelper.spec '#attach_file' do
137
138
  it 'should set a file path by partial label when false' do
138
139
  @session.attach_file 'Imag', with_os_path_separators(__FILE__), exact: false
139
140
  @session.click_button('awesome')
140
- expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
141
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
141
142
  end
142
143
 
143
144
  it 'should not allow partial matches when true' do
@@ -179,11 +180,37 @@ Capybara::SpecHelper.spec '#attach_file' do
179
180
  @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
180
181
  expect(@session.evaluate_script('arguments[0].style.display', @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
181
182
  end
183
+
184
+ it 'should fire change' do
185
+ @session.visit('/with_js')
186
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
187
+ expect(@session).to have_css('.file_change')
188
+ end
182
189
  end
183
190
 
184
- private
191
+ context 'with a block', requires: %i[js] do
192
+ it 'can upload by clicking the file input' do
193
+ @session.attach_file(with_os_path_separators(__FILE__)) do
194
+ @session.find(:file_field, 'form[image]').click
195
+ end
196
+ @session.click_button('awesome')
197
+ expect(extract_results(@session)['image']).to end_with(File.basename(__FILE__))
198
+ end
199
+
200
+ it 'can upload by clicking the label' do
201
+ @session.attach_file(with_os_path_separators(__FILE__)) do
202
+ @session.find(:label, 'Hidden Image').click
203
+ end
204
+ @session.click_button('awesome')
205
+ expect(extract_results(@session)['hidden_image']).to end_with(File.basename(__FILE__))
206
+ end
185
207
 
186
- def with_os_path_separators(path)
187
- Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
208
+ it 'should fire change' do
209
+ @session.visit('/with_js')
210
+ @session.attach_file(with_os_path_separators(__FILE__)) do
211
+ @session.find(:label, 'Label for hidden file input').click
212
+ end
213
+ expect(@session).to have_css('.file_change')
214
+ end
188
215
  end
189
216
  end
@@ -83,7 +83,7 @@ Capybara::SpecHelper.spec '#check' do
83
83
 
84
84
  context "with a locator that doesn't exist" do
85
85
  it 'should raise an error' do
86
- msg = 'Unable to find checkbox "does not exist"'
86
+ msg = /Unable to find checkbox "does not exist"/
87
87
  expect do
88
88
  @session.check('does not exist')
89
89
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -120,6 +120,12 @@ Capybara::SpecHelper.spec '#check' do
120
120
  expect(extract_results(@session)['pets']).to include('cat')
121
121
  end
122
122
 
123
+ it 'should alias `with`' do
124
+ @session.check('form[pets][]', with: 'cat')
125
+ @session.click_button('awesome')
126
+ expect(extract_results(@session)['pets']).to include('cat')
127
+ end
128
+
123
129
  it 'should raise an error if option not found' do
124
130
  expect do
125
131
  @session.check('form[pets][]', option: 'elephant')
@@ -171,11 +177,11 @@ Capybara::SpecHelper.spec '#check' do
171
177
  end
172
178
 
173
179
  it 'should raise original error when no label available' do
174
- expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_ariel"')
180
+ expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_ariel"/)
175
181
  end
176
182
 
177
183
  it 'should raise error if not allowed to click label' do
178
- expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren"')
184
+ expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/)
179
185
  end
180
186
  end
181
187
 
@@ -187,7 +193,7 @@ Capybara::SpecHelper.spec '#check' do
187
193
  end
188
194
 
189
195
  it 'should raise error if checkbox not visible' do
190
- expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren"')
196
+ expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/)
191
197
  end
192
198
 
193
199
  it 'should include node filter in error if verified' do
@@ -38,7 +38,7 @@ Capybara::SpecHelper.spec '#choose' do
38
38
 
39
39
  context "with a locator that doesn't exist" do
40
40
  it 'should raise an error' do
41
- msg = 'Unable to find radio button "does not exist"'
41
+ msg = /Unable to find radio button "does not exist"/
42
42
  expect do
43
43
  @session.choose('does not exist')
44
44
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -74,6 +74,12 @@ Capybara::SpecHelper.spec '#choose' do
74
74
  expect(extract_results(@session)['gender']).to eq('male')
75
75
  end
76
76
 
77
+ it 'should alias `:with` option' do
78
+ @session.choose('form[gender]', with: 'male')
79
+ @session.click_button('awesome')
80
+ expect(extract_results(@session)['gender']).to eq('male')
81
+ end
82
+
77
83
  it 'should raise an error if option not found' do
78
84
  expect do
79
85
  @session.choose('form[gender]', option: 'hermaphrodite')
@@ -103,7 +109,7 @@ Capybara::SpecHelper.spec '#choose' do
103
109
  end
104
110
 
105
111
  it 'should raise error if not allowed to click label' do
106
- expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible radio button "party_democrat"')
112
+ expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible radio button "party_democrat"/)
107
113
  end
108
114
  end
109
115
  end
@@ -7,8 +7,10 @@ Capybara::SpecHelper.spec '#click_button' do
7
7
 
8
8
  it 'should wait for asynchronous load', requires: [:js] do
9
9
  @session.visit('/with_js')
10
- @session.click_link('Click me')
11
- @session.click_button('New Here')
10
+ @session.using_wait_time(1.5) do
11
+ @session.click_link('Click me')
12
+ @session.click_button('New Here')
13
+ end
12
14
  end
13
15
 
14
16
  it 'casts to string' do
@@ -43,111 +45,113 @@ Capybara::SpecHelper.spec '#click_button' do
43
45
 
44
46
  context 'with value given on a submit button' do
45
47
  context 'on a form with HTML5 fields' do
48
+ let(:results) { extract_results(@session) }
49
+
46
50
  before do
47
51
  @session.click_button('html5_submit')
48
- @results = extract_results(@session)
49
52
  end
50
53
 
51
54
  it 'should serialise and submit search fields' do
52
- expect(@results['html5_search']).to eq('what are you looking for')
55
+ expect(results['html5_search']).to eq('what are you looking for')
53
56
  end
54
57
 
55
58
  it 'should serialise and submit email fields' do
56
- expect(@results['html5_email']).to eq('person@email.com')
59
+ expect(results['html5_email']).to eq('person@email.com')
57
60
  end
58
61
 
59
62
  it 'should serialise and submit url fields' do
60
- expect(@results['html5_url']).to eq('http://www.example.com')
63
+ expect(results['html5_url']).to eq('http://www.example.com')
61
64
  end
62
65
 
63
66
  it 'should serialise and submit tel fields' do
64
- expect(@results['html5_tel']).to eq('911')
67
+ expect(results['html5_tel']).to eq('911')
65
68
  end
66
69
 
67
70
  it 'should serialise and submit color fields' do
68
- expect(@results['html5_color'].upcase).to eq('#FFFFFF')
71
+ expect(results['html5_color'].upcase).to eq('#FFFFFF')
69
72
  end
70
73
  end
71
74
 
72
75
  context 'on an HTML4 form' do
76
+ let(:results) { extract_results(@session) }
77
+
73
78
  before do
74
79
  @session.click_button('awesome')
75
- @results = extract_results(@session)
76
80
  end
77
81
 
78
82
  it 'should serialize and submit text fields' do
79
- expect(@results['first_name']).to eq('John')
83
+ expect(results['first_name']).to eq('John')
80
84
  end
81
85
 
82
86
  it 'should escape fields when submitting' do
83
- expect(@results['phone']).to eq('+1 555 7021')
87
+ expect(results['phone']).to eq('+1 555 7021')
84
88
  end
85
89
 
86
90
  it 'should serialize and submit password fields' do
87
- expect(@results['password']).to eq('seeekrit')
91
+ expect(results['password']).to eq('seeekrit')
88
92
  end
89
93
 
90
94
  it 'should serialize and submit hidden fields' do
91
- expect(@results['token']).to eq('12345')
95
+ expect(results['token']).to eq('12345')
92
96
  end
93
97
 
94
98
  it 'should not serialize fields from other forms' do
95
- expect(@results['middle_name']).to be_nil
99
+ expect(results['middle_name']).to be_nil
96
100
  end
97
101
 
98
102
  it 'should submit the button that was clicked, but not other buttons' do
99
- expect(@results['awesome']).to eq('awesome')
100
- expect(@results['crappy']).to be_nil
103
+ expect(results['awesome']).to eq('awesome')
104
+ expect(results['crappy']).to be_nil
101
105
  end
102
106
 
103
107
  it 'should serialize radio buttons' do
104
- expect(@results['gender']).to eq('female')
108
+ expect(results['gender']).to eq('female')
105
109
  end
106
110
 
107
111
  it "should default radio value to 'on' if none specified" do
108
- expect(@results['valueless_radio']).to eq('on')
112
+ expect(results['valueless_radio']).to eq('on')
109
113
  end
110
114
 
111
115
  it 'should serialize check boxes' do
112
- expect(@results['pets']).to include('dog', 'hamster')
113
- expect(@results['pets']).not_to include('cat')
116
+ expect(results['pets']).to include('dog', 'hamster')
117
+ expect(results['pets']).not_to include('cat')
114
118
  end
115
119
 
116
120
  it "should default checkbox value to 'on' if none specififed" do
117
- expect(@results['valueless_checkbox']).to eq('on')
121
+ expect(results['valueless_checkbox']).to eq('on')
118
122
  end
119
123
 
120
124
  it 'should serialize text areas' do
121
- expect(@results['description']).to eq('Descriptive text goes here')
125
+ expect(results['description']).to eq('Descriptive text goes here')
122
126
  end
123
127
 
124
128
  it 'should serialize select tag with values' do
125
- expect(@results['locale']).to eq('en')
129
+ expect(results['locale']).to eq('en')
126
130
  end
127
131
 
128
132
  it 'should serialize select tag without values' do
129
- expect(@results['region']).to eq('Norway')
133
+ expect(results['region']).to eq('Norway')
130
134
  end
131
135
 
132
136
  it 'should serialize first option for select tag with no selection' do
133
- expect(@results['city']).to eq('London')
137
+ expect(results['city']).to eq('London')
134
138
  end
135
139
 
136
140
  it 'should not serialize a select tag without options' do
137
- expect(@results['tendency']).to be_nil
141
+ expect(results['tendency']).to be_nil
138
142
  end
139
143
 
140
144
  it 'should convert lf to cr/lf in submitted textareas' do
141
- expect(@results['newline']).to eq("\r\nNew line after and before textarea tag\r\n")
145
+ expect(results['newline']).to eq("\r\nNew line after and before textarea tag\r\n")
142
146
  end
143
147
 
144
148
  it 'should not submit disabled fields' do
145
- expect(@results['disabled_text_field']).to be_nil
146
- expect(@results['disabled_textarea']).to be_nil
147
- expect(@results['disabled_checkbox']).to be_nil
148
- expect(@results['disabled_radio']).to be_nil
149
- expect(@results['disabled_select']).to be_nil
150
- expect(@results['disabled_file']).to be_nil
149
+ expect(results['disabled_text_field']).to be_nil
150
+ expect(results['disabled_textarea']).to be_nil
151
+ expect(results['disabled_checkbox']).to be_nil
152
+ expect(results['disabled_radio']).to be_nil
153
+ expect(results['disabled_select']).to be_nil
154
+ expect(results['disabled_file']).to be_nil
151
155
  end
152
156
  end
153
157
  end
@@ -158,6 +162,11 @@ Capybara::SpecHelper.spec '#click_button' do
158
162
  expect(extract_results(@session)['first_name']).to eq('John')
159
163
  end
160
164
 
165
+ it 'should submit by specific button id' do
166
+ @session.click_button(id: 'awe123')
167
+ expect(extract_results(@session)['first_name']).to eq('John')
168
+ end
169
+
161
170
  it 'should submit by button title' do
162
171
  @session.click_button('What an Awesome Button')
163
172
  expect(extract_results(@session)['first_name']).to eq('John')
@@ -167,60 +176,89 @@ Capybara::SpecHelper.spec '#click_button' do
167
176
  @session.click_button('What an Awesome')
168
177
  expect(extract_results(@session)['first_name']).to eq('John')
169
178
  end
179
+
180
+ it 'should submit by button name' do
181
+ @session.click_button('form[awesome]')
182
+ expect(extract_results(@session)['first_name']).to eq('John')
183
+ end
184
+
185
+ it 'should submit by specific button name' do
186
+ @session.click_button(name: 'form[awesome]')
187
+ expect(extract_results(@session)['first_name']).to eq('John')
188
+ end
189
+
190
+ it 'should submit by specific button name regex' do
191
+ @session.click_button(name: /form\[awes.*\]/)
192
+ expect(extract_results(@session)['first_name']).to eq('John')
193
+ end
194
+ end
195
+
196
+ context 'when Capybara.enable_aria_role = true' do
197
+ it 'should click on a button role', requires: [:js] do
198
+ Capybara.enable_aria_role = true
199
+ @session.using_wait_time(1.5) do
200
+ @session.visit('/with_js')
201
+ @session.click_button('ARIA button')
202
+ expect(@session).to have_button('ARIA button has been clicked')
203
+ end
204
+ end
170
205
  end
171
206
 
172
207
  context 'with fields associated with the form using the form attribute', requires: [:form_attribute] do
208
+ let(:results) { extract_results(@session) }
209
+
173
210
  before do
174
211
  @session.click_button('submit_form1')
175
- @results = extract_results(@session)
176
212
  end
177
213
 
178
214
  it 'should serialize and submit text fields' do
179
- expect(@results['outside_input']).to eq('outside_input')
215
+ expect(results['outside_input']).to eq('outside_input')
180
216
  end
181
217
 
182
218
  it 'should serialize text areas' do
183
- expect(@results['outside_textarea']).to eq('Some text here')
219
+ expect(results['outside_textarea']).to eq('Some text here')
184
220
  end
185
221
 
186
222
  it 'should serialize select tags' do
187
- expect(@results['outside_select']).to eq('Ruby')
223
+ expect(results['outside_select']).to eq('Ruby')
188
224
  end
189
225
 
190
226
  it 'should not serliaze fields associated with a different form' do
191
- expect(@results['for_form2']).to be_nil
227
+ expect(results['for_form2']).to be_nil
192
228
  end
193
229
  end
194
230
 
195
231
  context 'with submit button outside the form defined by <button> tag', requires: [:form_attribute] do
232
+ let(:results) { extract_results(@session) }
233
+
196
234
  before do
197
235
  @session.click_button('outside_button')
198
- @results = extract_results(@session)
199
236
  end
200
237
 
201
238
  it 'should submit the associated form' do
202
- expect(@results['which_form']).to eq('form2')
239
+ expect(results['which_form']).to eq('form2')
203
240
  end
204
241
 
205
242
  it 'should submit the button that was clicked, but not other buttons' do
206
- expect(@results['outside_button']).to eq('outside_button')
207
- expect(@results['unused']).to be_nil
243
+ expect(results['outside_button']).to eq('outside_button')
244
+ expect(results['unused']).to be_nil
208
245
  end
209
246
  end
210
247
 
211
248
  context "with submit button outside the form defined by <input type='submit'> tag", requires: [:form_attribute] do
249
+ let(:results) { extract_results(@session) }
250
+
212
251
  before do
213
252
  @session.click_button('outside_submit')
214
- @results = extract_results(@session)
215
253
  end
216
254
 
217
255
  it 'should submit the associated form' do
218
- expect(@results['which_form']).to eq('form1')
256
+ expect(results['which_form']).to eq('form1')
219
257
  end
220
258
 
221
259
  it 'should submit the button that was clicked, but not other buttons' do
222
- expect(@results['outside_submit']).to eq('outside_submit')
223
- expect(@results['submit_form1']).to be_nil
260
+ expect(results['outside_submit']).to eq('outside_submit')
261
+ expect(results['submit_form1']).to be_nil
224
262
  end
225
263
  end
226
264
 
@@ -301,9 +339,21 @@ Capybara::SpecHelper.spec '#click_button' do
301
339
  it 'should serialize and send GET forms' do
302
340
  @session.visit('/form')
303
341
  @session.click_button('med')
304
- @results = extract_results(@session)
305
- expect(@results['middle_name']).to eq('Darren')
306
- expect(@results['foo']).to be_nil
342
+ results = extract_results(@session)
343
+ expect(results['middle_name']).to eq('Darren')
344
+ expect(results['foo']).to be_nil
345
+ end
346
+ end
347
+
348
+ context 'with name given on a button defined by <button> tag' do
349
+ it 'should submit the associated form when name is locator' do
350
+ @session.click_button('form[no_value]')
351
+ expect(extract_results(@session)['first_name']).to eq('John')
352
+ end
353
+
354
+ it 'should submit the associated form when name is specific' do
355
+ @session.click_button(name: 'form[no_value]')
356
+ expect(extract_results(@session)['first_name']).to eq('John')
307
357
  end
308
358
  end
309
359
 
@@ -345,7 +395,7 @@ Capybara::SpecHelper.spec '#click_button' do
345
395
 
346
396
  context "with a locator that doesn't exist" do
347
397
  it 'should raise an error' do
348
- msg = 'Unable to find button "does not exist"'
398
+ msg = /Unable to find button "does not exist"/
349
399
  expect do
350
400
  @session.click_button('does not exist')
351
401
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -355,39 +405,45 @@ Capybara::SpecHelper.spec '#click_button' do
355
405
  context 'with formaction attribute on button' do
356
406
  it 'should submit to the formaction attribute' do
357
407
  @session.click_button('Formaction button')
358
- @results = extract_results(@session)
408
+ results = extract_results(@session)
359
409
  expect(@session.current_path).to eq '/form'
360
- expect(@results['which_form']).to eq 'formaction form'
410
+ expect(results['which_form']).to eq 'formaction form'
361
411
  end
362
412
  end
363
413
 
364
414
  context 'with formmethod attribute on button' do
365
415
  it 'should submit to the formethod attribute' do
366
416
  @session.click_button('Formmethod button')
367
- @results = extract_results(@session)
417
+ results = extract_results(@session)
368
418
  expect(@session.current_path).to eq '/form/get'
369
- expect(@results['which_form']).to eq 'formaction form'
419
+ expect(results['which_form']).to eq 'formaction form'
370
420
  end
371
421
  end
372
422
 
373
423
  it 'should serialize and send valueless buttons that were clicked' do
374
424
  @session.click_button('No Value!')
375
- @results = extract_results(@session)
376
- expect(@results['no_value']).not_to be_nil
425
+ results = extract_results(@session)
426
+ expect(results['no_value']).not_to be_nil
427
+ end
428
+
429
+ it 'should send button in document order' do
430
+ @session.click_button('outside_button')
431
+ results = extract_results(@session)
432
+ expect(results.keys).to eq %w[for_form2 outside_button which_form post_count]
377
433
  end
378
434
 
379
435
  it 'should not send image buttons that were not clicked' do
380
436
  @session.click_button('Click me!')
381
- @results = extract_results(@session)
382
- expect(@results['okay']).to be_nil
437
+ results = extract_results(@session)
438
+ expect(results['okay']).to be_nil
383
439
  end
384
440
 
385
441
  it 'should serialize and send GET forms' do
386
442
  @session.visit('/form')
387
443
  @session.click_button('med')
388
- @results = extract_results(@session)
389
- expect(@results['middle_name']).to eq('Darren')
390
- expect(@results['foo']).to be_nil
444
+ results = extract_results(@session)
445
+ expect(results['middle_name']).to eq('Darren')
446
+ expect(results['foo']).to be_nil
391
447
  end
392
448
 
393
449
  it 'should follow redirects' do