capybara 3.36.0 → 3.37.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +27 -1
  3. data/README.md +1 -1
  4. data/lib/capybara/driver/node.rb +4 -0
  5. data/lib/capybara/dsl.rb +4 -10
  6. data/lib/capybara/helpers.rb +1 -1
  7. data/lib/capybara/minitest/spec.rb +2 -2
  8. data/lib/capybara/node/element.rb +12 -1
  9. data/lib/capybara/node/finders.rb +8 -1
  10. data/lib/capybara/queries/selector_query.rb +20 -7
  11. data/lib/capybara/rack_test/browser.rb +56 -7
  12. data/lib/capybara/rack_test/driver.rb +4 -4
  13. data/lib/capybara/rack_test/node.rb +1 -1
  14. data/lib/capybara/registration_container.rb +0 -3
  15. data/lib/capybara/rspec/matchers/have_selector.rb +4 -4
  16. data/lib/capybara/rspec/matchers.rb +14 -14
  17. data/lib/capybara/selector/definition.rb +2 -1
  18. data/lib/capybara/selector/selector.rb +5 -1
  19. data/lib/capybara/selenium/driver.rb +6 -2
  20. data/lib/capybara/selenium/node.rb +12 -0
  21. data/lib/capybara/server/animation_disabler.rb +29 -17
  22. data/lib/capybara/session/config.rb +1 -1
  23. data/lib/capybara/session.rb +8 -21
  24. data/lib/capybara/spec/session/all_spec.rb +5 -7
  25. data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
  26. data/lib/capybara/spec/session/find_spec.rb +6 -0
  27. data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
  28. data/lib/capybara/spec/session/has_field_spec.rb +1 -1
  29. data/lib/capybara/spec/session/has_link_spec.rb +6 -0
  30. data/lib/capybara/spec/session/has_select_spec.rb +4 -4
  31. data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
  32. data/lib/capybara/spec/session/has_text_spec.rb +1 -5
  33. data/lib/capybara/spec/session/node_spec.rb +42 -0
  34. data/lib/capybara/spec/session/visit_spec.rb +20 -0
  35. data/lib/capybara/spec/session/window/window_spec.rb +1 -1
  36. data/lib/capybara/spec/test_app.rb +49 -0
  37. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  38. data/lib/capybara/version.rb +1 -1
  39. data/lib/capybara/window.rb +1 -1
  40. data/lib/capybara.rb +1 -0
  41. data/spec/dsl_spec.rb +2 -2
  42. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
  43. data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
  44. data/spec/rack_test_spec.rb +6 -0
  45. data/spec/result_spec.rb +27 -29
  46. data/spec/rspec/features_spec.rb +2 -2
  47. data/spec/rspec/scenarios_spec.rb +1 -1
  48. data/spec/sauce_spec_chrome.rb +3 -3
  49. data/spec/selector_spec.rb +2 -2
  50. data/spec/selenium_spec_chrome.rb +1 -1
  51. data/spec/selenium_spec_firefox.rb +5 -1
  52. data/spec/selenium_spec_safari.rb +5 -1
  53. data/spec/server_spec.rb +5 -5
  54. data/spec/shared_selenium_session.rb +9 -2
  55. data/spec/spec_helper.rb +1 -1
  56. metadata +6 -4
@@ -765,33 +765,20 @@ module Capybara
765
765
  end
766
766
 
767
767
  NODE_METHODS.each do |method|
768
- if RUBY_VERSION >= '2.7'
769
- class_eval <<~METHOD, __FILE__, __LINE__ + 1
770
- def #{method}(...)
771
- @touched = true
772
- current_scope.#{method}(...)
773
- end
774
- METHOD
775
- else
776
- define_method method do |*args, &block|
768
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
769
+ def #{method}(...)
777
770
  @touched = true
778
- current_scope.send(method, *args, &block)
771
+ current_scope.#{method}(...)
779
772
  end
780
- end
773
+ METHOD
781
774
  end
782
775
 
783
776
  DOCUMENT_METHODS.each do |method|
784
- if RUBY_VERSION >= '2.7'
785
- class_eval <<~METHOD, __FILE__, __LINE__ + 1
786
- def #{method}(...)
787
- document.#{method}(...)
788
- end
789
- METHOD
790
- else
791
- define_method method do |*args, &block|
792
- document.send(method, *args, &block)
777
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
778
+ def #{method}(...)
779
+ document.#{method}(...)
793
780
  end
794
- end
781
+ METHOD
795
782
  end
796
783
 
797
784
  def inspect
@@ -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)
@@ -208,12 +208,10 @@ Capybara::SpecHelper.spec '#all' do
208
208
  expect { @session.all(:css, 'h1, p', between: 5..) }.to raise_error(Capybara::ExpectationNotMet)
