capybara 3.13.2 → 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 (260) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +587 -16
  4. data/README.md +240 -90
  5. data/lib/capybara/config.rb +24 -11
  6. data/lib/capybara/cucumber.rb +1 -1
  7. data/lib/capybara/driver/base.rb +8 -0
  8. data/lib/capybara/driver/node.rb +20 -4
  9. data/lib/capybara/dsl.rb +5 -3
  10. data/lib/capybara/helpers.rb +25 -4
  11. data/lib/capybara/minitest/spec.rb +174 -90
  12. data/lib/capybara/minitest.rb +256 -142
  13. data/lib/capybara/node/actions.rb +123 -77
  14. data/lib/capybara/node/base.rb +20 -12
  15. data/lib/capybara/node/document.rb +2 -2
  16. data/lib/capybara/node/document_matchers.rb +3 -3
  17. data/lib/capybara/node/element.rb +223 -117
  18. data/lib/capybara/node/finders.rb +81 -71
  19. data/lib/capybara/node/matchers.rb +271 -134
  20. data/lib/capybara/node/simple.rb +18 -5
  21. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  22. data/lib/capybara/queries/active_element_query.rb +18 -0
  23. data/lib/capybara/queries/ancestor_query.rb +8 -9
  24. data/lib/capybara/queries/base_query.rb +3 -2
  25. data/lib/capybara/queries/current_path_query.rb +15 -5
  26. data/lib/capybara/queries/selector_query.rb +364 -54
  27. data/lib/capybara/queries/sibling_query.rb +8 -6
  28. data/lib/capybara/queries/style_query.rb +2 -2
  29. data/lib/capybara/queries/text_query.rb +13 -1
  30. data/lib/capybara/queries/title_query.rb +1 -1
  31. data/lib/capybara/rack_test/browser.rb +76 -11
  32. data/lib/capybara/rack_test/driver.rb +10 -5
  33. data/lib/capybara/rack_test/errors.rb +6 -0
  34. data/lib/capybara/rack_test/form.rb +31 -9
  35. data/lib/capybara/rack_test/node.rb +74 -23
  36. data/lib/capybara/registration_container.rb +41 -0
  37. data/lib/capybara/registrations/drivers.rb +42 -0
  38. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  39. data/lib/capybara/registrations/servers.rb +66 -0
  40. data/lib/capybara/result.rb +44 -20
  41. data/lib/capybara/rspec/matcher_proxies.rb +13 -11
  42. data/lib/capybara/rspec/matchers/base.rb +31 -16
  43. data/lib/capybara/rspec/matchers/compound.rb +1 -1
  44. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  45. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  46. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  47. data/lib/capybara/rspec/matchers/have_selector.rb +21 -21
  48. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  49. data/lib/capybara/rspec/matchers/have_text.rb +4 -4
  50. data/lib/capybara/rspec/matchers/have_title.rb +2 -2
  51. data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
  52. data/lib/capybara/rspec/matchers/match_style.rb +7 -2
  53. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  54. data/lib/capybara/rspec/matchers.rb +111 -68
  55. data/lib/capybara/rspec.rb +2 -0
  56. data/lib/capybara/selector/builders/css_builder.rb +11 -7
  57. data/lib/capybara/selector/builders/xpath_builder.rb +5 -3
  58. data/lib/capybara/selector/css.rb +11 -9
  59. data/lib/capybara/selector/definition/button.rb +68 -0
  60. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  61. data/lib/capybara/selector/definition/css.rb +10 -0
  62. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  63. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  64. data/lib/capybara/selector/definition/element.rb +28 -0
  65. data/lib/capybara/selector/definition/field.rb +40 -0
  66. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  67. data/lib/capybara/selector/definition/file_field.rb +13 -0
  68. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  69. data/lib/capybara/selector/definition/frame.rb +17 -0
  70. data/lib/capybara/selector/definition/id.rb +6 -0
  71. data/lib/capybara/selector/definition/label.rb +62 -0
  72. data/lib/capybara/selector/definition/link.rb +55 -0
  73. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  74. data/lib/capybara/selector/definition/option.rb +27 -0
  75. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  76. data/lib/capybara/selector/definition/select.rb +81 -0
  77. data/lib/capybara/selector/definition/table.rb +109 -0
  78. data/lib/capybara/selector/definition/table_row.rb +21 -0
  79. data/lib/capybara/selector/definition/xpath.rb +5 -0
  80. data/lib/capybara/selector/definition.rb +280 -0
  81. data/lib/capybara/selector/filter_set.rb +19 -18
  82. data/lib/capybara/selector/filters/base.rb +11 -2
  83. data/lib/capybara/selector/filters/locator_filter.rb +13 -3
  84. data/lib/capybara/selector/regexp_disassembler.rb +11 -7
  85. data/lib/capybara/selector/selector.rb +50 -440
  86. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  87. data/lib/capybara/selector.rb +473 -482
  88. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  89. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  90. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  91. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  92. data/lib/capybara/selenium/driver.rb +174 -62
  93. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +74 -18
  94. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  95. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +37 -3
  96. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +14 -1
  97. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  98. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  99. data/lib/capybara/selenium/extensions/find.rb +68 -45
  100. data/lib/capybara/selenium/extensions/html5_drag.rb +192 -22
  101. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  102. data/lib/capybara/selenium/extensions/scroll.rb +8 -10
  103. data/lib/capybara/selenium/node.rb +268 -72
  104. data/lib/capybara/selenium/nodes/chrome_node.rb +105 -9
  105. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  106. data/lib/capybara/selenium/nodes/firefox_node.rb +51 -61
  107. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  108. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  109. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  110. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  111. data/lib/capybara/selenium/patches/logs.rb +45 -0
  112. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
  113. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  114. data/lib/capybara/server/animation_disabler.rb +43 -21
  115. data/lib/capybara/server/checker.rb +6 -2
  116. data/lib/capybara/server/middleware.rb +25 -13
  117. data/lib/capybara/server.rb +20 -4
  118. data/lib/capybara/session/config.rb +15 -11
  119. data/lib/capybara/session/matchers.rb +11 -11
  120. data/lib/capybara/session.rb +162 -131
  121. data/lib/capybara/spec/public/offset.js +6 -0
  122. data/lib/capybara/spec/public/test.js +105 -6
  123. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
  124. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  125. data/lib/capybara/spec/session/all_spec.rb +89 -15
  126. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  127. data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
  128. data/lib/capybara/spec/session/assert_text_spec.rb +26 -22
  129. data/lib/capybara/spec/session/attach_file_spec.rb +64 -31
  130. data/lib/capybara/spec/session/check_spec.rb +26 -4
  131. data/lib/capybara/spec/session/choose_spec.rb +14 -2
  132. data/lib/capybara/spec/session/click_button_spec.rb +109 -61
  133. data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
  134. data/lib/capybara/spec/session/click_link_spec.rb +23 -1
  135. data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
  136. data/lib/capybara/spec/session/current_url_spec.rb +11 -1
  137. data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
  138. data/lib/capybara/spec/session/evaluate_script_spec.rb +12 -0
  139. data/lib/capybara/spec/session/fill_in_spec.rb +46 -5
  140. data/lib/capybara/spec/session/find_link_spec.rb +10 -0
  141. data/lib/capybara/spec/session/find_spec.rb +80 -7
  142. data/lib/capybara/spec/session/first_spec.rb +2 -2
  143. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
  144. data/lib/capybara/spec/session/frame/within_frame_spec.rb +14 -1
  145. data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
  146. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  147. data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
  148. data/lib/capybara/spec/session/has_button_spec.rb +81 -0
  149. data/lib/capybara/spec/session/has_css_spec.rb +45 -8
  150. data/lib/capybara/spec/session/has_current_path_spec.rb +22 -7
  151. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  152. data/lib/capybara/spec/session/has_field_spec.rb +59 -1
  153. data/lib/capybara/spec/session/has_link_spec.rb +40 -0
  154. data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
  155. data/lib/capybara/spec/session/has_select_spec.rb +42 -8
  156. data/lib/capybara/spec/session/has_selector_spec.rb +19 -4
  157. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  158. data/lib/capybara/spec/session/has_table_spec.rb +177 -0
  159. data/lib/capybara/spec/session/has_text_spec.rb +31 -3
  160. data/lib/capybara/spec/session/html_spec.rb +1 -1
  161. data/lib/capybara/spec/session/matches_style_spec.rb +6 -4
  162. data/lib/capybara/spec/session/node_spec.rb +697 -23
  163. data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
  164. data/lib/capybara/spec/session/refresh_spec.rb +2 -1
  165. data/lib/capybara/spec/session/reset_session_spec.rb +21 -7
  166. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  167. data/lib/capybara/spec/session/save_page_spec.rb +4 -4
  168. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  169. data/lib/capybara/spec/session/scroll_spec.rb +9 -7
  170. data/lib/capybara/spec/session/select_spec.rb +5 -10
  171. data/lib/capybara/spec/session/selectors_spec.rb +24 -3
  172. data/lib/capybara/spec/session/uncheck_spec.rb +3 -3
  173. data/lib/capybara/spec/session/unselect_spec.rb +1 -1
  174. data/lib/capybara/spec/session/visit_spec.rb +20 -0
  175. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  176. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
  177. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
  178. data/lib/capybara/spec/session/window/window_spec.rb +54 -57
  179. data/lib/capybara/spec/session/window/windows_spec.rb +2 -2
  180. data/lib/capybara/spec/session/within_spec.rb +36 -0
  181. data/lib/capybara/spec/spec_helper.rb +30 -19
  182. data/lib/capybara/spec/test_app.rb +122 -34
  183. data/lib/capybara/spec/views/animated.erb +49 -0
  184. data/lib/capybara/spec/views/form.erb +86 -8
  185. data/lib/capybara/spec/views/frame_child.erb +3 -2
  186. data/lib/capybara/spec/views/frame_one.erb +2 -1
  187. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  188. data/lib/capybara/spec/views/frame_two.erb +1 -1
  189. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  190. data/lib/capybara/spec/views/layout.erb +10 -0
  191. data/lib/capybara/spec/views/obscured.erb +10 -10
  192. data/lib/capybara/spec/views/offset.erb +33 -0
  193. data/lib/capybara/spec/views/path.erb +2 -2
  194. data/lib/capybara/spec/views/popup_one.erb +1 -1
  195. data/lib/capybara/spec/views/popup_two.erb +1 -1
  196. data/lib/capybara/spec/views/react.erb +45 -0
  197. data/lib/capybara/spec/views/scroll.erb +2 -1
  198. data/lib/capybara/spec/views/spatial.erb +31 -0
  199. data/lib/capybara/spec/views/tables.erb +67 -0
  200. data/lib/capybara/spec/views/with_animation.erb +39 -4
  201. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  202. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  203. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  204. data/lib/capybara/spec/views/with_hover.erb +3 -2
  205. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  206. data/lib/capybara/spec/views/with_html.erb +34 -6
  207. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  208. data/lib/capybara/spec/views/with_js.erb +7 -4
  209. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  210. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  211. data/lib/capybara/spec/views/with_scope.erb +2 -2
  212. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  213. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  214. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  215. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  216. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  217. data/lib/capybara/spec/views/with_windows.erb +1 -1
  218. data/lib/capybara/spec/views/within_frames.erb +1 -1
  219. data/lib/capybara/version.rb +1 -1
  220. data/lib/capybara/window.rb +14 -18
  221. data/lib/capybara.rb +91 -126
  222. data/spec/basic_node_spec.rb +30 -16
  223. data/spec/capybara_spec.rb +40 -28
  224. data/spec/counter_spec.rb +35 -0
  225. data/spec/css_builder_spec.rb +3 -1
  226. data/spec/css_splitter_spec.rb +1 -1
  227. data/spec/dsl_spec.rb +33 -22
  228. data/spec/filter_set_spec.rb +5 -5
  229. data/spec/fixtures/selenium_driver_rspec_failure.rb +3 -3
  230. data/spec/fixtures/selenium_driver_rspec_success.rb +3 -3
  231. data/spec/minitest_spec.rb +24 -2
  232. data/spec/minitest_spec_spec.rb +60 -45
  233. data/spec/per_session_config_spec.rb +1 -1
  234. data/spec/rack_test_spec.rb +131 -98
  235. data/spec/regexp_dissassembler_spec.rb +53 -39
  236. data/spec/result_spec.rb +68 -66
  237. data/spec/rspec/features_spec.rb +9 -4
  238. data/spec/rspec/scenarios_spec.rb +6 -2
  239. data/spec/rspec/shared_spec_matchers.rb +137 -98
  240. data/spec/rspec_matchers_spec.rb +25 -0
  241. data/spec/rspec_spec.rb +23 -21
  242. data/spec/sauce_spec_chrome.rb +43 -0
  243. data/spec/selector_spec.rb +77 -21
  244. data/spec/selenium_spec_chrome.rb +141 -39
  245. data/spec/selenium_spec_chrome_remote.rb +32 -17
  246. data/spec/selenium_spec_edge.rb +36 -8
  247. data/spec/selenium_spec_firefox.rb +110 -68
  248. data/spec/selenium_spec_firefox_remote.rb +22 -15
  249. data/spec/selenium_spec_ie.rb +29 -22
  250. data/spec/selenium_spec_safari.rb +162 -0
  251. data/spec/server_spec.rb +153 -81
  252. data/spec/session_spec.rb +11 -4
  253. data/spec/shared_selenium_node.rb +79 -0
  254. data/spec/shared_selenium_session.rb +179 -74
  255. data/spec/spec_helper.rb +80 -5
  256. data/spec/whitespace_normalizer_spec.rb +54 -0
  257. data/spec/xpath_builder_spec.rb +3 -1
  258. metadata +218 -30
  259. data/lib/capybara/spec/session/source_spec.rb +0 -0
  260. data/lib/capybara/spec/views/with_title.erb +0 -5
