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
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Capybara::Server::Middleware::Counter do
6
+ let(:counter) { described_class.new }
7
+ let(:uri) { '/example' }
8
+
9
+ describe '#increment' do
10
+ it 'successfully' do
11
+ counter.increment(uri)
12
+ expect(counter).to be_positive
13
+ end
14
+ end
15
+
16
+ describe '#decrement' do
17
+ before do
18
+ counter.increment(uri)
19
+ end
20
+
21
+ context 'successfully' do
22
+ it 'with same uri' do
23
+ expect(counter).to be_positive
24
+ counter.decrement(uri)
25
+ expect(counter).not_to be_positive
26
+ end
27
+
28
+ it 'with changed uri' do
29
+ expect(counter).to be_positive
30
+ counter.decrement('/')
31
+ expect(counter).not_to be_positive
32
+ end
33
+ end
34
+ end
35
+ end
@@ -2,9 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
+ # rubocop:disable RSpec/InstanceVariable
5
6
  RSpec.describe Capybara::Selector::CSSBuilder do
6
7
  let :builder do
7
- ::Capybara::Selector::CSSBuilder.new(@css)
8
+ described_class.new(@css)
8
9
  end
9
10
 
10
11
  context 'add_attribute_conditions' do
@@ -97,3 +98,4 @@ RSpec.describe Capybara::Selector::CSSBuilder do
97
98
  end
98
99
  end
99
100
  end
101
+ # rubocop:enable RSpec/InstanceVariable
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Selector::CSS::Splitter do
6
6
  let :splitter do
7
- ::Capybara::Selector::CSS::Splitter.new
7
+ described_class.new
8
8
  end
9
9
 
10
10
  context 'split not needed' do
data/spec/dsl_spec.rb CHANGED
@@ -8,17 +8,23 @@ class TestClass
8
8
  end
9
9
 
10
10
  Capybara::SpecHelper.run_specs TestClass.new, 'DSL', capybara_skip: %i[
11
- js modals screenshot frames windows send_keys server hover about_scheme psc download css driver scroll
11
+ js modals screenshot frames windows send_keys server hover about_scheme psc download css driver scroll spatial html_validation shadow_dom active_element
12
12
  ] do |example|
13
13
  case example.metadata[:full_description]
14
14
  when /has_css\? should support case insensitive :class and :id options/
15
15
  pending "Nokogiri doesn't support case insensitive CSS attribute matchers"
16
16
  when /#click_button should follow permanent redirects that maintain method/
17
17
  pending "Rack < 2 doesn't support 308" if Gem.loaded_specs['rack'].version < Gem::Version.new('2.0.0')
18
+ when /#attach_file with multipart form should send prior hidden field if no file submitted/
19
+ 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')
18
20
  end
19
21
  end
20
22
 
21
23
  RSpec.describe Capybara::DSL do
24
+ before do
25
+ Capybara.use_default_driver
26
+ end
27
+
22
28
  after do
23
29
  Capybara.session_name = nil
24
30
  Capybara.default_driver = nil
@@ -92,7 +98,7 @@ RSpec.describe Capybara::DSL do
92
98
  driver_before_block = Capybara.current_driver
93
99
  begin
94
100
  Capybara.using_driver(:selenium) { raise 'ohnoes!' }
95
- rescue Exception # rubocop:disable Lint/RescueException,Lint/HandleExceptions
101
+ rescue Exception # rubocop:disable Lint/RescueException,Lint/SuppressedException
96
102
  end
97
103
  expect(Capybara.current_driver).to eq(driver_before_block)
98
104
  end
@@ -111,18 +117,15 @@ RSpec.describe Capybara::DSL do
111
117
  it 'should yield the passed block' do
112
118
  called = false
113
119
  Capybara.using_driver(:selenium) { called = true }
114
- expect(called).to eq(true)
120
+ expect(called).to be(true)
115
121
  end
116
122
  end
