capybara 3.35.2 → 3.39.2

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 +133 -7
  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 +2 -2
  54. data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
  55. data/lib/capybara/selenium/logger_suppressor.rb +6 -2
  56. data/lib/capybara/selenium/node.rb +82 -33
  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 +16 -15
  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 +35 -2
  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
@@ -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)
@@ -27,7 +27,7 @@ Capybara.register_driver :sauce_chrome do |app|
27
27
 
28
28
  Capybara::Selenium::Driver.new(app,
29
29
  browser: :remote, url: url,
30
- desired_capabilities: capabilities,
30
+ capabilities: capabilities,
31
31
  options: Selenium::WebDriver::Chrome::Options.new(args: ['']))
32
32
  end
33
33
 
@@ -111,13 +111,13 @@ RSpec.describe Capybara do
111
111
  end
112
112
 
113
113
  describe 'adding a selector' do
114
- it 'can set default visiblity' do
114
+ it 'can set default visibility' do
115
115
  described_class.add_selector :hidden_field do
116
116
  visible :hidden
117
117
  css { |_sel| 'input[type="hidden"]' }
118
118
  end
119
119
 
120
- expect(string).to have_no_css('input[type="hidden"]')
120
+ expect(string).to have_no_css('input[type="hidden"]') # rubocop:disable RSpec/Capybara/SpecificMatcher
121
121
  expect(string).to have_selector(:hidden_field)
122
122
  end
123
123
  end
@@ -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,11 +8,11 @@ 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
+
13
+ browser_options = Selenium::WebDriver::Chrome::Options.new
14
+ browser_options.add_argument('--headless') if ENV['HEADLESS']
12
15
 
13
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
14
- browser_options.headless! if ENV['HEADLESS']
15
- browser_options.add_option(:w3c, ENV['W3C'] != 'false')
16
16
  # Chromedriver 77 requires setting this for headless mode on linux
17
17
  # Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
18
18
  browser_options.add_preference('download.default_directory', Capybara.save_path)
@@ -85,10 +85,11 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
85
85
  skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
86
86
  when /Capybara::Session selenium_chrome Capybara::Window#maximize/
87
87
  pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
88
- when /Capybara::Window#fullscreen should be able to fullscreen the window/
89
- skip 'Chromedriver hangs on attempts to fullscreen in headless mode' if ENV['HEADLESS']
90
- when /node #right_click delay should delay the mouse up/
91
- skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
88
+ when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
89
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
90
+ when /Capybara::Session selenium_chrome node #shadow_root/
91
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
92
+ skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
92
93
  end
93
94
  end
94
95
 
@@ -185,23 +186,22 @@ RSpec.describe 'Capybara::Session with chrome' do
185
186
  end
186
187
 
187
188
  describe 'log access' do
188
- before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
189
+ let(:logs) do
190
+ session.driver.browser.then do |chrome_driver|
191
+ chrome_driver.respond_to?(:logs) ? chrome_driver : chrome_driver.manage
192
+ end.logs
193
+ end
189
194
 
190
195
  it 'does not error getting log types' do
191
- skip if Gem::Requirement.new('< 75.0.3770.90').satisfied_by? chromedriver_version
192
196
  expect do
193
- session.driver.browser.manage.logs.available_types
197
+ logs.available_types
194
198
  end.not_to raise_error
195
199
  end
196
200
 
197
201
  it 'does not error when getting logs' do
198
202
  expect do
199
- session.driver.browser.manage.logs.get(:browser)
203
+ logs.get(:browser)
200
204
  end.not_to raise_error
201
205
  end
202
206
  end
203
-
204
- def chromedriver_version
205
- Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
206
- end
207
207
  end
@@ -21,8 +21,8 @@ def ensure_selenium_running!
21
21
  rescue StandardError
22
22
  if timer.expired?
23
23
  raise 'Selenium is not running. ' \
24
- "You can run a selenium server easily with: \n" \
25
- ' $ docker-compose up -d selenium_chrome'
24
+ "You can run a selenium server easily with: \n " \
25
+ '$ docker-compose up -d selenium_chrome'
26
26
  else
27
27
  puts 'Waiting for Selenium docker instance...'
28
28
  sleep 1
@@ -32,18 +32,17 @@ def ensure_selenium_running!
32
32
  end
33
33
 
34
34
  def selenium_gte?(version)
35
- defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION.to_f >= version)
35
+ defined?(Selenium::WebDriver::VERSION) && (Gem::Version.new(Selenium::WebDriver::VERSION) >= Gem::Version.new(version))
36
36
  end
