capybara 3.33.0 → 3.35.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +83 -15
  3. data/README.md +0 -2
  4. data/lib/capybara.rb +1 -1
  5. data/lib/capybara/config.rb +4 -6
  6. data/lib/capybara/driver/base.rb +4 -0
  7. data/lib/capybara/helpers.rb +25 -1
  8. data/lib/capybara/minitest.rb +2 -2
  9. data/lib/capybara/minitest/spec.rb +14 -11
  10. data/lib/capybara/node/actions.rb +1 -2
  11. data/lib/capybara/node/base.rb +6 -6
  12. data/lib/capybara/node/element.rb +1 -5
  13. data/lib/capybara/node/finders.rb +7 -6
  14. data/lib/capybara/node/matchers.rb +8 -6
  15. data/lib/capybara/node/simple.rb +5 -1
  16. data/lib/capybara/queries/ancestor_query.rb +1 -1
  17. data/lib/capybara/queries/current_path_query.rb +14 -4
  18. data/lib/capybara/queries/selector_query.rb +32 -17
  19. data/lib/capybara/queries/sibling_query.rb +1 -1
  20. data/lib/capybara/queries/text_query.rb +2 -2
  21. data/lib/capybara/rack_test/browser.rb +7 -3
  22. data/lib/capybara/rack_test/driver.rb +1 -0
  23. data/lib/capybara/rack_test/form.rb +1 -1
  24. data/lib/capybara/rack_test/node.rb +1 -1
  25. data/lib/capybara/registration_container.rb +3 -3
  26. data/lib/capybara/registrations/drivers.rb +18 -12
  27. data/lib/capybara/registrations/patches/puma_ssl.rb +3 -1
  28. data/lib/capybara/registrations/servers.rb +2 -1
  29. data/lib/capybara/result.rb +6 -10
  30. data/lib/capybara/rspec.rb +2 -0
  31. data/lib/capybara/rspec/matcher_proxies.rb +1 -1
  32. data/lib/capybara/rspec/matchers.rb +7 -6
  33. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  34. data/lib/capybara/rspec/matchers/match_style.rb +5 -0
  35. data/lib/capybara/selector.rb +2 -2
  36. data/lib/capybara/selector/builders/css_builder.rb +1 -1
  37. data/lib/capybara/selector/builders/xpath_builder.rb +3 -1
  38. data/lib/capybara/selector/definition.rb +6 -5
  39. data/lib/capybara/selector/definition/button.rb +26 -15
  40. data/lib/capybara/selector/definition/css.rb +1 -1
  41. data/lib/capybara/selector/definition/datalist_input.rb +1 -1
  42. data/lib/capybara/selector/definition/element.rb +2 -1
  43. data/lib/capybara/selector/definition/label.rb +1 -1
  44. data/lib/capybara/selector/definition/select.rb +1 -1
  45. data/lib/capybara/selector/definition/table_row.rb +2 -2
  46. data/lib/capybara/selector/filter_set.rb +2 -2
  47. data/lib/capybara/selector/selector.rb +5 -1
  48. data/lib/capybara/selenium/atoms/src/isDisplayed.js +1 -1
  49. data/lib/capybara/selenium/driver.rb +47 -5
  50. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +3 -3
  51. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +3 -3
  52. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
  53. data/lib/capybara/selenium/extensions/find.rb +4 -4
  54. data/lib/capybara/selenium/extensions/scroll.rb +8 -10
  55. data/lib/capybara/selenium/logger_suppressor.rb +8 -2
  56. data/lib/capybara/selenium/node.rb +6 -3
  57. data/lib/capybara/selenium/nodes/chrome_node.rb +23 -5
  58. data/lib/capybara/selenium/nodes/firefox_node.rb +6 -1
  59. data/lib/capybara/selenium/nodes/safari_node.rb +1 -1
  60. data/lib/capybara/selenium/patches/atoms.rb +4 -4
  61. data/lib/capybara/selenium/patches/logs.rb +4 -4
  62. data/lib/capybara/server/animation_disabler.rb +8 -3
  63. data/lib/capybara/server/middleware.rb +4 -2
  64. data/lib/capybara/session.rb +20 -11
  65. data/lib/capybara/session/matchers.rb +11 -11
  66. data/lib/capybara/spec/public/test.js +6 -1
  67. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
  68. data/lib/capybara/spec/session/check_spec.rb +6 -0
  69. data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
  70. data/lib/capybara/spec/session/current_url_spec.rb +11 -1
  71. data/lib/capybara/spec/session/has_button_spec.rb +35 -0
  72. data/lib/capybara/spec/session/has_css_spec.rb +2 -1
  73. data/lib/capybara/spec/session/has_current_path_spec.rb +13 -0
  74. data/lib/capybara/spec/session/has_text_spec.rb +0 -11
  75. data/lib/capybara/spec/session/html_spec.rb +1 -1
  76. data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
  77. data/lib/capybara/spec/session/node_spec.rb +23 -3
  78. data/lib/capybara/spec/session/refresh_spec.rb +2 -1
  79. data/lib/capybara/spec/session/save_page_spec.rb +4 -4
  80. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
  81. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
  82. data/lib/capybara/spec/session/window/window_spec.rb +1 -1
  83. data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
  84. data/lib/capybara/spec/spec_helper.rb +11 -12
  85. data/lib/capybara/spec/test_app.rb +9 -3
  86. data/lib/capybara/spec/views/form.erb +23 -1
  87. data/lib/capybara/spec/views/with_animation.erb +8 -0
  88. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  89. data/lib/capybara/spec/views/with_js.erb +2 -0
  90. data/lib/capybara/spec/views/with_sortable_js.erb +1 -1
  91. data/lib/capybara/version.rb +1 -1
  92. data/lib/capybara/window.rb +3 -7
  93. data/spec/basic_node_spec.rb +9 -8
  94. data/spec/dsl_spec.rb +1 -1
  95. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  96. data/spec/minitest_spec.rb +2 -1
  97. data/spec/rack_test_spec.rb +15 -5
  98. data/spec/rspec/features_spec.rb +3 -1
  99. data/spec/rspec/scenarios_spec.rb +4 -0
  100. data/spec/rspec/shared_spec_matchers.rb +2 -2
  101. data/spec/rspec_spec.rb +4 -0
  102. data/spec/selector_spec.rb +16 -1
  103. data/spec/selenium_spec_chrome.rb +39 -18
  104. data/spec/selenium_spec_chrome_remote.rb +5 -1
  105. data/spec/selenium_spec_firefox.rb +15 -13
  106. data/spec/server_spec.rb +19 -0
  107. data/spec/shared_selenium_session.rb +74 -1
  108. metadata +47 -13
  109. data/lib/capybara/spec/session/source_spec.rb +0 -0