117
123
 
124
+ # rubocop:disable RSpec/InstanceVariable
118
125
  describe '#using_wait_time' do
119
- before do
120
- @previous_wait_time = Capybara.default_max_wait_time
121
- end
126
+ before { @previous_wait_time = Capybara.default_max_wait_time }
122
127
 
123
- after do
124
- Capybara.default_max_wait_time = @previous_wait_time
125
- end
128
+ after { Capybara.default_max_wait_time = @previous_wait_time }
126
129
 
127
130
  it 'should switch the wait time and switch it back' do
128
131
  in_block = nil
@@ -142,6 +145,7 @@ RSpec.describe Capybara::DSL do
142
145
  expect(Capybara.default_max_wait_time).to eq(@previous_wait_time)
143
146
  end
144
147
  end
148
+ # rubocop:enable RSpec/InstanceVariable
145
149
 
146
150
  describe '#app' do
147
151
  it 'should be changeable' do
@@ -210,7 +214,7 @@ RSpec.describe Capybara::DSL do
210
214
  Capybara.using_session(:raise) do
211
215
  raise
212
216
  end
213
- rescue Exception # rubocop:disable Lint/RescueException,Lint/HandleExceptions
217
+ rescue Exception # rubocop:disable Lint/RescueException,Lint/SuppressedException
214
218
  end
215
219
  expect(Capybara.session_name).to eq(:default)
216
220
  end
@@ -218,7 +222,7 @@ RSpec.describe Capybara::DSL do
218
222
  it 'should yield the passed block' do
219
223
  called = false
220
224
  Capybara.using_session(:administrator) { called = true }
221
- expect(called).to eq(true)
225
+ expect(called).to be(true)
222
226
  end
223
227
 
224
228
  it 'should be nestable' do
@@ -240,6 +244,15 @@ RSpec.describe Capybara::DSL do
240
244
  end
241
245
  expect(Capybara.current_session).to eq(original_session)
242
246
  end
247
+
248
+ it 'should pass the new session if block accepts' do
249
+ original_session = Capybara.current_session
250
+ Capybara.using_session(:administrator) do |admin_session, prev_session|
251
+ expect(admin_session).to be(Capybara.current_session)
252
+ expect(prev_session).to be(original_session)
253
+ expect(prev_session).not_to be(admin_session)
254
+ end
255
+ end
243
256
  end
244
257
 
245
258
  describe '#session_name' do
@@ -249,31 +262,29 @@ RSpec.describe Capybara::DSL do
249
262
  end
250
263
 
251
264
  describe 'the DSL' do
252
- before do
253
- @session = Class.new { include Capybara::DSL }.new
254
- end
265
+ let(:session) { Class.new { include Capybara::DSL }.new }
255
266
 
256
267
  it 'should be possible to include it in another class' do
257
- @session.visit('/with_html')
258
- @session.click_link('ullamco')
259
- expect(@session.body).to include('Another World')
268
+ session.visit('/with_html')
269
+ session.click_link('ullamco')
270
+ expect(session.body).to include('Another World')
260
271
  end
261
272
 
262
273
  it "should provide a 'page' shortcut for more expressive tests" do
263
- @session.page.visit('/with_html')
264
- @session.page.click_link('ullamco')
265
- expect(@session.page.body).to include('Another World')
274
+ session.page.visit('/with_html')
275
+ session.page.click_link('ullamco')
276
+ expect(session.page.body).to include('Another World')
266
277
  end
267
278
 
268
279
  it "should provide an 'using_session' shortcut" do
269
280
  allow(Capybara).to receive(:using_session)
270
- @session.using_session(:name)
281
+ session.using_session(:name)
271
282
  expect(Capybara).to have_received(:using_session).with(:name)
272
283
  end
273
284
 
274
285
  it "should provide a 'using_wait_time' shortcut" do
275
286
  allow(Capybara).to receive(:using_wait_time)