37
37
 
38
38
  Capybara.register_driver :selenium_chrome_remote do |app|
39
39
  ensure_selenium_running!
40
40
 
41
41
  url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
42
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
42
+ browser_options = Selenium::WebDriver::Chrome::Options.new
43
43
 
44
44
  Capybara::Selenium::Driver.new app,
45
45
  browser: :remote,
46
- desired_capabilities: :chrome,
47
46
  options: browser_options,
48
47
  url: url
49
48
  end
@@ -62,8 +61,11 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s,
62
61
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded',
63
62
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty'
64
63
  pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14)
65
- when /node #right_click delay should delay the mouse up/
66
- skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
64
+ when /Capybara::Session selenium_chrome_remote node #shadow_root should get visible text/
65
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
66
+ when /Capybara::Session selenium_chrome_remote node #shadow_root/
67
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
68
+ skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
67
69
  end
68
70
  end
69
71
 
@@ -78,23 +80,22 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
78
80
  end
79
81
 
80
82
  describe 'log access' do
81
- before { skip 'Only makes sense in W3C mode' if ENV['W3C'] == 'false' }
83
+ let(:logs) do
84
+ session.driver.browser.then do |chrome_driver|
85
+ chrome_driver.respond_to?(:logs) ? chrome_driver : chrome_driver.manage
86
+ end.logs
87
+ end
82
88
 
83
89
  it 'does not error when getting log types' do
84
- skip unless Gem::Requirement.new('>= 75.0.3770.90').satisfied_by? chromedriver_version
85
90
  expect do
86
- session.driver.browser.manage.logs.available_types
91
+ logs.available_types
87
92
  end.not_to raise_error
88
93
  end
89
94
 
90
95
  it 'does not error when getting logs' do
91
96
  expect do
92
- session.driver.browser.manage.logs.get(:browser)
97
+ logs.get(:browser)
93
98
  end.not_to raise_error
94
99
  end
95
100
  end
96
-
97
- def chromedriver_version
98
- Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
99
- end
100
101
  end
@@ -10,15 +10,17 @@ require 'rspec/shared_spec_matchers'
10
10
  # Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
11
11
  # end
12
12
 
13
- if ::Selenium::WebDriver::Platform.mac?
14
- Selenium::WebDriver::EdgeChrome.path = '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev'
13
+ if Selenium::WebDriver::Platform.mac?
14
+ Selenium::WebDriver::Edge.path = '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'
15
15
  end
16
16
 
17
17
  Capybara.register_driver :selenium_edge do |app|
18
18
  # ::Selenium::WebDriver.logger.level = "debug"
19
19
  # If we don't create an options object the path set above won't be used
20
- browser_options = ::Selenium::WebDriver::EdgeChrome::Options.new
21
- Capybara::Selenium::Driver.new(app, browser: :edge_chrome, options: browser_options).tap do |driver|
20
+ browser_options = Selenium::WebDriver::Edge::Options.new
21
+ browser_options.add_argument('--headless') if ENV['HEADLESS']
22
+
23
+ Capybara::Selenium::Driver.new(app, browser: :edge, options: browser_options).tap do |driver|
22
24
  driver.browser
23
25
  driver.download_path = Capybara.save_path
24
26
  end
@@ -30,12 +32,16 @@ end
30
32
 
31
33
  skipped_tests = %i[response_headers status_code trigger]
32
34
 
33
- Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::EdgeChrome) if ENV['CI']
35
+ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Edge) if ENV['CI']
34
36
 
35
37
  Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
36
38
  case example.metadata[:full_description]
37
39
  when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
38
- pending "EdgeChrome doesn't allow clicking on file inputs"
40
+ pending "Edge doesn't allow clicking on file inputs"
41
+ when /Capybara::Session selenium node #shadow_root should get visible text/
42
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
43
+ when /Capybara::Session selenium Capybara::Window#maximize/
44
+ pending "Edge headless doesn't support maximize" if ENV['HEADLESS']
39
45
  end
40
46
  end
41
47
 
@@ -6,7 +6,7 @@ require 'shared_selenium_session'
6
6
  require 'shared_selenium_node'
7
7
  require 'rspec/shared_spec_matchers'
8
8
 
9
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
9
+ browser_options = Selenium::WebDriver::Firefox::Options.new
10
10
  browser_options.headless! if ENV['HEADLESS']
11
11
  # browser_options.add_option("log", {"level": "trace"})
12
12
 
@@ -15,6 +15,7 @@ browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof
15
15
  profile['browser.download.folderList'] = 2
