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
data/spec/result_spec.rb CHANGED
@@ -86,25 +86,23 @@ RSpec.describe Capybara::Result do
86
86
  expect(result[2..].map(&:text)).to eq %w[Gamma Delta]
87
87
  end
88
88
 
89
- eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.6
90
- it 'supports inclusive positive beginless ranges' do
91
- expect(result[..2].map(&:text)).to eq %w[Alpha Beta Gamma]
92
- end
89
+ it 'supports inclusive positive beginless ranges' do
90
+ expect(result[..2].map(&:text)).to eq %w[Alpha Beta Gamma]
91
+ end
93
92
 
94
- it 'supports inclusive negative beginless ranges' do
95
- expect(result[..-2].map(&:text)).to eq %w[Alpha Beta Gamma]
96
- expect(result[..-1].map(&:text)).to eq %w[Alpha Beta Gamma Delta]
97
- end
93
+ it 'supports inclusive negative beginless ranges' do
94
+ expect(result[..-2].map(&:text)).to eq %w[Alpha Beta Gamma]
95
+ expect(result[..-1].map(&:text)).to eq %w[Alpha Beta Gamma Delta]
96
+ end
98
97
 
99
- it 'supports exclusive positive beginless ranges' do
100
- expect(result[...2].map(&:text)).to eq %w[Alpha Beta]
101
- end
98
+ it 'supports exclusive positive beginless ranges' do
99
+ expect(result[...2].map(&:text)).to eq %w[Alpha Beta]
100
+ end
102
101
 
103
- it 'supports exclusive negative beginless ranges' do
104
- expect(result[...-2].map(&:text)).to eq %w[Alpha Beta]
105
- expect(result[...-1].map(&:text)).to eq %w[Alpha Beta Gamma]
106
- end
107
- TEST
102
+ it 'supports exclusive negative beginless ranges' do
103
+ expect(result[...-2].map(&:text)).to eq %w[Alpha Beta]
104
+ expect(result[...-1].map(&:text)).to eq %w[Alpha Beta Gamma]
105
+ end
108
106
 
109
107
  it 'works with filter blocks' do
110
108
  result = string.all('//li') { |node| node.text == 'Alpha' }
@@ -115,52 +113,52 @@ RSpec.describe Capybara::Result do
115
113
  it 'should evaluate filters lazily for idx' do
116
114
  skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
117
115
  # Not processed until accessed
118
- expect(result.instance_variable_get('@result_cache').size).to be 0
116
+ expect(result.instance_variable_get(:@result_cache).size).to be 0
119
117
 
120
118
  # Only one retrieved when needed
121
119
  result.first
122
- expect(result.instance_variable_get('@result_cache').size).to be 1
120
+ expect(result.instance_variable_get(:@result_cache).size).to be 1
123
121
 
124
122
  # works for indexed access
125
123
  result[0]
126
- expect(result.instance_variable_get('@result_cache').size).to be 1
124
+ expect(result.instance_variable_get(:@result_cache).size).to be 1
127
125
 
128
126
  result[2]
129
- expect(result.instance_variable_get('@result_cache').size).to be 3
127
+ expect(result.instance_variable_get(:@result_cache).size).to be 3
130
128
 
131
129
  # All cached when converted to array
132
130
  result.to_a
133
- expect(result.instance_variable_get('@result_cache').size).to eq 4
131
+ expect(result.instance_variable_get(:@result_cache).size).to eq 4
134
132
  end
135
133
 
136
134
  it 'should evaluate filters lazily for range' do
137
135
  skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
138
136
  result[0..1]
139
- expect(result.instance_variable_get('@result_cache').size).to be 2
137
+ expect(result.instance_variable_get(:@result_cache).size).to be 2
140
138
 
141
139
  expect(result[0..7].size).to eq 4
142
- expect(result.instance_variable_get('@result_cache').size).to be 4
140
+ expect(result.instance_variable_get(:@result_cache).size).to be 4
143
141
  end
144
142
 
145
143
  it 'should evaluate filters lazily for idx and length' do
146
144
  skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
147
145
  result[1, 2]
148
- expect(result.instance_variable_get('@result_cache').size).to be 3
146
+ expect(result.instance_variable_get(:@result_cache).size).to be 3
149
147
 
150
148
  expect(result[2, 5].size).to eq 2