276
- @session.using_wait_time(6)
287
+ session.using_wait_time(6)
277
288
  expect(Capybara).to have_received(:using_wait_time).with(6)
278
289
  end
279
290
  end
@@ -4,11 +4,11 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Selector::FilterSet do
6
6
  after do
7
- Capybara::Selector::FilterSet.remove(:test)
7
+ described_class.remove(:test)
8
8
  end
9
9
 
10
10
  it 'allows node filters' do
11
- fs = Capybara::Selector::FilterSet.add(:test) do
11
+ fs = described_class.add(:test) do
12
12
  node_filter(:node_test, :boolean) { |_node, _value| true }
13
13
  expression_filter(:expression_test, :boolean) { |_expr, _value| true }
14
14
  end
@@ -18,7 +18,7 @@ RSpec.describe Capybara::Selector::FilterSet do
18
18
  end
19
19
 
20
20
  it 'allows expression filters' do
21
- fs = Capybara::Selector::FilterSet.add(:test) do
21
+ fs = described_class.add(:test) do
22
22
  node_filter(:node_test, :boolean) { |_node, _value| true }
23
23
  expression_filter(:expression_test, :boolean) { |_expr, _value| true }
24
24
  end
@@ -28,7 +28,7 @@ RSpec.describe Capybara::Selector::FilterSet do
28
28
  end
29
29
 
30
30
  it 'allows node filter and expression filter with the same name' do
31
- fs = Capybara::Selector::FilterSet.add(:test) do
31
+ fs = described_class.add(:test) do
32
32
  node_filter(:test, :boolean) { |_node, _value| true }
33
33
  expression_filter(:test, :boolean) { |_expr, _value| true }
34
34
  end
@@ -37,7 +37,7 @@ RSpec.describe Capybara::Selector::FilterSet do
37
37
  end
38
38
 
39
39
  it 'allows `filter` as an alias of `node_filter`' do
40
- fs = Capybara::Selector::FilterSet.add(:test) do
40
+ fs = described_class.add(:test) do
41
41
  filter(:node_test, :boolean) { |_node, _value| true }
42
42
  end
43
43
 
@@ -5,9 +5,9 @@ require 'selenium-webdriver'
5
5
 
6
6
  RSpec.describe Capybara::Selenium::Driver do
7
7
  it 'should exit with a non-zero exit status' do
8
- options = { browser: (ENV['SELENIUM_BROWSER'] || :firefox).to_sym }
9
- browser = Capybara::Selenium::Driver.new(TestApp, options).browser
8
+ options = { browser: ENV.fetch('SELENIUM_BROWSER', :firefox).to_sym }
9
+ browser = described_class.new(TestApp, options).browser
10
10
  expect(browser).to be_truthy
11
- expect(true).to eq(false) # rubocop:disable RSpec/ExpectActual
11
+ expect(true).to be(false) # rubocop:disable RSpec/ExpectActual
12
12
  end
13
13
  end
@@ -5,9 +5,9 @@ require 'selenium-webdriver'
5
5
 
6
6
  RSpec.describe Capybara::Selenium::Driver do
7
7
  it 'should exit with a zero exit status' do
8
- options = { browser: (ENV['SELENIUM_BROWSER'] || :firefox).to_sym }
9
- browser = Capybara::Selenium::Driver.new(TestApp, options).browser
8
+ options = { browser: ENV.fetch('SELENIUM_BROWSER', :firefox).to_sym }
9
+ browser = described_class.new(TestApp, **options).browser
10
10
  expect(browser).to be_truthy
11
- expect(true).to eq(true) # rubocop:disable RSpec/ExpectActual
11
+ expect(true).to be(true) # rubocop:disable RSpec/ExpectActual,RSpec/IdenticalEqualityAssertion
12
12
  end
13
13
  end
@@ -15,8 +15,12 @@ class MinitestTest < Minitest::Test
15
15
  Capybara.reset_sessions!
