capybara 3.35.3 → 3.39.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +110 -4
  3. data/README.md +28 -12
  4. data/lib/capybara/config.rb +16 -4
  5. data/lib/capybara/driver/base.rb +4 -0
  6. data/lib/capybara/driver/node.rb +5 -1
  7. data/lib/capybara/dsl.rb +4 -10
  8. data/lib/capybara/helpers.rb +8 -13
  9. data/lib/capybara/minitest/spec.rb +2 -2
  10. data/lib/capybara/node/actions.rb +14 -9
  11. data/lib/capybara/node/base.rb +2 -1
  12. data/lib/capybara/node/document.rb +2 -2
  13. data/lib/capybara/node/element.rb +13 -2
  14. data/lib/capybara/node/finders.rb +11 -2
  15. data/lib/capybara/node/simple.rb +5 -1
  16. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  17. data/lib/capybara/queries/active_element_query.rb +18 -0
  18. data/lib/capybara/queries/ancestor_query.rb +2 -1
  19. data/lib/capybara/queries/base_query.rb +2 -2
  20. data/lib/capybara/queries/current_path_query.rb +1 -1
  21. data/lib/capybara/queries/selector_query.rb +38 -10
  22. data/lib/capybara/queries/sibling_query.rb +2 -1
  23. data/lib/capybara/queries/text_query.rb +1 -1
  24. data/lib/capybara/rack_test/browser.rb +63 -8
  25. data/lib/capybara/rack_test/driver.rb +4 -4
  26. data/lib/capybara/rack_test/form.rb +29 -7
  27. data/lib/capybara/rack_test/node.rb +28 -22
  28. data/lib/capybara/registration_container.rb +0 -3
  29. data/lib/capybara/registrations/drivers.rb +6 -6
  30. data/lib/capybara/registrations/servers.rb +30 -10
  31. data/lib/capybara/rspec/matcher_proxies.rb +6 -6
  32. data/lib/capybara/rspec/matchers/base.rb +8 -6
  33. data/lib/capybara/rspec/matchers/compound.rb +1 -1
  34. data/lib/capybara/rspec/matchers/have_selector.rb +5 -5
  35. data/lib/capybara/rspec/matchers.rb +14 -14
  36. data/lib/capybara/selector/builders/css_builder.rb +1 -1
  37. data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
  38. data/lib/capybara/selector/css.rb +1 -1
  39. data/lib/capybara/selector/definition/button.rb +9 -4
  40. data/lib/capybara/selector/definition/checkbox.rb +1 -1
  41. data/lib/capybara/selector/definition/file_field.rb +1 -1
  42. data/lib/capybara/selector/definition/fillable_field.rb +1 -1
  43. data/lib/capybara/selector/definition/link.rb +2 -1
  44. data/lib/capybara/selector/definition/radio_button.rb +1 -1
  45. data/lib/capybara/selector/definition.rb +4 -2
  46. data/lib/capybara/selector/filter_set.rb +4 -7
  47. data/lib/capybara/selector/regexp_disassembler.rb +2 -5
  48. data/lib/capybara/selector/selector.rb +5 -1
  49. data/lib/capybara/selector.rb +1 -0
  50. data/lib/capybara/selenium/driver.rb +30 -13
  51. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
  52. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +9 -5
  53. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
  54. data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
  55. data/lib/capybara/selenium/logger_suppressor.rb +4 -0
  56. data/lib/capybara/selenium/node.rb +81 -32
  57. data/lib/capybara/selenium/nodes/chrome_node.rb +6 -2
  58. data/lib/capybara/selenium/nodes/edge_node.rb +25 -3
  59. data/lib/capybara/selenium/nodes/firefox_node.rb +3 -3
  60. data/lib/capybara/selenium/nodes/safari_node.rb +4 -4
  61. data/lib/capybara/selenium/patches/action_pauser.rb +3 -3
  62. data/lib/capybara/selenium/patches/atoms.rb +1 -1
  63. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
  64. data/lib/capybara/server/animation_disabler.rb +40 -23
  65. data/lib/capybara/server/middleware.rb +1 -1
  66. data/lib/capybara/session/config.rb +4 -2
  67. data/lib/capybara/session.rb +31 -32
  68. data/lib/capybara/spec/public/test.js +4 -0
  69. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  70. data/lib/capybara/spec/session/all_spec.rb +10 -14
  71. data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
  72. data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
  73. data/lib/capybara/spec/session/check_spec.rb +10 -0
  74. data/lib/capybara/spec/session/choose_spec.rb +6 -0
  75. data/lib/capybara/spec/session/click_link_spec.rb +11 -0
  76. data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
  77. data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
  78. data/lib/capybara/spec/session/find_link_spec.rb +10 -0
  79. data/lib/capybara/spec/session/find_spec.rb +7 -1
  80. data/lib/capybara/spec/session/first_spec.rb +1 -1
  81. data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
  82. data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
  83. data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -2
  84. data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
  85. data/lib/capybara/spec/session/has_button_spec.rb +30 -0
  86. data/lib/capybara/spec/session/has_current_path_spec.rb +3 -3
  87. data/lib/capybara/spec/session/has_field_spec.rb +25 -1
  88. data/lib/capybara/spec/session/has_link_spec.rb +40 -0
  89. data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
  90. data/lib/capybara/spec/session/has_select_spec.rb +10 -4
  91. data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
  92. data/lib/capybara/spec/session/has_text_spec.rb +6 -14
  93. data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
  94. data/lib/capybara/spec/session/node_spec.rb +82 -1
  95. data/lib/capybara/spec/session/reset_session_spec.rb +13 -0
  96. data/lib/capybara/spec/session/scroll_spec.rb +7 -5
  97. data/lib/capybara/spec/session/visit_spec.rb +20 -0
  98. data/lib/capybara/spec/session/window/window_spec.rb +1 -1
  99. data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
  100. data/lib/capybara/spec/session/within_spec.rb +13 -0
  101. data/lib/capybara/spec/spec_helper.rb +12 -5
  102. data/lib/capybara/spec/test_app.rb +91 -14
  103. data/lib/capybara/spec/views/animated.erb +1 -1
  104. data/lib/capybara/spec/views/form.erb +28 -3
  105. data/lib/capybara/spec/views/frame_child.erb +1 -1
  106. data/lib/capybara/spec/views/frame_one.erb +1 -1
  107. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  108. data/lib/capybara/spec/views/frame_two.erb +1 -1
  109. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  110. data/lib/capybara/spec/views/layout.erb +10 -0
  111. data/lib/capybara/spec/views/obscured.erb +1 -1
  112. data/lib/capybara/spec/views/offset.erb +2 -1
  113. data/lib/capybara/spec/views/path.erb +2 -2
  114. data/lib/capybara/spec/views/popup_one.erb +1 -1
  115. data/lib/capybara/spec/views/popup_two.erb +1 -1
  116. data/lib/capybara/spec/views/react.erb +2 -2
  117. data/lib/capybara/spec/views/scroll.erb +2 -1
  118. data/lib/capybara/spec/views/spatial.erb +1 -1
  119. data/lib/capybara/spec/views/with_animation.erb +2 -3
  120. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  121. data/lib/capybara/spec/views/with_dragula.erb +2 -2
  122. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  123. data/lib/capybara/spec/views/with_hover.erb +2 -2
  124. data/lib/capybara/spec/views/with_html.erb +3 -3
  125. data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
  126. data/lib/capybara/spec/views/with_js.erb +2 -3
  127. data/lib/capybara/spec/views/with_jstree.erb +1 -1
  128. data/lib/capybara/spec/views/with_namespace.erb +1 -0
  129. data/lib/capybara/spec/views/with_scope.erb +2 -2
  130. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  131. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  132. data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
  133. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  134. data/lib/capybara/spec/views/with_windows.erb +1 -1
  135. data/lib/capybara/spec/views/within_frames.erb +1 -1
  136. data/lib/capybara/version.rb +1 -1
  137. data/lib/capybara/window.rb +1 -1
  138. data/lib/capybara.rb +23 -24
  139. data/spec/basic_node_spec.rb +16 -3
  140. data/spec/capybara_spec.rb +12 -0
  141. data/spec/counter_spec.rb +35 -0
  142. data/spec/css_builder_spec.rb +1 -1
  143. data/spec/css_splitter_spec.rb +1 -1
  144. data/spec/dsl_spec.rb +5 -3
  145. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
  146. data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
  147. data/spec/minitest_spec.rb +4 -0
  148. data/spec/minitest_spec_spec.rb +4 -0
  149. data/spec/per_session_config_spec.rb +1 -1
  150. data/spec/rack_test_spec.rb +30 -12
  151. data/spec/result_spec.rb +32 -35
  152. data/spec/rspec/features_spec.rb +3 -3
  153. data/spec/rspec/scenarios_spec.rb +2 -2
  154. data/spec/rspec/shared_spec_matchers.rb +3 -3
  155. data/spec/rspec_matchers_spec.rb +25 -0
  156. data/spec/rspec_spec.rb +2 -2
  157. data/spec/sauce_spec_chrome.rb +4 -4
  158. data/spec/selector_spec.rb +4 -4
  159. data/spec/selenium_spec_chrome.rb +16 -16
  160. data/spec/selenium_spec_chrome_remote.rb +15 -14
  161. data/spec/selenium_spec_edge.rb +12 -6
  162. data/spec/selenium_spec_firefox.rb +24 -7
  163. data/spec/selenium_spec_firefox_remote.rb +19 -4
  164. data/spec/selenium_spec_ie.rb +7 -8
  165. data/spec/selenium_spec_safari.rb +34 -20
  166. data/spec/server_spec.rb +7 -7
  167. data/spec/shared_selenium_node.rb +0 -4
  168. data/spec/shared_selenium_session.rb +24 -14
  169. data/spec/spec_helper.rb +34 -1
  170. data/spec/whitespace_normalizer_spec.rb +54 -0
  171. data/spec/xpath_builder_spec.rb +1 -1
  172. metadata +40 -14
  173. data/lib/capybara/spec/views/with_title.erb +0 -5
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#active_element', requires: [:active_element] do
4
+ it 'should return the active element' do
5
+ @session.visit('/form')
6
+ @session.send_keys(:tab)
7
+
8
+ expect(@session.active_element).to match_selector(:css, '[tabindex="1"]')
9
+
10
+ @session.send_keys(:tab)
11
+
12
+ expect(@session.active_element).to match_selector(:css, '[tabindex="2"]')
13
+ end
14
+
15
+ it 'should support reloading' do
16
+ @session.visit('/form')
17
+ expect(@session.active_element).to match_selector(:css, 'body')
18
+ @session.execute_script <<-JS
19
+ window.setTimeout(() => {
20
+ document.querySelector('#form_title').focus();
21
+ }, 1000)
22
+ JS
23
+ expect(@session.active_element).to match_selector(:css, 'body', wait: false)
24
+ expect(@session.active_element).to match_selector(:css, '#form_title', wait: 2)
25
+ end
26
+
27
+ it 'should return a Capybara::Element' do
28
+ @session.visit('/form')
29
+ expect(@session.active_element).to be_a Capybara::Node::Element
30
+ end
31
+ end
@@ -31,7 +31,7 @@ Capybara::SpecHelper.spec '#all' do
31
31
  it 'should accept an XPath instance', :exact_false do