16
16
  profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
17
17
  profile['browser.startup.homepage'] = 'about:blank' # workaround bug in Selenium 4 alpha4-7
18
+ profile['accessibility.tabfocus'] = 7 # make tab move over links too
18
19
  end
19
20
 
20
21
  Capybara.register_driver :selenium_firefox do |app|
@@ -59,18 +60,34 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
59
60
  when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty'
60
61
  pending "FF < 62 doesn't support setting all files at once" if firefox_lt?(62, @session)
61
62
  when 'Capybara::Session selenium #accept_confirm should work with nested modals'
62
- skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
63
- skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
64
- skip 'Broken again intermittently in FF 71 - jus skip it'
63
+ skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
64
+ skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
65
+ skip 'Broken again intermittently in FF 71 - jus skip it' if firefox_lt?(109, @session) # don't really know when it was fixed
65
66
  when 'Capybara::Session selenium #click_link can download a file'
66
67
  skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
67
68
  when 'Capybara::Session selenium #reset_session! removes ALL cookies'
68
69
  pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
69
70
  when /drag_to.*HTML5/
70
- pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
71
+ pending "Firefox < 62 doesn't support a DataTransfer constructor" if firefox_lt?(62.0, @session)
71
72
  when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
72
73
  'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
73
- skip 'No clue what Firefox is doing here - works fine on MacOS locally'
74
+ skip 'No clue what Firefox is doing here - works fine on MacOS locally' if firefox_lt?(109, @session) # don't really know when it was fixed
75
+ when 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
76
+ 'Capybara::Session selenium node #shadow_root should find nested shadow roots',
77
+ 'Capybara::Session selenium node #shadow_root should click on elements',
78
+ 'Capybara::Session selenium node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
79
+ 'Capybara::Session selenium node #shadow_root should produce error messages when failing',
80
+ 'Capybara::Session with firefox with selenium driver #evaluate_script returns a shadow root'
81
+ pending "Firefox doesn't yet have full W3C shadow root support"
82
+ when 'Capybara::Session selenium #fill_in should handle carriage returns with line feeds in a textarea correctly'
83
+ pending 'Not sure what firefox is doing here'
84
+ when /Capybara::Session selenium node #shadow_root should get visible text/
85
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
86
+ when /Capybara::Session selenium node #shadow_root/
87
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
88
+ skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
89
+ when /Capybara::Session selenium node #set should submit single text input forms if ended with \\n/
90
+ pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
74
91
  end
75
92
  end
76
93
 
@@ -102,7 +119,7 @@ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/Multi
102
119
  end
103
120
 
104
121
  it 'should fill in a datetime input with a String' do
105
- # FF doesn't currently support datetime-local so this is really just a text input
122
+ pending 'Need to figure out what string format this will actually accept'
106
123
  session.fill_in('form_datetime', with: datetime.iso8601)
107
124
  session.click_button('awesome')
108
125
  expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
@@ -21,8 +21,8 @@ def ensure_selenium_running!
21
21
  rescue StandardError
22
22
  if timer.expired?
23
23
  raise 'Selenium is not running. ' \
24
- "You can run a selenium server easily with: \n" \
25
- ' $ docker-compose up -d selenium_firefox'
24
+ "You can run a selenium server easily with: \n. " \
25
+ '$ docker-compose up -d selenium_firefox'
26
26
  else
27
27
  puts 'Waiting for Selenium docker instance...'
28
28
  sleep 1
@@ -35,11 +35,10 @@ Capybara.register_driver :selenium_firefox_remote do |app|
35
35
  ensure_selenium_running!
36
36
 
37
37
  url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
38
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
38
+ browser_options = Selenium::WebDriver::Firefox::Options.new
39
39
 
40
40
  Capybara::Selenium::Driver.new app,
41
41
  browser: :remote,
42
- desired_capabilities: :firefox,
43
42
  options: browser_options,
44
43
  url: url
45
44
  end
@@ -65,6 +64,22 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE
65
64
  when /#accept_confirm should work with nested modals$/
66
65
  # skip because this is timing based and hence flaky when set to pending
67
66
  skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session)