209
209
  end
210
210
 
211
- eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.6
212
- it'treats a beginless range as maximum' do
213
- expect { @session.all(:css, 'h1, p', between: ..7) }.not_to raise_error
214
- expect { @session.all(:css, 'h1, p', between: ..3) }.to raise_error(Capybara::ExpectationNotMet)
215
- end
216
- 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
217
215
  end
218
216
 
219
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
@@ -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
@@ -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
@@ -383,7 +383,7 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
383
383
  end
384
384
 
385
385
  it 'should support locator-less usage' do
386
- 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
387
387
  expect(@session).to have_no_unchecked_field(disabled: false, id: 'form_disabled_unchecked_checkbox')
388
388
  end
389
389
  end
@@ -19,6 +19,12 @@ Capybara::SpecHelper.spec '#has_link?' do
19
19
  expect(@session).not_to have_link('A link', href: /nonexistent/)
20
20
  end
21
21
 
22
+ it 'should notify if an invalid locator is specified' do
23
+ allow(Capybara::Helpers).to receive(:warn).and_return(nil)
24
+ @session.has_link?(@session)
25
+ expect(Capybara::Helpers).to have_received(:warn).with(/Called from: .+/)
26
+ end
27
+
22
28
  context 'with focused:', requires: [:active_element] do
23
29
  it 'should be true if the given link is on the page and has focus' do
24
30
  @session.send_keys(:tab)
@@ -180,9 +180,9 @@ Capybara::SpecHelper.spec '#has_select?' do
180
180
  end
181
181
 
182
182
  it 'should support locator-less usage' do
183
- expect(@session.has_select?(with_options: %w[Norway Sweden])).to eq true
183
+ expect(@session.has_select?(with_options: %w[Norway Sweden])).to be true
184
184
  expect(@session).to have_select(with_options: ['London'])
185
- expect(@session.has_select?(with_selected: %w[Commando Boxerbriefs])).to eq true
185
+ expect(@session.has_select?(with_selected: %w[Commando Boxerbriefs])).to be true
186
186
  expect(@session).to have_select(with_selected: ['Briefs'])
187
187
  end
188
188
  end
@@ -302,9 +302,9 @@ Capybara::SpecHelper.spec '#has_no_select?' do
302
302
  end
303
303
 
304
304
  it 'should support locator-less usage' do
305
- expect(@session.has_no_select?(with_options: %w[Norway Sweden Finland Latvia])).to eq true
305
+ expect(@session.has_no_select?(with_options: %w[Norway Sweden Finland Latvia])).to be true
306
306
  expect(@session).to have_no_select(with_options: ['New London'])
307
- expect(@session.has_no_select?(id: 'form_underwear', with_selected: ['Boxers'])).to eq true
307
+ expect(@session.has_no_select?(id: 'form_underwear', with_selected: ['Boxers'])).to be true
308
308
  expect(@session).to have_no_select(id: 'form_underwear', with_selected: %w[Commando Boxers])
309
309
  end
310
310
  end
@@ -117,6 +117,21 @@ Capybara::SpecHelper.spec '#has_selector?' do
117
117
  expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test One', exact_text: false)
118
118
  expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test', exact_text: false)
119
119
  end
120
+
121
+ it 'should warn if text option is a regexp that it is ignoring exact_text' do
122
+ allow(Capybara::Helpers).to receive(:warn)
123
+ expect(@session).to have_selector(:id, 'h2one', text: /Class Test/, exact_text: true)
124
+ expect(Capybara::Helpers).to have_received(:warn).with(/'exact_text' option is not supported/)
125
+ end
126
+ end
127
+
128
+ context 'regexp' do
129
+ it 'should only match when it fully matches' do
130
+ expect(@session).to have_selector(:id, 'h2one', exact_text: /Header Class Test One/)
131
+ expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Header Class Test/)
132
+ expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test One/)
133
+ expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test/)
134
+ end
120
135
  end
121
136
  end
122
137
 
@@ -127,11 +127,7 @@ Capybara::SpecHelper.spec '#has_text?' do
127
127
  def to_hash; { value: 'Other hash' } end
128
128
  end.new
129
129
  @session.visit('/with_html')
130
- if RUBY_VERSION >= '2.7'
131
- expect(@session).to have_text(:visible, with_to_hash, **{})
132
- else
133
- expect(@session).to have_text(:visible, with_to_hash, {})
134
- end
130
+ expect(@session).to have_text(:visible, with_to_hash, **{})
135
131
  end
136
132
  end
137
133
 