@@ -1,12 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- nokogumbo_required = begin
5
- require 'nokogumbo'
6
- true
7
- rescue LoadError
8
- false
9
- end
10
4
 
11
5
  module TestSessions
12
6
  RackTest = Capybara::Session.new(:rack_test, TestApp)
@@ -25,6 +19,10 @@ skipped_tests = %i[
25
19
  download
26
20
  css
27
21
  scroll
22
+ spatial
23
+ html_validation
24
+ shadow_dom
25
+ active_element
28
26
  ]
29
27
  Capybara::SpecHelper.run_specs TestSessions::RackTest, 'RackTest', capybara_skip: skipped_tests do |example|
30
28
  case example.metadata[:full_description]
@@ -32,111 +30,145 @@ Capybara::SpecHelper.run_specs TestSessions::RackTest, 'RackTest', capybara_skip
32
30
  skip "Nokogiri doesn't support case insensitive CSS attribute matchers"
33
31
  when /#click_button should follow permanent redirects that maintain method/
34
32
  skip "Rack < 2 doesn't support 308" if Gem.loaded_specs['rack'].version < Gem::Version.new('2.0.0')
33
+ when /#attach_file with multipart form should send prior hidden field if no file submitted/
34
+ skip 'Rack-test < 2 needs an empty file to detect multipart form' if Gem.loaded_specs['rack-test'].version < Gem::Version.new('2.0.0')
35
35
  end