16
16
  end
17
17
 
18
+ def self.test_order
19
+ :sorted
20
+ end
21
+
18
22
  def test_assert_text
19
- assert_text('Form')
23
+ assert_text('Form', normalize_ws: false)
20
24
  assert_no_text('Not on the page')
21
25
  refute_text('Also Not on the page')
22
26
  end
@@ -30,6 +34,7 @@ class MinitestTest < Minitest::Test
30
34
 
31
35
  def test_assert_current_path
32
36
  assert_current_path('/form')
37
+ assert_current_path('/form') { |url| url.query.nil? }
33
38
  assert_no_current_path('/not_form')
34
39
  refute_current_path('/not_form')
35
40
  end
@@ -55,6 +60,13 @@ class MinitestTest < Minitest::Test
55
60
  refute_selector(:css, 'select#not_form_title')
56
61
  end
57
62
 
63
+ def test_assert_element
64
+ visit('/with_html')
65
+ assert_element('a', text: 'A link')
66
+ assert_element(count: 1) { |el| el.text == 'A link' }
67
+ assert_no_element(text: 'Not on page')
68
+ end
69
+
58
70
  def test_assert_link
59
71
  visit('/with_html')
60
72
  assert_link('A link')
@@ -130,6 +142,16 @@ class MinitestTest < Minitest::Test
130
142
  visit('/with_html')
131
143
  assert_matches_style(find(:css, '#second'), display: 'inline')
132
144
  end
145
+
146
+ def test_assert_ancestor
147
+ option = find(:option, 'Finnish')
148
+ assert_ancestor(option, :css, '#form_locale')
149
+ end
150
+
151
+ def test_assert_sibling
152
+ option = find(:css, '#form_title').find(:option, 'Mrs')
153
+ assert_sibling(option, :option, 'Mr')
154
+ end
133
155
  end
134
156
 
135
157
  RSpec.describe 'capybara/minitest' do
@@ -148,6 +170,6 @@ RSpec.describe 'capybara/minitest' do
148
170
  reporter.start
149
171
  MinitestTest.run reporter, {}
150
172
  reporter.report
151
- expect(output.string).to include('20 runs, 50 assertions, 0 failures, 0 errors, 1 skips')
173
+ expect(output.string).to include('23 runs, 56 assertions, 0 failures, 0 errors, 1 skips')
152
174
  end
153
175
  end
@@ -16,115 +16,130 @@ class MinitestSpecTest < Minitest::Spec
16
16
  Capybara.reset_sessions!
17
17
  end
18
18
 
19
+ def self.test_order
20
+ :sorted
21
+ end
22
+
19
23
  it 'supports text expectations' do
20
- page.must_have_text('Form', minimum: 1)
21
- page.wont_have_text('Not a form')
24
+ _(page).must_have_text('Form', minimum: 1)
25
+ _(page).wont_have_text('Not a form')
22
26
  form = find(:css, 'form', text: 'Title')
23
- form.must_have_text('Customer Email')
24
- form.wont_have_text('Some other email')
27
+ _(form).must_have_text('Customer Email')
28
+ _(form).wont_have_text('Some other email')
25
29
  end
26
30
 
27
31
  it 'supports current_path expectations' do
28
- page.must_have_current_path('/form')
29
- page.wont_have_current_path('/form2')
32
+ _(page).must_have_current_path('/form')
33
+ _(page).wont_have_current_path('/form2')
30
34
  end
31
35
 
32
36
  it 'supports title expectations' do
33
37
  visit('/with_title')
34
- page.must_have_title('Test Title')
35
- page.wont_have_title('Not the title')
38
+ _(page).must_have_title('Test Title')
39
+ _(page).wont_have_title('Not the title')
36
40
  end
37
41
 
38
42
  it 'supports xpath expectations' do