151
- expect(result.instance_variable_get('@result_cache').size).to be 4
149
+ expect(result.instance_variable_get(:@result_cache).size).to be 4
152
150
  end
153
151
 
154
152
  it 'should only need to evaluate one result for any?' do
155
153
  skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
156
154
  result.any?
157
- expect(result.instance_variable_get('@result_cache').size).to be 1
155
+ expect(result.instance_variable_get(:@result_cache).size).to be 1
158
156
  end
159
157
 
160
158
  it 'should evaluate all elements when #to_a called' do
161
159
  # All cached when converted to array
162
160
  result.to_a
163
- expect(result.instance_variable_get('@result_cache').size).to eq 4
161
+ expect(result.instance_variable_get(:@result_cache).size).to eq 4
164
162
  end
165
163
 
166
164
  describe '#each' do
@@ -169,7 +167,7 @@ RSpec.describe Capybara::Result do
169
167
  results = []
170
168
  result.each do |el|
171
169
  results << el
172
- expect(result.instance_variable_get('@result_cache').size).to eq results.size
170
+ expect(result.instance_variable_get(:@result_cache).size).to eq results.size
173
171
  end
174
172
 
175
173
  expect(results.size).to eq 4
@@ -183,7 +181,7 @@ RSpec.describe Capybara::Result do
183
181
  it 'lazily evaluates' do
184
182
  skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
185
183
  result.each.with_index do |_el, idx|
186
- expect(result.instance_variable_get('@result_cache').size).to eq(idx + 1) # 0 indexing
184
+ expect(result.instance_variable_get(:@result_cache).size).to eq(idx + 1) # 0 indexing
187
185
  end
188
186
  end
189
187
  end
@@ -91,11 +91,11 @@ end
91
91
 
92
92
  ffeature 'if ffeature aliases focused tag then' do # rubocop:disable RSpec/Focus
93
93
  scenario 'scenario inside this feature has metatag focus tag' do |example|
94
- expect(example.metadata[:focus]).to eq true
94
+ expect(example.metadata[:focus]).to be true
95
95
  end
96
96
 
97
97
  scenario 'other scenarios also has metatag focus tag' do |example|
98
- expect(example.metadata[:focus]).to eq true
98
+ expect(example.metadata[:focus]).to be true
99
99
  end
100
100
  end
101
101
  # rubocop:enable RSpec/RepeatedExample, RSpec/MultipleDescribes
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  feature 'if fscenario aliases focused tag then' do
13
13
  fscenario 'scenario should have focused meta tag' do |example| # rubocop:disable RSpec/Focus
14
- expect(example.metadata[:focus]).to eq true
14
+ expect(example.metadata[:focus]).to be true
15
15
  end
16
16
  end
17
17
 
@@ -15,9 +15,9 @@ Capybara.register_driver :sauce_chrome do |app|
15
15
  browser_name: 'chrome',
16
16
  version: '65.0',
17
17
  name: 'Capybara test',
18
- build: ENV['TRAVIS_REPO_SLUG'] || "Ruby-RSpec-Selenium: Local-#{Time.now.to_i}",
19
- username: ENV['SAUCE_USERNAME'],
20
- access_key: ENV['SAUCE_ACCESS_KEY']
18
+ build: ENV.fetch('TRAVIS_REPO_SLUG', "Ruby-RSpec-Selenium: Local-#{Time.now.to_i}"),
19
+ username: ENV.fetch('SAUCE_USERNAME', nil),
20
+ access_key: ENV.fetch('SAUCE_ACCESS_KEY', nil)
21
21
  }
22
22
 
23
23
  options.delete(:browser_name)
@@ -159,7 +159,7 @@ RSpec.describe Capybara do
159
159
  end
160
160
 
161
161
  it 'returns nil if no match' do
162
- expect(Capybara::Selector.for('nothing')).to be nil
162
+ expect(Capybara::Selector.for('nothing')).to be_nil
163
163
  end
164
164
  end
165
165
 
@@ -471,7 +471,7 @@ RSpec.describe Capybara do
471
471
  end
472
472
 
473
473
  it 'includes wildcarded keys in description' do