36
36
  end
37
37
 
38
38
  RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
39
+ include Capybara::RSpecMatchers
39
40
  context 'with rack test driver' do
40
- before do
41
- @session = TestSessions::RackTest
42
- end
41
+ let(:session) { TestSessions::RackTest }
43
42
 
44
43
  describe '#driver' do
45
44
  it 'should be a rack test driver' do
46
- expect(@session.driver).to be_an_instance_of(Capybara::RackTest::Driver)
45
+ expect(session.driver).to be_an_instance_of(Capybara::RackTest::Driver)
47
46
  end
48
47
  end
49
48
 
50
49
  describe '#mode' do
51
50
  it 'should remember the mode' do
52
- expect(@session.mode).to eq(:rack_test)
51
+ expect(session.mode).to eq(:rack_test)
53
52
  end
54
53
  end
55
54
 
56
55
  describe '#click_link' do
57
56
  after do
58
- @session.driver.options[:respect_data_method] = false
57
+ session.driver.options[:respect_data_method] = false
59
58
  end
60
59
 
61
60
  it 'should use data-method if option is true' do
62
- @session.driver.options[:respect_data_method] = true
63
- @session.visit '/with_html'
64
- @session.click_link 'A link with data-method'
65
- expect(@session.html).to include('The requested object was deleted')
61
+ session.driver.options[:respect_data_method] = true
62
+ session.visit '/with_html'
63
+ session.click_link 'A link with data-method'
64
+ expect(session.html).to include('The requested object was deleted')
66
65
  end