@@ -18,6 +18,14 @@
18
18
  });
19
19
  </script>
20
20
  <style>
21
+ html {
22
+ scroll-behavior: smooth;
23
+ }
24
+
25
+ body {
26
+ min-height: 2000px;
27
+ }
28
+
21
29
  .transition.away {
22
30
  width: 0%;
23
31
  }
@@ -0,0 +1,24 @@
1
+
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
+ <title>with_jquery_animation</title>
6
+ <style>
7
+ body {
8
+ height: 2000px;
9
+ }
10
+ </style>
11
+ </head>
12
+
13
+ <body id="with_animation">
14
+ <a href="#" id='scroll'>scroll top 500</a>
15
+
16
+ <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
17
+ <script type='text/javascript'>
18
+ $('#scroll').click(function(e){
19
+ e.preventDefault();
20
+ $('html, body').animate({ scrollTop: 500 }, 'slow');
21
+ });
22
+ </script>
23
+ </body>
24
+ </html>
@@ -36,6 +36,7 @@
36
36
  <p><a href="#" id="clickable">Click me</a></p>
37
37
  <p><a href="#" id="slow-click">Slowly</a></p>
38
38
  <p><span id="aria-button" role="button">ARIA button</span></p>
39
+ <p><span role="button">ARIA button2</span></p>
39
40
 
40
41
  <p>
41
42
  <select id="waiter">
@@ -152,6 +153,7 @@
152
153
  <p>This is an HTML5 draggable element.</p>
153
154
  </div>
154
155
 
156
+ <div id="shadow"></div>
155
157
  <script type="text/javascript">