32
32
  @session.visit('/form')
33
33
  @xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('Name')
34
- expect(@xpath).to be_a(::XPath::Union)
34
+ expect(@xpath).to be_a(XPath::Union)
35
35
  @result = @session.all(@xpath).map(&:value)
36
36
  expect(@result).to include('Smith', 'John', 'John Smith')
37
37
  end
@@ -132,7 +132,7 @@ Capybara::SpecHelper.spec '#all' do
132
132
  it 'should use the sessions ignore_hidden_elements', psc: true do
133
133
  Capybara.ignore_hidden_elements = true
134
134
  @session.config.ignore_hidden_elements = false
135
- expect(Capybara.ignore_hidden_elements).to eq(true)
135
+ expect(Capybara.ignore_hidden_elements).to be(true)
136
136
  expect(@session.all(:css, 'a.simple').size).to eq(2)
137
137
  @session.config.ignore_hidden_elements = true
138
138
  expect(@session.all(:css, 'a.simple').size).to eq(1)
@@ -203,19 +203,15 @@ Capybara::SpecHelper.spec '#all' do
203
203
  expect { @session.all(:css, 'h1, p', between: 0..3) }.to raise_error(Capybara::ExpectationNotMet)
204
204
  end
205
205
 
206
- eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.5
207
- it'treats an endless range as minimum' do
208
- expect { @session.all(:css, 'h1, p', between: 2..) }.not_to raise_error
209
- expect { @session.all(:css, 'h1, p', between: 5..) }.to raise_error(Capybara::ExpectationNotMet)
210
- end
211
- TEST
206
+ it 'treats an endless range as minimum' do
207
+ expect { @session.all(:css, 'h1, p', between: 2..) }.not_to raise_error
208
+ expect { @session.all(:css, 'h1, p', between: 5..) }.to raise_error(Capybara::ExpectationNotMet)
209
+ end
212
210
 