@@ -1176,6 +1176,48 @@ Capybara::SpecHelper.spec 'node' do
1176
1176
  end
1177
1177
  end
1178
1178
 
1179
+ describe '#shadow_root', requires: %i[js] do
1180
+ it 'should get the shadow root' do
1181
+ @session.visit('/with_shadow')
1182
+ expect do
1183
+ shadow_root = @session.find(:css, '#shadow_host').shadow_root
1184
+ expect(shadow_root).not_to be_nil
1185
+ end.not_to raise_error
1186
+ end
1187
+
1188
+ it 'should find elements inside the shadow dom using CSS' do
1189
+ @session.visit('/with_shadow')
1190
+ shadow_root = @session.find(:css, '#shadow_host').shadow_root
1191
+ expect(shadow_root).to have_css('#shadow_content', text: 'some text')
1192
+ end
1193
+
1194
+ it 'should find nested shadow roots' do
1195
+ @session.visit('/with_shadow')
1196
+ shadow_root = @session.find(:css, '#shadow_host').shadow_root
1197
+ nested_shadow_root = shadow_root.find(:css, '#nested_shadow_host').shadow_root
1198
+ expect(nested_shadow_root).to have_css('#nested_shadow_content', text: 'nested text')
1199
+ end
1200
+
1201
+ it 'should click on elements' do
1202
+ @session.visit('/with_shadow')
1203
+ shadow_root = @session.find(:css, '#shadow_host').shadow_root
1204
+ checkbox = shadow_root.find(:css, 'input[type="checkbox"]')
1205
+ expect(checkbox).not_to be_checked
1206
+ checkbox.click
1207
+ expect(checkbox).to be_checked
1208
+ end
1209
+
1210
+ it 'should use convenience methods once moved to a descendant of the shadow root' do
1211
+ @session.visit('/with_shadow')
1212
+ shadow_root = @session.find(:css, '#shadow_host').shadow_root
1213
+ descendant = shadow_root.find(:css, '#controls_wrapper')
1214
+ expect do
1215
+ descendant.check('shadow_checkbox')
1216
+ end.not_to raise_error
1217
+ expect(descendant).to have_checked_field('shadow_checkbox')
1218
+ end
1219
+ end
1220
+
1179
1221
  describe '#reload', requires: [:js] do
1180
1222
  it 'should reload elements found via ancestor with CSS' do
1181
1223
  @session.visit('/with_js')
@@ -201,4 +201,24 @@ Capybara::SpecHelper.spec '#visit' do
201
201
  @session.visit('/get_cookie')
202
202
  expect(@session).to have_content('root cookie')
203
203
  end
204
+
205
+ context 'with base element' do
206
+ it 'should use base href with relative links' do
207
+ @session.visit('/base/with_base')
208
+ @session.click_link('Title page')
209
+ expect(@session).to have_current_path('/with_title')
210
+ end
211
+
212
+ it 'should use base href with bare queries' do
213
+ @session.visit('/base/with_base')
214
+ @session.click_link('Bare query')
215
+ expect(@session).to have_current_path('/?a=3')
216
+ end
217
+
218
+ it 'should not use the base href with a new visit call' do
219
+ @session.visit('/base/with_other_base')
220
+ @session.visit('with_html')
221
+ expect(@session).to have_current_path('/with_html')
222
+ end
223
+ end
204
224
  end
@@ -59,7 +59,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
59
59
  it 'should return false if window is closed' do
60
60
  @session.switch_to_window(other_window)
61
61
  other_window.close
62
- expect(other_window.current?).to eq(false)
62
+ expect(other_window.current?).to be(false)
63
63
  end
64
64
  end
65
65
 
@@ -177,6 +177,55 @@ class TestApp < Sinatra::Base
177
177
  HTML
178
178
  end
179
179
 
180
+ get '/base/with_base' do
181
+ <<-HTML
182
+ <!DOCTYPE html>
183
+ <html>
184
+ <head>
185
+ <base href="/">
186
+ <title>Origin</title>
187
+ </head>
188
+ <body>
189
+ <a href="with_title">Title page</a>
190
+ <a href="?a=3">Bare query</a>
191
+ </body>
192
+ </html>
193
+ HTML
194
+ end
195
+
196
+ get '/base/with_other_base' do
197
+ <<-HTML
198
+ <!DOCTYPE html>
199
+ <html>
200
+ <head>
201
+ <base href="/base/">
202
+ <title>Origin</title>
203
+ </head>
204
+ <body>
205
+ <a href="with_title">Title page</a>
206
+ <a href="?a=3">Bare query</a>
207
+ </body>
208
+ </html>
209
+ HTML
210
+ end
211
+
212
+ get '/csp' do
213
+ response.headers['Content-Security-Policy'] = "default-src 'none'; connect-src 'self'; base-uri 'none'; font-src 'self'; img-src 'self' data:; object-src 'none'; script-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; style-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; form-action 'self';"
214
+ <<-HTML
215
+ <!DOCTYPE html>
216
+ <html lang="en">
217
+ <head>
218
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
219
+ <title>CSP</title>
220
+ </head>
221
+
222
+ <body>
223
+ <div>CSP</div>
224
+ </body>
225
+ </html>
226
+ HTML
227
+ end
228
+
180
229
  get '/download.csv' do