39
- page.must_have_xpath('.//input[@id="customer_email"]')
40
- page.wont_have_xpath('.//select[@id="not_form_title"]')
41
- page.wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == 'not_customer_email' }
43
+ _(page).must_have_xpath('.//input[@id="customer_email"]')
44
+ _(page).wont_have_xpath('.//select[@id="not_form_title"]')
45
+ _(page).wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == 'not_customer_email' }
42
46
  select = find(:select, 'form_title')
43
- select.must_have_xpath('.//option[@class="title"]')
44
- select.must_have_xpath('.//option', count: 1) { |option| option[:class] != 'title' && !option.disabled? }
45
- select.wont_have_xpath('.//input[@id="customer_email"]')
47
+ _(select).must_have_xpath('.//option[@class="title"]')
48
+ _(select).must_have_xpath('.//option', count: 1) { |option| option[:class] != 'title' && !option.disabled? }
49
+ _(select).wont_have_xpath('.//input[@id="customer_email"]')
46
50
  end
47
51
 
48
52
  it 'support css expectations' do
49
- page.must_have_css('input#customer_email')
50
- page.wont_have_css('select#not_form_title')
53
+ _(page).must_have_css('input#customer_email')
54
+ _(page).wont_have_css('select#not_form_title')
51
55
  el = find(:select, 'form_title')
52
- el.must_have_css('option.title')
53
- el.wont_have_css('input#customer_email')
56
+ _(el).must_have_css('option.title')
57
+ _(el).wont_have_css('input#customer_email')
54
58
  end
55
59
 
56
60
  it 'supports link expectations' do
57
61
  visit('/with_html')
58
- page.must_have_link('A link')
59
- page.wont_have_link('Not on page')
62
+ _(page).must_have_link('A link')
63
+ _(page).wont_have_link('Not on page')
60
64
  end
61
65
 
62
66
  it 'supports button expectations' do
63
- page.must_have_button('fresh_btn')
64
- page.wont_have_button('not_btn')
67
+ _(page).must_have_button('fresh_btn')
68
+ _(page).wont_have_button('not_btn')
65
69
  end
66
70
 
67
71
  it 'supports field expectations' do
68
- page.must_have_field('customer_email')
69
- page.wont_have_field('not_on_the_form')
72
+ _(page).must_have_field('customer_email')
73
+ _(page).wont_have_field('not_on_the_form')
70
74
  end
71
75
 
72
76
  it 'supports select expectations' do
73
- page.must_have_select('form_title')
74
- page.wont_have_select('not_form_title')
77
+ _(page).must_have_select('form_title')
78
+ _(page).wont_have_select('not_form_title')
75
79
  end
76
80
 
77
81
  it 'supports checked_field expectations' do
78
- page.must_have_checked_field('form_pets_dog')
79
- page.wont_have_checked_field('form_pets_cat')
82
+ _(page).must_have_checked_field('form_pets_dog')
83
+ _(page).wont_have_checked_field('form_pets_cat')
80
84
  end
81
85
 
82
86
  it 'supports unchecked_field expectations' do
83
- page.must_have_unchecked_field('form_pets_cat')
84
- page.wont_have_unchecked_field('form_pets_dog')
87
+ _(page).must_have_unchecked_field('form_pets_cat')
88
+ _(page).wont_have_unchecked_field('form_pets_dog')
85
89
  end
86
90
 
87
91
  it 'supports table expectations' do
88
92
  visit('/tables')
89
- page.must_have_table('agent_table')
90
- page.wont_have_table('not_on_form')
93
+ _(page).must_have_table('agent_table')
94
+ _(page).wont_have_table('not_on_form')
91
95
  end
92
96
 
93
97
  it 'supports all_of_selectors expectations' do
94
- page.must_have_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
98
+ _(page).must_have_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
95
99
  end
96
100
 
97
101
  it 'supports none_of_selectors expectations' do
98
- page.must_have_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
102
+ _(page).must_have_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
99
103
  end