213
- eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.6
214
- it'treats a beginless range as maximum' do
215
- expect { @session.all(:css, 'h1, p', between: ..7) }.not_to raise_error
216
- expect { @session.all(:css, 'h1, p', between: ..3) }.to raise_error(Capybara::ExpectationNotMet)
217
- end
218
- TEST
211
+ it 'treats a beginless range as maximum' do
212
+ expect { @session.all(:css, 'h1, p', between: ..7) }.not_to raise_error
213
+ expect { @session.all(:css, 'h1, p', between: ..3) }.to raise_error(Capybara::ExpectationNotMet)
214
+ end
219
215
  end
220
216
 
221
217
  context 'with multiple count filters' do
@@ -3,16 +3,16 @@
3
3
  Capybara::SpecHelper.spec '#assert_text' do
4
4
  it 'should be true if the given text is on the page' do
5
5
  @session.visit('/with_html')
6
- expect(@session.assert_text('est')).to eq(true)
7
- expect(@session.assert_text('Lorem')).to eq(true)
8
- expect(@session.assert_text('Redirect')).to eq(true)
9
- expect(@session.assert_text(:Redirect)).to eq(true)
10
- expect(@session.assert_text('text with whitespace')).to eq(true)
6
+ expect(@session.assert_text('est')).to be(true)
7
+ expect(@session.assert_text('Lorem')).to be(true)
8
+ expect(@session.assert_text('Redirect')).to be(true)
9
+ expect(@session.assert_text(:Redirect)).to be(true)
10
+ expect(@session.assert_text('text with whitespace')).to be(true)
11
11
  end