67
66
 
68
67
  it 'should not use data-method if option is false' do
69
- @session.driver.options[:respect_data_method] = false
70
- @session.visit '/with_html'
71
- @session.click_link 'A link with data-method'
72
- expect(@session.html).to include('Not deleted')
68
+ session.driver.options[:respect_data_method] = false
69
+ session.visit '/with_html'
70
+ session.click_link 'A link with data-method'
71
+ expect(session.html).to include('Not deleted')
73
72
  end
74
73
 
75
74
  it "should use data-method if available even if it's capitalized" do
76
- @session.driver.options[:respect_data_method] = true
77
- @session.visit '/with_html'
78
- @session.click_link 'A link with capitalized data-method'
79
- expect(@session.html).to include('The requested object was deleted')
75
+ session.driver.options[:respect_data_method] = true
76
+ session.visit '/with_html'
77
+ session.click_link 'A link with capitalized data-method'
78
+ expect(session.html).to include('The requested object was deleted')
80
79
  end
81
80
  end
82
81
 
83
82
  describe '#fill_in' do
84
83
  it 'should warn that :fill_options are not supported' do
85
- allow_any_instance_of(Capybara::RackTest::Node).to receive(:warn)
86
- @session.visit '/with_html'
87
- field = @session.fill_in 'test_field', with: 'not_monkey', fill_options: { random: true }
88
- expect(@session).to have_field('test_field', with: 'not_monkey')
89
- expect(field.base).to have_received(:warn).with("Options passed to Node#set but the RackTest driver doesn't support any - ignoring")
84
+ session.visit '/with_html'
85
+ expect { session.fill_in 'test_field', with: 'not_monkey', fill_options: { random: true } }.to \
86
+ output(/^Options passed to Node#set but the RackTest driver doesn't support any - ignoring/).to_stderr
87
+ expect(session).to have_field('test_field', with: 'not_monkey')
90
88
  end
91
89
  end
92
90
 
93
91
  describe '#attach_file' do
94
92
  context 'with multipart form' do
95
93
  it 'should submit an empty form-data section if no file is submitted' do
96
- @session.visit('/form')
97
- @session.click_button('Upload Empty')
98
- expect(@session.html).to include('Successfully ignored empty file field.')
94
+ session.visit('/form')
95
+ session.click_button('Upload Empty')
96
+ expect(session.html).to include('Successfully ignored empty file field.')
97
+ end
98
+
99
+ it 'should submit multipart even if no file is submitted' do
100
+ session.visit('/form')
101
+ session.click_button('Upload Empty')
102
+ expect(session.html).to include('Content type was multipart/form-data;')
99
103
  end
100
104
  end
101
105
 
102
106
  it 'should not submit an obsolete mime type' do
103
- @test_jpg_file_path = File.expand_path('fixtures/capybara.csv', File.dirname(__FILE__))
104
- @session.visit('/form')
105
- @session.attach_file 'form_document', @test_jpg_file_path
106
- @session.click_button('Upload Single')
107
- expect(@session).to have_content('Content-type: text/csv')
107
+ test_jpg_file_path = File.expand_path('fixtures/capybara.csv', File.dirname(__FILE__))
108
+ session.visit('/form')
109
+ session.attach_file 'form_document', test_jpg_file_path
110
+ session.click_button('Upload Single')
111
+ expect(session).to have_content('Content-type: text/csv')
108
112
  end
109
113
  end
110
114
 
111
115
  describe '#click' do
112
116
  context 'on a label' do
113
117
  it 'should toggle the associated checkbox' do
114
- @session.visit('/form')
115
- expect(@session).to have_unchecked_field('form_pets_cat')
116
- @session.find(:label, 'Cat').click
117
- expect(@session).to have_checked_field('form_pets_cat')
118
- @session.find(:label, 'Cat').click
119
- expect(@session).to have_unchecked_field('form_pets_cat')
120
- @session.find(:label, 'McLaren').click
121
- expect(@session).to have_checked_field('form_cars_mclaren', visible: :hidden)
118
+ session.visit('/form')
119
+ expect(session).to have_unchecked_field('form_pets_cat')
120
+ session.find(:label, 'Cat').click
121
+ expect(session).to have_checked_field('form_pets_cat')
122
+ session.find(:label, 'Cat').click
123
+ expect(session).to have_unchecked_field('form_pets_cat')
124
+ session.find(:label, 'McLaren').click
125
+ expect(session).to have_checked_field('form_cars_mclaren', visible: :hidden)
122
126
  end
123
127
 
124
128
  it 'should toggle the associated radio' do
125
- @session.visit('/form')
126
- expect(@session).to have_unchecked_field('gender_male')
127
- @session.find(:label, 'Male').click
128
- expect(@session).to have_checked_field('gender_male')
129
- @session.find(:label, 'Female').click
130
- expect(@session).to have_unchecked_field('gender_male')
129
+ session.visit('/form')
130
+ expect(session).to have_unchecked_field('gender_male')
131
+ session.find(:label, 'Male').click
132
+ expect(session).to have_checked_field('gender_male')
133
+ session.find(:label, 'Female').click
134
+ expect(session).to have_unchecked_field('gender_male')
135
+ end
136
+
137
+ it 'should rewrite the forms action query for get submission' do
138
+ session.visit('/form')
139
+ session.click_button('mediocre')
140
+ expect(session).not_to have_current_path(/foo|bar/)
131
141
  end
142
+
143
+ it 'should rewrite the submit buttons formaction query for get submission' do
144
+ session.visit('/form')
145
+ session.click_button('mediocre2')
146
+ expect(session).not_to have_current_path(/foo|bar/)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#send_keys' do
152
+ it 'raises an UnsupportedMethodError' do
153
+ session.visit('/form')
154
+
155
+ expect { session.send_keys(:tab) }.to raise_error(Capybara::NotSupportedByDriverError)
156
+ end
157
+ end
158
+
159
+ describe '#active_element' do
160
+ it 'raises an UnsupportedMethodError' do
161
+ session.visit('/form')
162
+
163
+ expect { session.active_element }.to raise_error(Capybara::NotSupportedByDriverError)
132
164
  end
133
165
  end
134
166
 
135
167
  describe '#text' do
136
168
  it 'should return original text content for textareas' do
137
- @session.visit('/with_html')
138
- @session.find_field('normal', type: 'textarea', with: 'banana').set('hello')
139
- normal = @session.find(:css, '#normal')
169
+ session.visit('/with_html')
170
+ session.find_field('normal', type: 'textarea', with: 'banana').set('hello')
171
+ normal = session.find(:css, '#normal')
140
172
  expect(normal.value).to eq 'hello'
141
173
  expect(normal.text).to eq 'banana'
142
174
  end
@@ -144,8 +176,8 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
144
176
 
145
177
  describe '#style' do
146
178
  it 'should raise an error' do
147
- @session.visit('/with_html')
148
- el = @session.find(:css, '#first')
179
+ session.visit('/with_html')
180
+ el = session.find(:css, '#first')
149
181
  expect { el.style('display') }.to raise_error NotImplementedError, /not process CSS/
150
182
  end
151
183
  end
@@ -153,87 +185,87 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
153
185
  end
154
186
 
155
187
  RSpec.describe Capybara::RackTest::Driver do
156
- before do
157
- @driver = TestSessions::RackTest.driver
158
- end
188
+ let(:driver) { TestSessions::RackTest.driver }
159
189
 
160
190
  describe ':headers option' do
161
191
  it 'should always set headers' do
162
- @driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
163
- @driver.visit('/get_header')
164
- expect(@driver.html).to include('foobar')
192
+ driver = described_class.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
193
+ driver.visit('/get_header')
194
+ expect(driver.html).to include('foobar')
165
195
  end
166
196
 
167
197
  it 'should keep headers on link clicks' do
168
- @driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
169
- @driver.visit('/header_links')
170
- @driver.find_xpath('.//a').first.click
171
- expect(@driver.html).to include('foobar')
198
+ driver = described_class.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
199
+ driver.visit('/header_links')
200
+ driver.find_xpath('.//a').first.click
201
+ expect(driver.html).to include('foobar')
172
202
  end
173
203
 
174
204
  it 'should keep headers on form submit' do
175
- @driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
176
- @driver.visit('/header_links')
177
- @driver.find_xpath('.//input').first.click
178
- expect(@driver.html).to include('foobar')
205
+ driver = described_class.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
206
+ driver.visit('/header_links')
207
+ driver.find_xpath('.//input').first.click
208
+ expect(driver.html).to include('foobar')
179
209
  end
180
210
 
181
211
  it 'should keep headers on redirects' do
182
- @driver = Capybara::RackTest::Driver.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
183
- @driver.visit('/get_header_via_redirect')
184
- expect(@driver.html).to include('foobar')
212
+ driver = described_class.new(TestApp, headers: { 'HTTP_FOO' => 'foobar' })
213
+ driver.visit('/get_header_via_redirect')
214
+ expect(driver.html).to include('foobar')
185
215
  end
186
216
  end
187
217
 
188
218
  describe ':follow_redirects option' do
189
219
  it 'defaults to following redirects' do
190
- @driver = Capybara::RackTest::Driver.new(TestApp)
220
+ driver = described_class.new(TestApp)
221
+
222
+ driver.visit('/redirect')
223
+ expect(driver.response.headers['Location']).to be_nil
224
+ expect(driver.current_url).to match %r{/landed$}
225
+ end
191
226
 
192
- @driver.visit('/redirect')
193
- expect(@driver.response.header['Location']).to be_nil
194
- expect(@driver.current_url).to match %r{/landed$}
227
+ it 'should not include fragments in the referer header' do
228
+ driver.visit('/header_links#an-anchor')
229
+ driver.find_xpath('.//input').first.click
230
+ expect(driver.request.get_header('HTTP_REFERER')).to eq('http://www.example.com/header_links')
195
231
  end
196
232
 
197
233
  it 'is possible to not follow redirects' do
198
- @driver = Capybara::RackTest::Driver.new(TestApp, follow_redirects: false)
234
+ driver = described_class.new(TestApp, follow_redirects: false)
199
235
 
200
- @driver.visit('/redirect')
201
- expect(@driver.response.header['Location']).to match %r{/redirect_again$}
202
- expect(@driver.current_url).to match %r{/redirect$}
236
+ driver.visit('/redirect')
237
+ expect(driver.response.headers['Location']).to match %r{/redirect_again$}
238
+ expect(driver.current_url).to match %r{/redirect$}
203
239
  end
204
240
  end
205
241
 
206
242
  describe ':redirect_limit option' do
207
243
  context 'with default redirect limit' do
208
- before do
209
- @driver = Capybara::RackTest::Driver.new(TestApp)
210
- end
244
+ let(:driver) { described_class.new(TestApp) }
211
245
 
212
246
  it 'should follow 5 redirects' do
213
- @driver.visit('/redirect/5/times')
214
- expect(@driver.html).to include('redirection complete')
247
+ driver.visit('/redirect/5/times')
248
+ expect(driver.html).to include('redirection complete')
215
249
  end
216
250
 
217
251
  it 'should not follow more than 6 redirects' do
218
252
  expect do
219
- @driver.visit('/redirect/6/times')
253
+ driver.visit('/redirect/6/times')
220
254
  end.to raise_error(Capybara::InfiniteRedirectError)
221
255
  end
222
256
  end
223
257
 
224
258
  context 'with 21 redirect limit' do
225
- before do
226
- @driver = Capybara::RackTest::Driver.new(TestApp, redirect_limit: 21)
227
- end
259
+ let(:driver) { described_class.new(TestApp, redirect_limit: 21) }
228
260
 
229
261
  it 'should follow 21 redirects' do
230
- @driver.visit('/redirect/21/times')
231
- expect(@driver.html).to include('redirection complete')
262
+ driver.visit('/redirect/21/times')
263
+ expect(driver.html).to include('redirection complete')
232
264
  end
233
265
 
234
266
  it 'should not follow more than 21 redirects' do
235
267
  expect do
236
- @driver.visit('/redirect/22/times')
268
+ driver.visit('/redirect/22/times')
237
269
  end.to raise_error(Capybara::InfiniteRedirectError)
238
270
  end
239
271
  end
@@ -241,11 +273,12 @@ RSpec.describe Capybara::RackTest::Driver do
241
273
  end
242
274
 
243
275
  RSpec.describe 'Capybara::String' do
244
- it 'should use gumbo' do
245
- skip 'Only valid if gumbo is included' unless nokogumbo_required
246
- allow(Nokogiri).to receive(:HTML5).and_call_original
276
+ it 'should use HTML5 parsing' do
277
+ skip 'Only valid if Nokogiri >= 1.12.0 or gumbo is included' unless defined? Nokogiri::HTML5
278
+ Capybara.use_html5_parsing = true
279
+ allow(Nokogiri::HTML5).to receive(:parse).and_call_original
247
280
  Capybara.string('<div id=test_div></div>')
248
- expect(Nokogiri).to have_received(:HTML5)
281
+ expect(Nokogiri::HTML5).to have_received(:parse)
249
282
  end
250
283
  end
251
284
 
@@ -259,6 +292,6 @@ RSpec.describe Capybara::RackTest::CSSHandlers do
259
292
  include CSSHandlerIncludeTester
260
293
 
261
294
  it 'should not be extended by global includes' do
262
- expect(Capybara::RackTest::CSSHandlers.new).not_to respond_to(:dont_extend_css_handler)
295
+ expect(described_class.new).not_to respond_to(:dont_extend_css_handler)
263
296
  end
264
297
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Capybara::Selector::RegexpDisassembler do
5
+ RSpec.describe Capybara::Selector::RegexpDisassembler, :aggregate_failures do
6
6
  it 'handles strings' do
7
7
  verify_strings(
8
8
  /abcdef/ => %w[abcdef],
@@ -44,20 +44,22 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
44
44
  /abc?def?g/ => %w[ab de g],
45
45
  /d?/ => []
46
46
  }.each do |regexp, expected|
47
- expect(Capybara::Selector::RegexpDisassembler.new(regexp).substrings).to eq expected
47
+ expect(described_class.new(regexp).substrings).to eq expected
48
48
  end
49
49
  end
50
50
 
51
51
  it 'handles optional characters for #alternated_substrings' do
52
52
  verify_alternated_strings(
53
- /abc*def/ => [%w[ab def]],
54
- /abc*/ => [%w[ab]],
55
- /c*/ => [],
56
- /abc?def/ => [%w[abdef], %w[abcdef]],
57
- /abc?/ => [%w[ab]],
58
- /abc?def?/ => [%w[abde], %w[abcde]],
59
- /abc?def?g/ => [%w[abdeg], %w[abdefg], %w[abcdeg], %w[abcdefg]],
60
- /d?/ => []
53
+ {
54
+ /abc*def/ => [%w[ab def]],
55
+ /abc*/ => [%w[ab]],
56
+ /c*/ => [],
57
+ /abc?def/ => [%w[abdef], %w[abcdef]],
58
+ /abc?/ => [%w[ab]],
59
+ /abc?def?/ => [%w[abde], %w[abcde]],
60
+ /abc?def?g/ => [%w[abdeg], %w[abdefg], %w[abcdeg], %w[abcdefg]],
61
+ /d?/ => []
62
+ }
61
63
  )
62
64
  end
63
65
 
@@ -131,40 +133,42 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
131
133
  /ab(cd|cd)?ef/ => %w[ab ef],
132
134
  /ab\\?cd/ => %w[ab cd]
133
135
  }.each do |regexp, expected|