156
158
  // a javascript comment
157
159
  var aVar = 123;
@@ -2,7 +2,7 @@
2
2
  <head>
3
3
  <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
4
  <title>with_sortable_js</title>
5
- <script src="https://sortablejs.github.io/Sortable/Sortable.js" type="text/javascript"></script>
5
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.12.0/dist/sortable.umd.min.js" type="text/javascript"></script>
6
6
  </head>
7
7
 
8
8
  <body id="with_sortable_js">
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.33.0'
4
+ VERSION = '3.35.3'
5
5
  end
@@ -4,7 +4,7 @@ module Capybara
4
4
  ##
5
5
  # The {Window} class represents a browser window.
6
6
  #
7
- # You can get an instance of the class by calling either of:
7
+ # You can get an instance of the class by calling any of:
8
8
  #
9
9
  # * {Capybara::Session#windows}
10
10
  # * {Capybara::Session#current_window}
@@ -82,8 +82,8 @@ module Capybara
82
82
  # Resize window.
83
83
  #
84
84
  # @macro about_current
85
- # @param width [String] the new window width in pixels
86
- # @param height [String] the new window height in pixels
85
+ # @param width [Integer] the new window width in pixels
86
+ # @param height [Integer] the new window height in pixels
87
87
  #
88
88
  def resize_to(width, height)
89
89
  wait_for_stable_size { @driver.resize_window_to(handle, width, height) }
@@ -138,9 +138,5 @@ module Capybara
138
138
  end
139
139
  raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
140
140
  end
141
-
142
- def raise_unless_current(what)
143
- raise Capybara::WindowError, "#{what} not current window is not possible." unless current?
144
- end
145
141
  end
146
142
  end
@@ -3,6 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara do
6
+ include Capybara::RSpecMatchers
6
7
  describe '.string' do
7
8
  let :string do
8
9
  described_class.string <<-STRING
@@ -129,25 +130,25 @@ RSpec.describe Capybara do
129
130
 
130
131
  describe '#has_title?' do
131
132
  it 'returns whether the page has the given title' do
132
- expect(string.has_title?('simple_node')).to be_truthy
133
- expect(string.has_title?('monkey')).to be_falsey
133
+ expect(string.has_title?('simple_node')).to be true
134
+ expect(string.has_title?('monkey')).to be false
134
135
  end
135
136
 
136
137
  it 'allows regexp matches' do
137
- expect(string.has_title?(/s[a-z]+_node/)).to be_truthy
138
- expect(string.has_title?(/monkey/)).to be_falsey
138
+ expect(string.has_title?(/s[a-z]+_node/)).to be true
139
+ expect(string.has_title?(/monkey/)).to be false
139
140
  end
140
141
  end
141
142
 
142
143
  describe '#has_no_title?' do
143
144
  it 'returns whether the page does not have the given title' do
144
- expect(string.has_no_title?('simple_node')).to be_falsey
145
- expect(string.has_no_title?('monkey')).to be_truthy
145
+ expect(string.has_no_title?('simple_node')).to be false
146
+ expect(string.has_no_title?('monkey')).to be true
146
147
  end
147
148
 
148
149
  it 'allows regexp matches' do
149
- expect(string.has_no_title?(/s[a-z]+_node/)).to be_falsey
150
- expect(string.has_no_title?(/monkey/)).to be_truthy
150
+ expect(string.has_no_title?(/s[a-z]+_node/)).to be false
151
+ expect(string.has_no_title?(/monkey/)).to be true
151
152
  end
152
153
  end
153
154
  end
@@ -8,7 +8,7 @@ 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 spatial html_validation
11
+ js modals screenshot frames windows send_keys server hover about_scheme psc download css driver scroll spatial html_validation shadow_dom
12
12
  ] do |example|
13
13
  case example.metadata[:full_description]
14
14
  when /has_css\? should support case insensitive :class and :id options/
@@ -6,7 +6,7 @@ require 'selenium-webdriver'
6
6
  RSpec.describe Capybara::Selenium::Driver do
7
7
  it 'should exit with a zero exit status' do
8
8
  options = { browser: (ENV['SELENIUM_BROWSER'] || :firefox).to_sym }