12
12
 
13
13
  it 'should support collapsing whitespace' do
14
14
  @session.visit('/with_html')
15
- expect(@session.assert_text('text with whitespace', normalize_ws: true)).to eq(true)
15
+ expect(@session.assert_text('text with whitespace', normalize_ws: true)).to be(true)
16
16
  end
17
17
 
18
18
  context 'with enabled default collapsing whitespace' do
@@ -20,19 +20,19 @@ Capybara::SpecHelper.spec '#assert_text' do
20
20
 
21
21
  it 'should be true if the given unnormalized text is on the page' do
22
22
  @session.visit('/with_html')
23
- expect(@session.assert_text('text with whitespace', normalize_ws: false)).to eq(true)
23
+ expect(@session.assert_text('text with whitespace', normalize_ws: false)).to be(true)
24
24
  end
25
25
 
26
26
  it 'should support collapsing whitespace' do
27
27
  @session.visit('/with_html')
28
- expect(@session.assert_text('text with whitespace')).to eq(true)
28
+ expect(@session.assert_text('text with whitespace')).to be(true)
29
29
  end
30
30
  end
31
31
 
32
32
  it 'should take scopes into account' do
33
33
  @session.visit('/with_html')
34
34
  @session.within("//a[@title='awesome title']") do
35
- expect(@session.assert_text('labore')).to eq(true)
35
+ expect(@session.assert_text('labore')).to be(true)
36
36
  end
37
37
  end
38
38
 
@@ -47,13 +47,13 @@ Capybara::SpecHelper.spec '#assert_text' do
47
47
 
48
48
  it 'should be true if :all given and text is invisible.' do
49
49
  @session.visit('/with_html')
50
- expect(@session.assert_text(:all, 'Some of this text is hidden!')).to eq(true)
50
+ expect(@session.assert_text(:all, 'Some of this text is hidden!')).to be(true)
51
51
  end
52
52
 
53
53
  it 'should be true if `Capybara.ignore_hidden_elements = true` and text is invisible.' do
54
54
  Capybara.ignore_hidden_elements = false
55
55
  @session.visit('/with_html')
56
- expect(@session.assert_text('Some of this text is hidden!')).to eq(true)
56
+ expect(@session.assert_text('Some of this text is hidden!')).to be(true)
57
57
  end
58
58
 
59
59
  it 'should raise error with a helpful message if the requested text is present but invisible' do
@@ -88,7 +88,7 @@ Capybara::SpecHelper.spec '#assert_text' do
88
88
 
89
89
  it 'should be true if the text in the page matches given regexp' do
90
90
  @session.visit('/with_html')
91
- expect(@session.assert_text(/Lorem/)).to eq(true)
91
+ expect(@session.assert_text(/Lorem/)).to be(true)
92
92
  end
93
93
 
94
94
  it "should raise error if the text in the page doesn't match given regexp" do
@@ -109,13 +109,13 @@ Capybara::SpecHelper.spec '#assert_text' do
109
109
  Capybara.default_max_wait_time = 2
110
110
  @session.visit('/with_js')
111
111
  @session.click_link('Click me')
112
- expect(@session.assert_text('Has been clicked')).to eq(true)
112
+ expect(@session.assert_text('Has been clicked')).to be(true)
113
113
  end
114
114
 
115
115
  context 'with between' do
116
116
  it 'should be true if the text occurs within the range given' do
117
117
  @session.visit('/with_count')
118
- expect(@session.assert_text('count', between: 1..3)).to eq(true)
118
+ expect(@session.assert_text('count', between: 1..3)).to be(true)
119
119
  end
120
120
 
121
121
  it 'should be false if the text occurs more or fewer times than range' do
@@ -203,13 +203,13 @@ Capybara::SpecHelper.spec '#assert_no_text' do
203
203
  it 'should be true if scoped to an element which does not have the text' do
204
204
  @session.visit('/with_html')
205
205
  @session.within("//a[@title='awesome title']") do
206
- expect(@session.assert_no_text('monkey')).to eq(true)
206
+ expect(@session.assert_no_text('monkey')).to be(true)
207
207
  end
208
208
  end
209
209
 
210
210
  it 'should be true if the given text is on the page but not visible' do
211
211
  @session.visit('/with_html')
212
- expect(@session.assert_no_text('Inside element with hidden ancestor')).to eq(true)
212
+ expect(@session.assert_no_text('Inside element with hidden ancestor')).to be(true)
213
213
  end
214
214
 
215
215
  it 'should raise error if :all given and text is invisible.' do
@@ -236,7 +236,7 @@ Capybara::SpecHelper.spec '#assert_no_text' do
236
236
  context 'with count' do
237
237
  it 'should be true if the text occurs within the range given' do
238
238
  @session.visit('/with_count')