181
230
  content_type 'text/csv'
182
231
  'This, is, comma, separated' \
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <%# Borrowed from Titus Fortner %>
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6
+ <title>Shadow DOM</title>
7
+ </head>
8
+ <body>
9
+ <div id="no_host"></div>
10
+ <div id="shadow_host"></div>
11
+ <a href="scroll.html">scroll.html</a>
12
+ <script>
13
+ let shadowRoot = document.getElementById('shadow_host').attachShadow({mode: 'open'});
14
+ shadowRoot.innerHTML = `
15
+ <span class="wrapper" id="shadow_content"><span class="info">some text</span></span>
16
+ <div id="nested_shadow_host"></div>
17
+ <a href="scroll.html">scroll.html</a>
18
+ <div id="controls_wrapper">
19
+ <input type="text" />
20
+ <input type="checkbox" id="shadow_checkbox" />
21
+ <input type="file" />
22
+ </div>
23
+ `;
24
+
25
+ let nestedShadowRoot = shadowRoot.getElementById('nested_shadow_host').attachShadow({mode: 'open'});
26
+ nestedShadowRoot.innerHTML = `
27
+ <div id="nested_shadow_content"><div>nested text</div></div>
28
+ `;
29
+ </script>
30
+ </body>
31
+ </html>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.36.0'
4
+ VERSION = '3.37.1'
5
5
  end
@@ -118,7 +118,7 @@ module Capybara
118
118
  alias_method :==, :eql?
119
119
 
120
120
  def hash
121
- @session.hash ^ @handle.hash
121
+ [@session, @handle].hash
122
122
  end
123
123
 
124
124
  def inspect
data/lib/capybara.rb CHANGED
@@ -96,6 +96,7 @@ module Capybara
96
96
  # {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
97
97
  # - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
98
98
  # - **server_port** (Integer) - The port Capybara will run the application server on, if not specified a random port will be used.
99
+ # - **server_host** (String = "127.0.0.1") - The IP address Capybara will bind the application server to. If the test application is to be accessed from an external host, you will want to change this to "0.0.0.0" or to a more specific IP address that your test client can reach.
99
100
  # - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
100
101
  # and {configure raise_server_errors} is `true`.
101
102
  # - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
data/spec/dsl_spec.rb CHANGED
@@ -115,7 +115,7 @@ RSpec.describe Capybara::DSL do
115
115
  it 'should yield the passed block' do
116
116
  called = false
117
117
  Capybara.using_driver(:selenium) { called = true }
118
- expect(called).to eq(true)
118
+ expect(called).to be(true)
119
119
  end
120
120
  end
121
121
 
@@ -220,7 +220,7 @@ RSpec.describe Capybara::DSL do
220
220
  it 'should yield the passed block' do
221
221
  called = false
222
222
  Capybara.using_session(:administrator) { called = true }
223
- expect(called).to eq(true)
223
+ expect(called).to be(true)
224
224
  end
225
225
 
226
226
  it 'should be nestable' do
@@ -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 }
8
+ options = { browser: ENV.fetch('SELENIUM_BROWSER', :firefox).to_sym }
9
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 }
8
+ options = { browser: ENV.fetch('SELENIUM_BROWSER', :firefox).to_sym }
9
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,RSpec/IdenticalEqualityAssertion
11
+ expect(true).to be(true) # rubocop:disable RSpec/ExpectActual,RSpec/IdenticalEqualityAssertion
12
12
  end
13
13
  end
@@ -216,6 +216,12 @@ RSpec.describe Capybara::RackTest::Driver do
216
216
  expect(driver.current_url).to match %r{/landed$}
217
217
  end
218
218
 
219
+ it 'should not include fragments in the referer header' do
220
+ driver.visit('/header_links#an-anchor')
221
+ driver.find_xpath('.//input').first.click
222
+ expect(driver.request.get_header('HTTP_REFERER')).to eq('http://www.example.com/header_links')
223
+ end
224
+
219
225
  it 'is possible to not follow redirects' do
220
226
  driver = described_class.new(TestApp, follow_redirects: false)
221
227