474
- expect { string.find(:element, 'input', not_there: 'bad', presence: true, absence: false, count: 1) }
474
+ expect { string.all(:element, 'input', not_there: 'bad', presence: true, absence: false, count: 1) }
475
475
  .to(raise_error do |e|
476
476
  expect(e).to be_a(Capybara::ElementNotFound)
477
477
  expect(e.message).to include 'not_there => bad'
@@ -8,7 +8,7 @@ require 'rspec/shared_spec_matchers'
8
8
 
9
9
  CHROME_DRIVER = :selenium_chrome
10
10
 
11
- Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV['CI'] && ENV['CHROME_BETA']
11
+ Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV.fetch('CI', nil) && ENV.fetch('CHROME_BETA', nil)
12
12
 
13
13
  browser_options = ::Selenium::WebDriver::Chrome::Options.new
14
14
  browser_options.headless! if ENV['HEADLESS']
@@ -72,6 +72,10 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
72
72
  when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
73
73
  'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
74
74
  skip 'No clue what Firefox is doing here - works fine on MacOS locally'
75
+ when 'Capybara::Session selenium node #shadow_root should get the shadow root',
76
+ 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
77
+ 'Capybara::Session selenium node #shadow_root should find nested shadow roots'
78
+ pending "Firefox doesn't yet have W3C shadow root support"
75
79
  end
76
80
  end
77
81
 
@@ -103,7 +107,7 @@ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/Multi
103
107
  end
104
108
 
105
109
  it 'should fill in a datetime input with a String' do
106
- pending "Need to figure out what string format this will actually accept"
110
+ pending 'Need to figure out what string format this will actually accept'
107
111
  session.fill_in('form_datetime', with: datetime.iso8601)
108
112
  session.click_button('awesome')
109
113
  expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
@@ -80,10 +80,14 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
80
80
  when 'Capybara::Session selenium_safari node #double_click should allow modifiers'
81
81
  pending "safaridriver doesn't generate double click with key modifiers"
82
82
  when /when w3c_click_offset is true should offset/
83
- pending "w3c_click_offset is not currently supported with safaridriver"
83
+ pending 'w3c_click_offset is not currently supported with safaridriver'
84
84
  when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
85
85
  'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
86
86
  skip 'safaridriver loses the ability to find elements in the document after `go_back`'
87
+ when 'Capybara::Session selenium node #shadow_root should get the shadow root',
88
+ 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
89
+ 'Capybara::Session selenium node #shadow_root should find nested shadow roots'
90
+ pending "Safari doesn't yet have W3C shadow root support"
87
91
  end
88
92
  end
89
93
 
data/spec/server_spec.rb CHANGED
@@ -20,7 +20,7 @@ RSpec.describe Capybara::Server do
20
20
 
21
21
  it 'should bind to the specified host' do
22
22
  # TODO: travis with jruby in container mode has an issue with this test
23
- skip 'This platform has an issue with this test' if (ENV['TRAVIS'] && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
23
+ skip 'This platform has an issue with this test' if (ENV.fetch('TRAVIS', nil) && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
24
24
 
25
25
  begin
26
26
  app = proc { |_env| [200, {}, ['Hello Server!']] }
@@ -78,7 +78,7 @@ RSpec.describe Capybara::Server do
78
78
  # Use a port to force a EADDRINUSE error to be generated
79
79
  server = TCPServer.new('0.0.0.0', 0)
80
80
  server_port = server.addr[1]
81
- d_server = instance_double('TCPServer', addr: [nil, server_port, nil, nil], close: nil)
81
+ d_server = instance_double(TCPServer, addr: [nil, server_port, nil, nil], close: nil)
82
82
  call_count = 0
83
83
  allow(TCPServer).to receive(:new).and_wrap_original do |m, *args|
84
84
  call_count.zero? ? d_server : m.call(*args)
@@ -184,7 +184,7 @@ RSpec.describe Capybara::Server do
184
184
  start_request(server2, 3.0)
185
185
  server1.wait_for_pending_requests
186
186
  end.to change { done }.from(0).to(2)
187
- expect(server2.send(:pending_requests?)).to eq(false)
187
+ expect(server2.send(:pending_requests?)).to be(false)
188
188
  end
189
189
  end
190
190
 
@@ -229,7 +229,7 @@ RSpec.describe Capybara::Server do
229
229
  start_request(server2, 3.0)
230
230
  server1.wait_for_pending_requests
231
231
  end.to change { done }.from(0).to(1)
232
- expect(server2.send(:pending_requests?)).to eq(true)
232
+ expect(server2.send(:pending_requests?)).to be(true)
233
233
  expect do
234
234
  server2.wait_for_pending_requests
235
235
  end.to change { done }.from(1).to(2)
@@ -274,7 +274,7 @@ RSpec.describe Capybara::Server do
274
274
  app = -> { [200, {}, ['Hello, world']] }
275
275
  server = described_class.new(app)
276
276
  allow(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
277
- expect(server.responsive?).to eq false
277
+ expect(server.responsive?).to be false
278
278
  end
279
279
 
280
280
  [EOFError, Net::ReadTimeout].each do |err|
@@ -23,7 +23,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
23
23
  it 'freshly reset session should not be touched' do
24
24
  session.instance_variable_set(:@touched, true)
25
25
  session.reset!
26
- expect(session.instance_variable_get(:@touched)).to eq false
26
+ expect(session.instance_variable_get(:@touched)).to be false
27
27
  end
28
28
  end
29
29
 
@@ -280,6 +280,13 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
280
280
  expect(element).to eq session.find(:id, 'form_title')
281
281
  end
282
282
 
283
+ it 'returns a shadow root' do
284
+ session.visit('/with_shadow')
285
+ shadow = session.find(:css, '#shadow_host')
286
+ element = session.evaluate_script('arguments[0].shadowRoot', shadow)
287
+ expect(element).to be_instance_of(Capybara::Node::Element)
288
+ end
289
+
283
290
  it 'can return arrays of nested elements' do
284
291
  session.visit('/form')
285
292
  elements = session.evaluate_script('document.querySelectorAll("#form_city option")')
@@ -336,7 +343,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
336
343
  it 'can attach a directory' do
337
344
  pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
338
345
  pending "Selenium remote doesn't support transferring a directory" if remote?(session)
339
- pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && ENV['HEADLESS']
346
+ pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && ENV.fetch('HEADLESS', nil)
340
347
  pending "IE doesn't support uploading a directory" if ie?(session)
341
348
  pending 'Chrome/chromedriver 73 breaks this' if chrome?(session) && chrome_gte?(73, session) && chrome_lt?(75, session)
342
349
  pending "Safari doesn't support uploading a directory" if safari?(session)
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rspec/expectations'
4
- require 'webdrivers' if ENV['CI'] || ENV['WEBDRIVERS']
4
+ require 'webdrivers' if ENV.fetch('CI', nil) || ENV.fetch('WEBDRIVERS', nil)
5
5
  require 'selenium_statistics'
6
6
  if ENV['TRAVIS']
7
7
  require 'coveralls'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.36.0
4
+ version: 3.37.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Walpole
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-10-25 00:00:00.000000000 Z
12
+ date: 2022-05-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -734,6 +734,7 @@ files:
734
734
  - lib/capybara/spec/views/with_namespace.erb
735
735
  - lib/capybara/spec/views/with_scope.erb
736
736
  - lib/capybara/spec/views/with_scope_other.erb
737
+ - lib/capybara/spec/views/with_shadow.erb
737
738
  - lib/capybara/spec/views/with_simple_html.erb
738
739
  - lib/capybara/spec/views/with_slow_unload.erb
739
740
  - lib/capybara/spec/views/with_sortable_js.erb
@@ -786,6 +787,7 @@ licenses:
786
787
  metadata:
787
788
  changelog_uri: https://github.com/teamcapybara/capybara/blob/master/History.md
788
789
  source_code_uri: https://github.com/teamcapybara/capybara
790
+ rubygems_mfa_required: 'true'
789
791
  post_install_message:
790
792
  rdoc_options: []
791
793
  require_paths:
@@ -794,14 +796,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
794
796
  requirements:
795
797
  - - ">="
796
798
  - !ruby/object:Gem::Version
797
- version: 2.6.0
799
+ version: 2.7.0
798
800
  required_rubygems_version: !ruby/object:Gem::Requirement
799
801
  requirements:
800
802
  - - ">="
801
803
  - !ruby/object:Gem::Version
802
804
  version: '0'
803
805
  requirements: []
804
- rubygems_version: 3.2.29
806
+ rubygems_version: 3.3.7
805
807
  signing_key:
806
808
  specification_version: 4
807
809
  summary: Capybara aims to simplify the process of integration testing Rack applications,