239
- expect(@session.assert_text('count', count: 2)).to eq(true)
239
+ expect(@session.assert_text('count', count: 2)).to be(true)
240
240
  end
241
241
 
242
242
  it 'should be false if the text occurs more or fewer times than range' do
@@ -55,6 +55,12 @@ Capybara::SpecHelper.spec '#attach_file' do
55
55
  expect(@session).to have_content('No file uploaded')
56
56
  end
57
57
 
58
+ it 'should send prior hidden field if no file submitted' do
59
+ @session.click_button('Upload Empty With Hidden')
60
+ expect(extract_results(@session)['document2']).to eq('hidden_field')
61
+ expect(extract_content_type(@session)).to start_with('multipart/form-data;')
62
+ end
63
+
58
64
  it 'should send content type text/plain when uploading a text file' do
59
65
  @session.attach_file 'Single Document', with_os_path_separators(test_file_path)
60
66
  @session.click_button 'Upload Single'
@@ -236,6 +236,16 @@ Capybara::SpecHelper.spec '#check' do
236
236
  expect(@session).to have_field('multi_label_checkbox', checked: true, visible: :hidden)
237
237
  end
238
238
  end
239
+
240
+ context 'with allow_label_click options', requires: [:js] do
241
+ it 'should allow offsets to click location on label' do
242
+ Capybara.w3c_click_offset = false
243
+ expect(@session.find(:checkbox, 'form_cars_lotus', unchecked: true, visible: :hidden)).to be_truthy
244
+ @session.check('form_cars_lotus', allow_label_click: { x: 90, y: 10 })
245
+ @session.click_button('awesome')
246
+ expect(extract_results(@session)['cars']).to include('lotus')
247
+ end
248
+ end
239
249
  end
240
250
  end
241
251
  end
@@ -11,6 +11,12 @@ Capybara::SpecHelper.spec '#choose' do
11
11
  expect(extract_results(@session)['gender']).to eq('male')
12
12
  end
13
13
 
14
+ it 'ignores readonly attribute on radio buttons' do
15
+ @session.choose('gender_both')
16
+ @session.click_button('awesome')
17
+ expect(extract_results(@session)['gender']).to eq('both')
18
+ end
19
+
14
20
  it 'should choose a radio button by label' do
15
21
  @session.choose('Both')
16
22
  @session.click_button('awesome')
@@ -131,6 +131,17 @@ Capybara::SpecHelper.spec '#click_link' do
131
131
  end
132
132
  end
133
133
 
134
+ context 'with :target option given' do
135
+ it 'should find links with valid target' do
136
+ @session.click_link('labore', target: '_self')
137
+ expect(@session).to have_content('Bar')
138
+ end
139
+
140
+ it "should raise error if link wasn't found" do
141
+ expect { @session.click_link('labore', target: '_blank') }.to raise_error(Capybara::ElementNotFound, /Unable to find link "labore"/)
142
+ end
143
+ end
144
+
134
145
  it 'should follow relative links' do
135
146
  @session.visit('/')
136
147
  @session.click_link('Relative')
@@ -7,7 +7,7 @@ Capybara::SpecHelper.spec '#current_scope' do
7
7
 
8
8
  context 'when not in a #within block' do
9
9
  it 'should return the document' do
10
- expect(@session.current_scope).to be_kind_of Capybara::Node::Document
10
+ expect(@session.current_scope).to be_a Capybara::Node::Document
11
11
  end
12
12
  end
13
13
 
@@ -98,6 +98,12 @@ Capybara::SpecHelper.spec '#fill_in' do
98
98
  expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
99
99
  end
100
100
 
101
+ it 'should handle carriage returns with line feeds in a textarea correctly' do
102
+ @session.fill_in('form_description', with: "\r\nSome text\r\n")
103
+ @session.click_button('awesome')
104
+ expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
105
+ end
106
+
101
107
  it 'should fill in a color field' do
102
108
  @session.fill_in('Html5 Color', with: '#112233')
103
109
  @session.click_button('html5_submit')
@@ -67,4 +67,14 @@ Capybara::SpecHelper.spec '#find_link' do
67
67
  expect { @session.find_link(download: 37) }.to raise_error ArgumentError
68
68
  end
69
69
  end
70
+
71
+ context 'with :target option' do
72
+ it 'should accept partial matches when false' do
73
+ expect(@session.find_link(target: '_self').text).to eq('labore')
74
+ end
75
+
76
+ it 'should not accept partial matches when true' do
77
+ expect { @session.find_link(target: '_blank') }.to raise_error Capybara::ElementNotFound
78
+ end
79
+ end
70
80
  end
@@ -236,7 +236,7 @@ Capybara::SpecHelper.spec '#find' do
236
236
  it 'should accept an XPath instance' do
237
237
  @session.visit('/form')
238
238
  @xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
239
- expect(@xpath).to be_a(::XPath::Union)
239
+ expect(@xpath).to be_a(XPath::Union)
240
240
  expect(@session.find(@xpath).value).to eq('John')