9
- browser = described_class.new(TestApp, options).browser
9
+ browser = described_class.new(TestApp, **options).browser
10
10
  expect(browser).to be_truthy
11
11
  expect(true).to eq(true) # rubocop:disable RSpec/ExpectActual
12
12
  end
@@ -30,6 +30,7 @@ class MinitestTest < Minitest::Test
30
30
 
31
31
  def test_assert_current_path
32
32
  assert_current_path('/form')
33
+ assert_current_path('/form') { |url| url.query.nil? }
33
34
  assert_no_current_path('/not_form')
34
35
  refute_current_path('/not_form')
35
36
  end
@@ -158,6 +159,6 @@ RSpec.describe 'capybara/minitest' do
158
159
  reporter.start
159
160
  MinitestTest.run reporter, {}
160
161
  reporter.report
161
- expect(output.string).to include('22 runs, 52 assertions, 0 failures, 0 errors, 1 skips')
162
+ expect(output.string).to include('22 runs, 53 assertions, 0 failures, 0 errors, 1 skips')
162
163
  end
163
164
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  require 'spec_helper'
4
4
  nokogumbo_required = begin
5
- require 'nokogumbo'
6
- true
7
- rescue LoadError
8
- false
9
- end
5
+ require 'nokogumbo'
6
+ true
7
+ rescue LoadError
8
+ false
9
+ end
10
10
 
11
11
  module TestSessions
12
12
  RackTest = Capybara::Session.new(:rack_test, TestApp)
@@ -27,6 +27,7 @@ skipped_tests = %i[
27
27
  scroll
28
28
  spatial
29
29
  html_validation
30
+ shadow_dom
30
31
  ]
31
32
  Capybara::SpecHelper.run_specs TestSessions::RackTest, 'RackTest', capybara_skip: skipped_tests do |example|
32
33
  case example.metadata[:full_description]
@@ -38,6 +39,7 @@ Capybara::SpecHelper.run_specs TestSessions::RackTest, 'RackTest', capybara_skip
38
39
  end
39
40
 
40
41
  RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
42
+ include Capybara::RSpecMatchers
41
43
  context 'with rack test driver' do
42
44
  let(:session) { TestSessions::RackTest }
43
45
 
@@ -143,6 +145,14 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
143
145
  end
144
146
  end
145
147
 
148
+ describe '#send_keys' do
149
+ it 'raises an UnsupportedMethodError' do
150
+ session.visit('/form')
151
+
152
+ expect { session.send_keys(:tab) }.to raise_error(Capybara::NotSupportedByDriverError)
153
+ end
154
+ end
155
+
146
156
  describe '#text' do
147
157
  it 'should return original text content for textareas' do
148
158
  session.visit('/with_html')
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable RSpec/MultipleDescribes
4
+
3
5
  require 'spec_helper'
4
6
  require 'capybara/rspec'
5
7
 
@@ -96,4 +98,4 @@ ffeature 'if ffeature aliases focused tag then' do # rubocop:disable RSpec/Focus
96
98
  expect(example.metadata[:focus]).to eq true
97
99
  end
98
100
  end
99
- # rubocop:enable RSpec/RepeatedExample
101
+ # rubocop:enable RSpec/RepeatedExample, RSpec/MultipleDescribes
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable RSpec/MultipleDescribes
4
+
3
5
  require 'spec_helper'
4
6
  require 'capybara/rspec'
5
7
 
@@ -17,3 +19,5 @@ feature 'if xscenario aliases to pending then' do
17
19
  xscenario "this test should be 'temporarily disabled with xscenario'" do
18
20
  end
19
21
  end
22
+
23
+ # rubocop:enable RSpec/MultipleDescribes
@@ -840,10 +840,10 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
840
840
  end
841
841
 
842
842
  it 'gives proper description when :visible option passed' do
843
- expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
843
+ expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"')
844
844
  expect(have_table('Lovely table', visible: :hidden).description).to eq('have non-visible table "Lovely table"')
845
845
  expect(have_table('Lovely table', visible: :all).description).to eq('have table "Lovely table"')
846
- expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
846
+ expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"')
847
847
  end
848
848
 