134
- expect(Capybara::Selector::RegexpDisassembler.new(regexp).substrings).to eq expected
136
+ expect(described_class.new(regexp).substrings).to eq expected
135
137
  end
136
138
  end
137
139
 
138
140
  it 'handles alternation for #alternated_substrings' do
139
141
  verify_alternated_strings(
140
- /abc|def/ => [%w[abc], %w[def]],
141
- /ab(?:c|d)/ => [%w[abc], %w[abd]],
142
- /ab(c|d|e)fg/ => [%w[abcfg], %w[abdfg], %w[abefg]],
143
- /ab?(c|d)fg/ => [%w[acfg], %w[adfg], %w[abcfg], %w[abdfg]],
144
- /ab(c|d)ef/ => [%w[abcef], %w[abdef]],
145
- /ab(cd?|ef)g/ => [%w[abcg], %w[abcdg], %w[abefg]],
146
- /ab(cd|ef*)g/ => [%w[abcdg], %w[abe g]],
147
- /ab|cd*/ => [%w[ab], %w[c]],
148
- /cd(?:ef|gh)|xyz/ => [%w[cdef], %w[cdgh], %w[xyz]],
149
- /(cd(?:ef|gh)|xyz)/ => [%w[cdef], %w[cdgh], %w[xyz]],
150
- /cd(ef|gh)+/ => [%w[cdef], %w[cdgh]],
151
- /cd(ef|gh)?/ => [%w[cd]],
152
- /cd(ef|gh)?ij/ => [%w[cdij], %w[cdefij], %w[cdghij]],
153
- /cd(ef|gh)+ij/ => [%w[cdef ij], %w[cdgh ij]],
154
- /cd(ef|gh){2}ij/ => [%w[cdefefij], %w[cdefghij], %w[cdghefij], %w[cdghghij]],
155
- /(cd(ef|g*))/ => [%w[cd]],
156
- /a|b*/ => [],
157
- /ab(?:c|d?)/ => [%w[ab]],
158
- /ab(c|d)|a*/ => [],
159
- /(abc)?(d|e)/ => [%w[d], %w[e]],
160
- /(abc*de)?(d|e)/ => [%w[d], %w[e]],
161
- /(abc*de)?(d|e?)/ => [],
162
- /(abc)?(d|e?)/ => [],
163
- /ab(cd){0,2}ef/ => [%w[ab ef]],
164
- /ab(cd){0,1}ef/ => [%w[abef], %w[abcdef]],
165
- /ab(cd|cd)ef/ => [%w[abcdef]],
166
- /ab(cd|cd)?ef/ => [%w[abef], %w[abcdef]],
167
- /ab\\?cd/ => [%w[abcd], %w[ab\cd]]
142
+ {
143
+ /abc|def/ => [%w[abc], %w[def]],
144
+ /ab(?:c|d)/ => [%w[abc], %w[abd]],
145
+ /ab(c|d|e)fg/ => [%w[abcfg], %w[abdfg], %w[abefg]],
146
+ /ab?(c|d)fg/ => [%w[acfg], %w[adfg], %w[abcfg], %w[abdfg]],
147
+ /ab(c|d)ef/ => [%w[abcef], %w[abdef]],
148
+ /ab(cd?|ef)g/ => [%w[abcg], %w[abcdg], %w[abefg]],
149
+ /ab(cd|ef*)g/ => [%w[abcdg], %w[abe g]],
150
+ /ab|cd*/ => [%w[ab], %w[c]],
151
+ /cd(?:ef|gh)|xyz/ => [%w[cdef], %w[cdgh], %w[xyz]],
152
+ /(cd(?:ef|gh)|xyz)/ => [%w[cdef], %w[cdgh], %w[xyz]],
153
+ /cd(ef|gh)+/ => [%w[cdef], %w[cdgh]],
154
+ /cd(ef|gh)?/ => [%w[cd]],
155
+ /cd(ef|gh)?ij/ => [%w[cdij], %w[cdefij], %w[cdghij]],
156
+ /cd(ef|gh)+ij/ => [%w[cdef ij], %w[cdgh ij]],
157
+ /cd(ef|gh){2}ij/ => [%w[cdefefij], %w[cdefghij], %w[cdghefij], %w[cdghghij]],
158
+ /(cd(ef|g*))/ => [%w[cd]],
159
+ /a|b*/ => [],
160
+ /ab(?:c|d?)/ => [%w[ab]],
161
+ /ab(c|d)|a*/ => [],
162
+ /(abc)?(d|e)/ => [%w[d], %w[e]],
163
+ /(abc*de)?(d|e)/ => [%w[d], %w[e]],
164
+ /(abc*de)?(d|e?)/ => [],
165
+ /(abc)?(d|e?)/ => [],
166
+ /ab(cd){0,2}ef/ => [%w[ab ef]],
167
+ /ab(cd){0,1}ef/ => [%w[abef], %w[abcdef]],
168
+ /ab(cd|cd)ef/ => [%w[abcdef]],
169
+ /ab(cd|cd)?ef/ => [%w[abef], %w[abcdef]],
170
+ /ab\\?cd/ => [%w[abcd], %w[ab\cd]]
171
+ }
168
172
  )
169
173
  end
170
174
 
@@ -212,6 +216,16 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
212
216
  )
213
217
  end
214
218
 
219
+ it 'ignores negative lookaheads' do
220
+ verify_strings(
221
+ /^(?!.*\bContributing Editor\b).*$/ => %w[],
222
+ /abc(?!.*def).*/ => %w[abc],
223
+ /(?!.*def)abc/ => %w[abc],
224
+ /abc(?!.*def.*).*ghi/ => %w[abc ghi],
225
+ /abc(?!.*bcd)def/ => %w[abcdef]
226
+ )
227
+ end
228
+
215
229
  it 'handles anchors' do
216
230
  verify_strings(
217
231
  /^abc/ => %w[abc],