241
241
  end
242
242
 
@@ -528,4 +528,10 @@ Capybara::SpecHelper.spec '#find' do
528
528
  expect(@session.find(:link, 'test-foo')[:id]).to eq 'foo'
529
529
  end
530
530
  end
531
+
532
+ it 'should warn if passed count options' do
533
+ allow(Capybara::Helpers).to receive(:warn)
534
+ @session.find('//h1', count: 44)
535
+ expect(Capybara::Helpers).to have_received(:warn).with(/'find' does not support count options/)
536
+ end
531
537
  end
@@ -25,7 +25,7 @@ Capybara::SpecHelper.spec '#first' do
25
25
  it 'should accept an XPath instance' do
26
26
  @session.visit('/form')
27
27
  @xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
28
- expect(@xpath).to be_a(::XPath::Union)
28
+ expect(@xpath).to be_a(XPath::Union)
29
29
  expect(@session.first(@xpath).value).to eq('John')
30
30
  end
31
31
 
@@ -64,7 +64,9 @@ Capybara::SpecHelper.spec '#within_frame', requires: [:frames] do
64
64
  end
65
65
  expect do
66
66
  # Multiple frames in scope here
67
+ # rubocop:disable Style/Semicolon
67
68
  @session.within_frame { ; }
69
+ # rubocop:enable Style/Semicolon
68
70
  end.to raise_error Capybara::Ambiguous
69
71
  end
70
72
 
@@ -12,7 +12,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
12
12
  it 'should be false if any of the given selectors are not on the page' do
13
13
  expect do
14
14
  expect(@session).to have_all_of_selectors(:css, 'p a#foo', 'h2#h2three', 'h2#h2one')
15
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
15
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
16
16
  end
17
17
 
18
18
  it 'should use default selector' do
@@ -20,7 +20,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
20
20
  expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2two', 'h2#h2one')
21
21
  expect do
22
22
  expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2three', 'h2#h2one')
23
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
23
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
24
24
  end
25
25
 
26
26
  context 'should respect scopes' do
@@ -29,7 +29,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
29
29
  expect(@session).to have_all_of_selectors(".//a[@id='foo']")
30
30
  expect do
31
31
  expect(@session).to have_all_of_selectors(".//a[@id='red']")
32
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
32
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
33
33
  end
34
34
  end
35
35
 
@@ -38,7 +38,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
38
38
  expect(el).to have_all_of_selectors(".//a[@id='foo']")
39
39
  expect do
40
40
  expect(el).to have_all_of_selectors(".//a[@id='red']")
41
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
41
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
42
42
  end
43
43
  end
44
44
 
@@ -47,7 +47,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
47
47
  expect(@session).to have_all_of_selectors(:field, 'normal', 'additional_newline', type: :textarea)
48
48
  expect do
49
49
  expect(@session).to have_all_of_selectors(:field, 'normal', 'test_field', 'additional_newline', type: :textarea)
50
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
50
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
51
51
  end
52
52
  end
53
53
 
@@ -39,8 +39,8 @@ Capybara::SpecHelper.spec '#have_no_ancestor' do
39
39
  it 'should assert no matching ancestor' do
40
40
  el = @session.find(:css, '#ancestor1')
41
41
  expect(el).to have_no_ancestor(:css, '#child')
42
- expect(el).to have_no_ancestor(:css, '#ancestor1_sibiling')
42
+ expect(el).to have_no_ancestor(:css, '#ancestor1_sibling')
43
43
  expect(el).not_to have_ancestor(:css, '#child')
44
- expect(el).not_to have_ancestor(:css, '#ancestor1_sibiling')
44
+ expect(el).not_to have_ancestor(:css, '#ancestor1_sibling')
45
45
  end
46
46
  end
@@ -12,7 +12,7 @@ Capybara::SpecHelper.spec '#have_any_of_selectors' do
12
12
  it 'should be false if none of the given selectors are not on the page' do
13
13
  expect do
14
14
  expect(@session).to have_any_of_selectors(:css, 'span a#foo', 'h2#h2nope', 'h2#h2one_no')
15
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
15
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
16
16
  end
17
17
 
18
18
  it 'should use default selector' do
@@ -20,6 +20,10 @@ Capybara::SpecHelper.spec '#have_any_of_selectors' do
20
20
  expect(@session).to have_any_of_selectors('p a#foo', 'h2#h2two', 'a#not_on_page')
21
21
  expect do
22
22
  expect(@session).to have_any_of_selectors('p a#blah', 'h2#h2three')
23
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
23
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
24
+ end
25
+
26
+ it 'should be negateable' do
27
+ expect(@session).not_to have_any_of_selectors(:css, 'span a#foo', 'h2#h2nope', 'h2#h2one_no')
24
28
  end
25
29
  end
@@ -65,6 +65,24 @@ Capybara::SpecHelper.spec '#has_button?' do
65
65
  it 'should not affect other selectors when enable_aria_role: false' do