67
+ when 'Capybara::Session selenium_firefox_remote #fill_in should handle carriage returns with line feeds in a textarea correctly'
68
+ pending 'Not sure what firefox is doing here'
69
+ when 'Capybara::Session selenium_firefox_remote node #shadow_root should find elements inside the shadow dom using CSS',
70
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should find nested shadow roots',
71
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should click on elements',
72
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
73
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should produce error messages when failing',
74
+ 'Capybara::Session with firefox with selenium driver #evaluate_script returns a shadow root'
75
+ pending "Firefox doesn't yet have full W3C shadow root support"
76
+ when /Capybara::Session selenium_firefox_remote node #shadow_root should get visible text/
77
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
78
+ when /Capybara::Session selenium_firefox_remote node #shadow_root/
79
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
80
+ skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
81
+ when /Capybara::Session selenium_firefox_remote node #set should submit single text input forms if ended with \\n/
82
+ pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
68
83
  end
69
84
  end
70
85
 
@@ -28,7 +28,7 @@ end
28
28
 
29
29
  Capybara.register_driver :selenium_ie do |app|
30
30
  # ::Selenium::WebDriver.logger.level = "debug"
31
- options = ::Selenium::WebDriver::IE::Options.new
31
+ options = Selenium::WebDriver::IE::Options.new
32
32
  # options.require_window_focus = true
33
33
  # options.add_option("log", {"level": "trace"})
34
34
 
@@ -71,13 +71,10 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
71
71
  pending "IE 11 doesn't support date input types"
72
72
  when /#click_link_or_button with :disabled option happily clicks on links which incorrectly have the disabled attribute$/
73
73
  skip 'IE 11 obeys non-standard disabled attribute on anchor tag'
74
- when /#right_click should allow modifiers$/
75
- skip "Windows can't :meta click because :meta triggers start menu"
76
- when /#click should allow modifiers$/
74
+ when /#click should allow modifiers$/, /#double_click should allow modifiers$/
77
75
  pending "Doesn't work with IE for some unknown reason$"
78
- when /#double_click should allow modifiers$/
79
76
  pending "Doesn't work with IE for some unknown reason$"
80
- when /#click should allow multiple modifiers$/
77
+ when /#click should allow multiple modifiers$/, /#right_click should allow modifiers$/
81
78
  skip "Windows can't :meta click because :meta triggers start menu"
82
79
  when /#double_click should allow multiple modifiers$/
83
80
  skip "Windows can't :alt double click due to being properties shortcut"
@@ -91,7 +88,7 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
91
88
  pending "Window 7 and 8.1 don't support 308 http status code"
92
89
  when /#scroll_to can scroll an element to the center of the viewport$/,
93
90
  /#scroll_to can scroll an element to the center of the scrolling element$/
94
- pending " IE doesn't support ScrollToOptions"
91
+ pending "IE doesn't support ScrollToOptions"
95
92
  when /#attach_file with multipart form should fire change once for each set of files uploaded$/,
96
93
  /#attach_file with multipart form should fire change once when uploading multiple files from empty$/,
97
94
  /#attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files$/
@@ -106,11 +103,13 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
106
103
  when /#attach_file with a block/
107
104
  skip 'Hangs IE testing for unknown reason'
108
105
  when /drag_to.*HTML5/
109
- pending "IE doesn't support a DataTransfer constuctor"
106
+ pending "IE doesn't support a DataTransfer constructor"
110
107
  when /template elements should not be visible/
111
108
  skip "IE doesn't support template elements"
112
109
  when /Element#drop/
113
110
  pending "IE doesn't support DataTransfer constructor"
111
+ when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
112
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
114
113
  end
115
114
  end
116
115
 
@@ -8,28 +8,40 @@ require 'rspec/shared_spec_matchers'
8
8
 
9
9
  SAFARI_DRIVER = :selenium_safari
10
10
 
11
- if ::Selenium::WebDriver::Service.respond_to? :driver_path=
12
- ::Selenium::WebDriver::Safari::Service
13
- else
14
- ::Selenium::WebDriver::Safari
15
- end.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
11
+ # if ::Selenium::WebDriver::Service.respond_to? :driver_path=
12
+ # ::Selenium::WebDriver::Safari::Service
13
+ # else
14
+ # ::Selenium::WebDriver::Safari
15
+ # end.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
16
16
 
17
- browser_options = ::Selenium::WebDriver::Safari::Options.new
17
+ browser_options = Selenium::WebDriver::Safari::Options.new
18
18
  # browser_options.headless! if ENV['HEADLESS']
19
- # browser_options.add_option(:w3c, !!ENV['W3C'])
20
19
 
21
20
  Capybara.register_driver :selenium_safari do |app|
22
- Capybara::Selenium::Driver.new(app, browser: :safari, options: browser_options, timeout: 30).tap do |driver|
21
+ version = Capybara::Selenium::Driver.load_selenium
22
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
23
+ driver_options = { browser: :safari, timeout: 30 }.tap do |opts|
24
+ opts[options_key] = browser_options
25
+ end
26
+
27
+ Capybara::Selenium::Driver.new(app, **driver_options).tap do |driver|
23
28
  # driver.browser.download_path = Capybara.save_path