849
849
  it 'passes if there is such a table' do
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable RSpec/MultipleDescribes
4
+
3
5
  require 'spec_helper'
4
6
 
5
7
  RSpec.describe 'capybara/rspec' do
@@ -143,3 +145,5 @@ feature 'Feature DSL' do
143
145
  expect(page.body).to include('Another World')
144
146
  end
145
147
  end
148
+
149
+ # rubocop:enable RSpec/MultipleDescribes
@@ -3,6 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara do
6
+ include Capybara::RSpecMatchers
6
7
  describe 'Selectors' do
7
8
  let :string do
8
9
  described_class.string <<-STRING
@@ -326,9 +327,23 @@ RSpec.describe Capybara do
326
327
  expect(string.find(:custom_xpath_selector, './/div', class: /dOm WoR/i)[:id]).to eq 'random_words'
327
328
  end
328
329
 
329
- it 'accepts Regexp for CSS base selectors' do
330
+ it 'accepts Regexp for CSS based selectors' do
330
331
  expect(string.find(:custom_css_selector, 'div', class: /random/)[:id]).to eq 'random_words'
331
332
  end
333
+
334
+ it 'accepts Regexp for individual class names for XPath based selectors' do
335
+ expect(string.find(:custom_xpath_selector, './/div', class: [/random/, 'some'])[:id]).to eq 'random_words'
336
+ expect(string.find(:custom_xpath_selector, './/div', class: [/om/, /wor/])[:id]).to eq 'random_words'
337
+ expect { string.find(:custom_xpath_selector, './/div', class: [/not/, /wor/]) }.to raise_error(Capybara::ElementNotFound)
338
+ expect { string.find(:custom_xpath_selector, './/div', class: [/dom wor/]) }.to raise_error(Capybara::ElementNotFound)
339
+ end
340
+
341
+ it 'accepts Regexp for individual class names for CSS based selectors' do
342
+ expect(string.find(:custom_css_selector, 'div', class: [/random/])[:id]).to eq 'random_words'
343
+ expect(string.find(:custom_css_selector, 'div', class: [/om/, /wor/, 'some'])[:id]).to eq 'random_words'
344
+ expect { string.find(:custom_css_selector, 'div', class: [/not/, /wor/]) }.to raise_error(Capybara::ElementNotFound)
345
+ expect { string.find(:custom_css_selector, 'div', class: [/dom wor/]) }.to raise_error(Capybara::ElementNotFound)
346
+ end
332
347
  end
333
348
 
334
349
  context 'with :style option' do
@@ -19,39 +19,56 @@ browser_options.add_preference('download.default_directory', Capybara.save_path)
19
19
  browser_options.add_preference(:download, default_directory: Capybara.save_path)
20
20
 
21
21
  Capybara.register_driver :selenium_chrome do |app|
22
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options, timeout: 30).tap do |driver|
22
+ version = Capybara::Selenium::Driver.load_selenium
23
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
24
+ driver_options = { browser: :chrome, timeout: 30 }.tap do |opts|
25
+ opts[options_key] = browser_options
26
+ end
27
+
28
+ Capybara::Selenium::Driver.new(app, **driver_options).tap do |driver|
23
29
  # Set download dir for Chrome < 77
24
30
  driver.browser.download_path = Capybara.save_path
25
31
  end
26
32
  end
27
33
 
28
34
  Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
29
- chrome_options = {
30
- browser: :chrome,
31
- options: browser_options
32
- }
33
- Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
35
+ version = Capybara::Selenium::Driver.load_selenium
36
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
37
+ chrome_options = { browser: :chrome, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
38
+ opts[options_key] = browser_options
39
+ end
40
+
41
+ Capybara::Selenium::Driver.new(app, **chrome_options)
34
42
  end
35
43
 
36
44
  Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
37
- chrome_options = {
38
- browser: :chrome,
39
- options: browser_options
40
- }
41
- Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_session_storage: false))
45
+ version = Capybara::Selenium::Driver.load_selenium
46
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
47
+ chrome_options = { browser: :chrome, clear_session_storage: false }.tap do |opts|
48
+ opts[options_key] = browser_options
49
+ end
50
+
51
+ Capybara::Selenium::Driver.new(app, **chrome_options)
42
52
  end