100
104
 
101
105
  it 'supports any_of_selectors expectations' do
102
- page.must_have_any_of_selectors(:css, 'select#form_other_title', 'input#not_on_page')
106
+ _(page).must_have_any_of_selectors(:css, 'select#form_other_title', 'input#not_on_page')
103
107
  end
104
108
 
105
109
  it 'supports match_selector expectations' do
106
- find(:field, 'customer_email').must_match_selector(:field, 'customer_email')
107
- find(:select, 'form_title').wont_match_selector(:field, 'customer_email')
110
+ _(find(:field, 'customer_email')).must_match_selector(:field, 'customer_email')
111
+ _(find(:select, 'form_title')).wont_match_selector(:field, 'customer_email')
108
112
  end
109
113
 
110
114
  it 'supports match_css expectations' do
111
- find(:select, 'form_title').must_match_css('select#form_title')
112
- find(:select, 'form_title').wont_match_css('select#form_other_title')
115
+ _(find(:select, 'form_title')).must_match_css('select#form_title')
116
+ _(find(:select, 'form_title')).wont_match_css('select#form_other_title')
113
117
  end
114
118
 
115
119
  it 'supports match_xpath expectations' do
116
- find(:select, 'form_title').must_match_xpath('.//select[@id="form_title"]')
117
- find(:select, 'form_title').wont_match_xpath('.//select[@id="not_on_page"]')
120
+ _(find(:select, 'form_title')).must_match_xpath('.//select[@id="form_title"]')
121
+ _(find(:select, 'form_title')).wont_match_xpath('.//select[@id="not_on_page"]')
118
122
  end
119
123
 
120
124
  it 'handles failures' do
121
- page.must_have_select('non_existing_form_title')
125
+ _(page).must_have_select('non_existing_form_title')
122
126
  end
123
127
 
124
128
  it 'supports style expectations' do
125
129
  skip "Rack test doesn't support style" if Capybara.current_driver == :rack_test
126
130
  visit('/with_html')
127
- find(:css, '#second').must_match_style('display' => 'inline')
131
+ _(find(:css, '#second')).must_have_style('display' => 'inline') # deprecated
132
+ _(find(:css, '#second')).must_match_style('display' => 'inline')
133
+ end
134
+
135
+ it 'supports ancestor expectations' do
136
+ option = find(:option, 'Finnish')
137
+ _(option).must_have_ancestor(:css, '#form_locale')
138
+ end
139
+
140
+ it 'supports sibling expectations' do
141
+ option = find(:css, '#form_title').find(:option, 'Mrs')
142
+ _(option).must_have_sibling(:option, 'Mr')
128
143
  end
129
144
  end
130
145
 
@@ -144,8 +159,8 @@ RSpec.describe 'capybara/minitest/spec' do
144
159
  reporter.start
145
160
  MinitestSpecTest.run reporter, {}
146
161
  reporter.report
147
- expect(output.string).to include('20 runs, 42 assertions, 1 failures, 0 errors, 1 skips')
162
+ expect(output.string).to include('22 runs, 44 assertions, 1 failures, 0 errors, 1 skips')
148
163
  # Make sure error messages are displayed
149
- expect(output.string).to include('expected to find select box "non_existing_form_title" but there were no matches')
164
+ expect(output.string).to match(/expected to find select box "non_existing_form_title" .*but there were no matches/)
150
165
  end
151
166
  end
@@ -12,7 +12,7 @@ RSpec.describe Capybara::SessionConfig do
12
12
  default_selector default_max_wait_time ignore_hidden_elements
13
13
  automatic_reload match exact raise_server_errors visible_text_only
14
14
  automatic_label_click enable_aria_label save_path
15
- asset_host].each do |m|
15
+ asset_host default_retry_interval].each do |m|
16
16
  expect(session.config.public_send(m)).to eq Capybara.public_send(m)
17
17
  end
18
18
  end