66
66
  expect(@session).to have_button('Click me!', enable_aria_role: false)
67
67
  end
68
+
69
+ context 'with focused:', requires: [:active_element] do
70
+ it 'should be true if a field has focus when focused: true' do
71
+ @session.send_keys(:tab)
72
+
73
+ expect(@session).to have_button('A Button', focused: true)
74
+ end
75
+
76
+ it 'should be true if a field does not have focus when focused: false' do
77
+ expect(@session).to have_button('A Button', focused: false)
78
+ end
79
+ end
80
+
81
+ it 'should raise an error if an invalid option is passed' do
82
+ expect do
83
+ expect(@session).to have_button('A Button', invalid: true)
84
+ end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :disabled, :name, :value, :title, :type')
85
+ end
68
86
  end
69
87
 
70
88
  Capybara::SpecHelper.spec '#has_no_button?' do
@@ -117,4 +135,16 @@ Capybara::SpecHelper.spec '#has_no_button?' do
117
135
  it 'should not affect other selectors when enable_aria_role: false' do
118
136
  expect(@session).to have_no_button('Junk button that does not exist', enable_aria_role: false)
119
137
  end
138
+
139
+ context 'with focused:', requires: [:active_element] do
140
+ it 'should be true if a button does not have focus when focused: true' do
141
+ expect(@session).to have_no_button('A Button', focused: true)
142
+ end
143
+
144
+ it 'should be false if a button has focus when focused: false' do
145
+ @session.send_keys(:tab)
146
+
147
+ expect(@session).to have_no_button('A Button', focused: false)
148
+ end
149
+ end
120
150
  end
@@ -16,8 +16,8 @@ Capybara::SpecHelper.spec '#has_current_path?' do
16
16
 
17
17
  it 'should not raise an error when non-http' do
18
18
  @session.reset_session!
19
- expect(@session.has_current_path?(/monkey/)).to eq false
20
- expect(@session.has_current_path?('/with_js')).to eq false
19
+ expect(@session.has_current_path?(/monkey/)).to be false
20
+ expect(@session.has_current_path?('/with_js')).to be false
21
21
  end
22
22
 
23
23
  it 'should handle non-escaped query options' do
@@ -75,7 +75,7 @@ Capybara::SpecHelper.spec '#has_current_path?' do
75
75
  @session.visit('/with_js?test=test')
76
76
  expect(@session).to have_current_path('/with_js?test=test')
77
77
  expect(@session).to have_current_path('/with_js', ignore_query: true)
78
- uri = ::Addressable::URI.parse(@session.current_url)
78
+ uri = Addressable::URI.parse(@session.current_url)
79
79
  uri.query = nil
80
80
  expect(@session).to have_current_path(uri.to_s, ignore_query: true)
81
81
  end
@@ -110,6 +110,18 @@ Capybara::SpecHelper.spec '#has_field' do
110
110
  end
111
111
  end
112
112
 
113
+ context 'with focused:', requires: [:active_element] do
114
+ it 'should be true if a field has focus' do
115
+ 2.times { @session.send_keys(:tab) }
116
+
117
+ expect(@session).to have_field('An Input', focused: true)
118
+ end
119
+
120
+ it 'should be false if a field does not have focus' do
121
+ expect(@session).to have_field('An Input', focused: false)
122
+ end
123
+ end
124
+
113
125
  context 'with valid', requires: [:js] do
114
126
  it 'should be true if field is valid' do
115
127
  @session.fill_in 'required', with: 'something'
@@ -184,6 +196,18 @@ Capybara::SpecHelper.spec '#has_no_field' do
184
196
  expect(@session).to have_no_field('Languages', type: 'textarea')
185
197
  end
186
198
  end
199
+
200
+ context 'with focused:', requires: [:active_element] do
201
+ it 'should be true if a field does not have focus when focused: true' do
202
+ expect(@session).to have_no_field('An Input', focused: true)
203
+ end
204
+
205
+ it 'should be false if a field has focus when focused: true' do
206
+ 2.times { @session.send_keys(:tab) }
207
+
208
+ expect(@session).not_to have_no_field('An Input', focused: true)
209
+ end
210
+ end
187
211
  end
188
212
 
189
213
  Capybara::SpecHelper.spec '#has_checked_field?' do
@@ -359,7 +383,7 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
359
383
  end
360
384
 
361
385
  it 'should support locator-less usage' do
362
- expect(@session.has_no_unchecked_field?(disabled: false, id: 'form_disabled_unchecked_checkbox')).to eq true
386
+ expect(@session.has_no_unchecked_field?(disabled: false, id: 'form_disabled_unchecked_checkbox')).to be true
363
387
  expect(@session).to have_no_unchecked_field(disabled: false, id: 'form_disabled_unchecked_checkbox')
364
388
  end
365
389
  end
@@ -11,12 +11,38 @@ Capybara::SpecHelper.spec '#has_link?' do
11
11
  expect(@session).to have_link('A link', href: '/with_simple_html')