43
53
 
44
54
  Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
45
- chrome_options = {
46
- browser: :chrome,
47
- options: browser_options
48
- }
49
- Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false))
55
+ version = Capybara::Selenium::Driver.load_selenium
56
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
57
+ chrome_options = { browser: :chrome, clear_local_storage: false }.tap do |opts|
58
+ opts[options_key] = browser_options
59
+ end
60
+ Capybara::Selenium::Driver.new(app, **chrome_options)
50
61
  end
51
62
 
52
63
  Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
64
+ version = Capybara::Selenium::Driver.load_selenium
65
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
53
66
  subclass = Class.new(Capybara::Selenium::Driver)
54
- subclass.new(app, browser: :chrome, options: browser_options, timeout: 30)
67
+ chrome_options = { browser: :chrome, timeout: 30 }.tap do |opts|
68
+ opts[options_key] = browser_options
69
+ end
70
+
71
+ subclass.new(app, **chrome_options)
55
72
  end
56
73
 
57
74
  module TestSessions
@@ -171,7 +188,7 @@ RSpec.describe 'Capybara::Session with chrome' do
171
188
  before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
172
189
 
173
190
  it 'does not error getting log types' do
174
- skip if Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0]) < Gem::Version.new('75.0.3770.90')
191
+ skip if Gem::Requirement.new('< 75.0.3770.90').satisfied_by? chromedriver_version
175
192
  expect do
176
193
  session.driver.browser.manage.logs.available_types
177
194
  end.not_to raise_error
@@ -183,4 +200,8 @@ RSpec.describe 'Capybara::Session with chrome' do
183
200
  end.not_to raise_error
184
201
  end
185
202
  end
203
+
204
+ def chromedriver_version
205
+ Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
206
+ end
186
207
  end
@@ -81,7 +81,7 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
81
81
  before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
82
82
 
83
83
  it 'does not error when getting log types' do
84
- skip if Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0]) < Gem::Version.new('75.0.3770.90')
84
+ skip unless Gem::Requirement.new('>= 75.0.3770.90').satisfied_by? chromedriver_version
85
85
  expect do
86
86
  session.driver.browser.manage.logs.available_types
87
87
  end.not_to raise_error
@@ -93,4 +93,8 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
93
93
  end.not_to raise_error
94
94
  end
95
95
  end
96
+
97
+ def chromedriver_version
98
+ Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
99
+ end
96
100
  end
@@ -14,28 +14,30 @@ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof
14
14
  profile['browser.download.dir'] = Capybara.save_path
15
15
  profile['browser.download.folderList'] = 2
16
16
  profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
17
+ profile['browser.startup.homepage'] = 'about:blank' # workaround bug in Selenium 4 alpha4-7
17
18
  end
18
19
 
19
20
  Capybara.register_driver :selenium_firefox do |app|
20
21
  # ::Selenium::WebDriver.logger.level = "debug"
21
- Capybara::Selenium::Driver.new(
22
- app,
23
- browser: :firefox,
24
- options: browser_options,
25
- timeout: 31
22
+ version = Capybara::Selenium::Driver.load_selenium
23
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
24
+ driver_options = { browser: :firefox, timeout: 31 }.tap do |opts|
25
+ opts[options_key] = browser_options
26
26
  # Get a trace level log from geckodriver
27
27
  # :driver_opts => { args: ['-vv'] }
28
- )
28
+ end
29
+
30
+ Capybara::Selenium::Driver.new(app, **driver_options)
29
31
  end
30
32
 
31
33
  Capybara.register_driver :selenium_firefox_not_clear_storage do |app|
32
- Capybara::Selenium::Driver.new(
33
- app,
34
- browser: :firefox,
35
- clear_local_storage: false,
36
- clear_session_storage: false,
37
- options: browser_options
38
- )
34
+ version = Capybara::Selenium::Driver.load_selenium
35
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
36
+ driver_options = { browser: :firefox, clear_local_storage: false, clear_session_storage: false }.tap do |opts|
37
+ opts[options_key] = browser_options
38
+ end
39
+
40
+ Capybara::Selenium::Driver.new(app, **driver_options)
39
41
  end
40
42
 
41
43
  module TestSessions