24
29
  end
25
30
  end
26
31
 
27
32
  Capybara.register_driver :selenium_safari_not_clear_storage do |app|
28
- safari_options = {
33
+ version = Capybara::Selenium::Driver.load_selenium
34
+ options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
35
+ driver_options = {
29
36
  browser: :safari,
30
- options: browser_options
31
- }
32
- Capybara::Selenium::Driver.new(app, safari_options.merge(clear_local_storage: false, clear_session_storage: false))
37
+ clear_local_storage: false,
38
+ clear_session_storage: false,
39
+ timeout: 30
40
+ }.tap do |opts|
41
+ opts[options_key] = browser_options
42
+ end
43
+
44
+ Capybara::Selenium::Driver.new(app, **driver_options)
33
45
  end
34
46
 
35
47
  module TestSessions
@@ -65,16 +77,19 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
65
77
  when 'Capybara::Session selenium_safari node #double_click should allow to adjust the offset',
66
78
  'Capybara::Session selenium_safari node #double_click should double click an element'
67
79
  pending "safardriver doesn't generate a double click event"
68
- when 'Capybara::Session selenium_safari node #click should allow multiple modifiers',
69
- /Capybara::Session selenium_safari node #(click|right_click|double_click) should allow modifiers/
70
- pending "safaridriver doesn't take key state into account when clicking"
71
- when 'Capybara::Session selenium_safari #fill_in on a pre-populated textfield with a reformatting onchange should trigger change when clearing field'
72
- pending "safardriver clear doesn't generate change event"
80
+ when 'Capybara::Session selenium_safari node #double_click should allow modifiers'
81
+ pending "safaridriver doesn't generate double click with key modifiers"
82
+ when /when w3c_click_offset is true should offset/
83
+ pending 'w3c_click_offset is not currently supported with safaridriver'
73
84
  when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
74
85
  'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
75
86
  skip 'safaridriver loses the ability to find elements in the document after `go_back`'
76
- when /drag_to.*HTML5/
77
- pending "Safari doesn't support"
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"
91
+ when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
92
+ pending "Selenium doesn't currently support getting visible text for shadow root elements"
78
93
  end
79
94
  end
80
95
 
@@ -124,7 +139,6 @@ RSpec.describe 'Capybara::Session with safari' do
124
139
  end
125
140
 
126
141
  it 'should fill in a date input with a String' do
127
- pending "Safari doesn't support date inputs"
128
142
  session.fill_in('form_date', with: '06/19/1983')
129
143
  session.click_button('awesome')
130
144
  expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
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)
@@ -95,7 +95,7 @@ RSpec.describe Capybara::Server do
95
95
  it 'should return its #base_url' do
96
96
  app = proc { |_env| [200, {}, ['Hello Server!']] }
97
97
  server = described_class.new(app).boot
98
- uri = ::Addressable::URI.parse(server.base_url)
98
+ uri = Addressable::URI.parse(server.base_url)
99
99
  expect(uri.to_hash).to include(scheme: 'http', host: server.host, port: server.port)
100
100
  end
101
101
 
@@ -136,7 +136,7 @@ RSpec.describe Capybara::Server do
136
136
  end
137
137
 
138
138
  expect(res.body).to include('Hello SSL Server!')
139
- uri = ::Addressable::URI.parse(server.base_url)
139
+ uri = Addressable::URI.parse(server.base_url)
140
140
  expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
141
141
  ensure
142
142
  Capybara.server = :default
@@ -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|
@@ -61,8 +61,6 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
61
61
  end
62
62
 
63
63
  it 'will use native displayed if told to' do
64
- pending "Chromedriver < 76.0.3809.25 doesn't support native displayed in W3C mode" if chrome_lt?(76, session) && (ENV['W3C'] != 'false')
65
-
66
64
  session.driver.options[:native_displayed] = true
67
65
  session.visit('/form')
68
66
  session.find(:css, '#address1_city', visible: true)
@@ -71,8 +69,6 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
71
69
  end
72
70
 
73
71
  it "won't use native displayed if told not to" do
74
- skip 'Non-W3C uses native' if chrome?(session) && (ENV['W3C'] == 'false')
75
-
76
72
  session.driver.options[:native_displayed] = false
77
73
  session.visit('/form')
78
74
  session.find(:css, '#address1_city', visible: true)