12
12
  expect(@session).to have_link(:'A link', href: :'/with_simple_html')
13
13
  expect(@session).to have_link('A link', href: %r{/with_simple_html})
14
+ expect(@session).to have_link('labore', target: '_self')
14
15
  end
15
16
 
16
17
  it 'should be false if the given link is not on the page' do
17
18
  expect(@session).not_to have_link('monkey')
18
19
  expect(@session).not_to have_link('A link', href: '/nonexistent-href')
19
20
  expect(@session).not_to have_link('A link', href: /nonexistent/)
21
+ expect(@session).not_to have_link('labore', target: '_blank')
22
+ end
23
+
24
+ it 'should notify if an invalid locator is specified' do
25
+ allow(Capybara::Helpers).to receive(:warn).and_return(nil)
26
+ @session.has_link?(@session)
27
+ expect(Capybara::Helpers).to have_received(:warn).with(/Called from: .+/)
28
+ end
29
+
30
+ context 'with focused:', requires: [:active_element] do
31
+ it 'should be true if the given link is on the page and has focus' do
32
+ @session.send_keys(:tab)
33
+
34
+ expect(@session).to have_link('labore', focused: true)
35
+ end
36
+
37
+ it 'should be false if the given link is on the page and does not have focus' do
38
+ expect(@session).to have_link('labore', focused: false)
39
+ end
40
+ end
41
+
42
+ it 'should raise an error if an invalid option is passed' do
43
+ expect do
44
+ expect(@session).to have_link('labore', invalid: true)
45
+ end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :target, :download')
20
46
  end
21
47
  end
22
48
 
@@ -29,11 +55,25 @@ Capybara::SpecHelper.spec '#has_no_link?' do
29
55
  expect(@session).not_to have_no_link('foo')
30
56
  expect(@session).not_to have_no_link('awesome title')
31
57
  expect(@session).not_to have_no_link('A link', href: '/with_simple_html')
58
+ expect(@session).not_to have_no_link('labore', target: '_self')
32
59
  end
33
60
 
34
61
  it 'should be true if the given link is not on the page' do
35
62
  expect(@session).to have_no_link('monkey')
36
63
  expect(@session).to have_no_link('A link', href: '/nonexistent-href')
37
64
  expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
65
+ expect(@session).to have_no_link('labore', target: '_blank')
66
+ end
67
+
68
+ context 'with focused:', requires: [:active_element] do
69
+ it 'should be true if the given link is on the page and has focus' do
70
+ expect(@session).to have_no_link('labore', focused: true)
71
+ end
72
+
73
+ it 'should be false if the given link is on the page and does not have focus' do
74
+ @session.send_keys(:tab)
75
+
76
+ expect(@session).to have_no_link('labore', focused: false)
77
+ end
38
78
  end
39
79
  end
@@ -8,10 +8,10 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
8
8
  it 'should be false if any of the given locators are on the page' do
9
9
  expect do
10
10
  expect(@session).to have_none_of_selectors(:xpath, '//p', '//a')
11
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
11
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
12
12
  expect do
13
13
  expect(@session).to have_none_of_selectors(:css, 'p a#foo')
14
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
14
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
15
15
  end
16
16
 
17
17
  it 'should be true if none of the given locators are on the page' do
@@ -24,7 +24,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
24
24
  expect(@session).to have_none_of_selectors('p a#doesnotexist', 'abbr')
25
25
  expect do
26
26
  expect(@session).to have_none_of_selectors('abbr', 'p a#foo')
27
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
27
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
28
28
  end
29
29
 
30
30
  context 'should respect scopes' do
@@ -32,7 +32,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
32
32
  @session.within "//p[@id='first']" do
33
33
  expect do
34
34
  expect(@session).to have_none_of_selectors(".//a[@id='foo']")
35
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
35
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
36
36
  expect(@session).to have_none_of_selectors(".//a[@id='red']")
37
37
  end
38
38
  end
@@ -41,7 +41,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
41
41
  el = @session.find "//p[@id='first']"
42
42
  expect do
43
43
  expect(el).to have_none_of_selectors(".//a[@id='foo']")
44
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
44
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
45
45
  expect(el).to have_none_of_selectors(".//a[@id='red']")
46
46
  end
47
47
  end
@@ -50,14 +50,14 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
50
50
  it 'should apply the options to all locators' do
51
51
  expect do
52
52
  expect(@session).to have_none_of_selectors('//p//a', text: 'Redirect')
53
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
53
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
54
54
  expect(@session).to have_none_of_selectors('//p', text: 'Doesnotexist')
55
55
  end
56
56
 
57
57
  it 'should discard all matches where the given regexp is matched' do
58
58
  expect do
59
59
  expect(@session).to have_none_of_selectors('//p//a', text: /re[dab]i/i, count: 1)
60
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
60
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
61
61
  expect(@session).to have_none_of_selectors('//p//a', text: /Red$/)
62
62
  end
63
63
  end