Skip to content

Commit fbfc808

Browse files
committed
[rb] add custom Selenium Manager error and improve logic
1 parent 757faf0 commit fbfc808

19 files changed

+91
-56
lines changed

rb/Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
selenium-devtools (0.113.0)
4+
selenium-devtools (0.114.0)
55
selenium-webdriver (~> 4.2)
66
selenium-webdriver (4.9.1)
77
rexml (~> 3.2, >= 3.2.5)

rb/lib/selenium/webdriver/common/driver_finder.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,20 @@ def self.path(options, klass)
2626
path ||= Platform.find_binary(klass::EXECUTABLE)
2727

2828
path ||= begin
29-
SeleniumManager.driver_path(options)
29+
SeleniumManager.driver_path(options) unless options.is_a?(Remote::Capabilities)
3030
rescue StandardError => e
31-
WebDriver.logger.warn("Unable to obtain driver using Selenium Manager\n #{e.message}",
32-
id: :selenium_manager)
33-
nil
31+
raise Error::NoSuchDriverError, "Unable to obtain #{klass::EXECUTABLE} using Selenium Manager; #{e.message}"
32+
end
33+
34+
begin
35+
Platform.assert_file(path)
36+
Platform.assert_executable(path)
37+
rescue TypeError
38+
raise Error::NoSuchDriverError, "Unable to locate or obtain #{klass::EXECUTABLE}"
39+
rescue Error::WebDriverError => e
40+
raise Error::NoSuchDriverError, "#{klass::EXECUTABLE} located, but: #{e.message}"
3441
end
35-
msg = "Unable to locate the #{klass::EXECUTABLE} executable; for more information on how to install drivers, " \
36-
'see https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/'
37-
raise Error::WebDriverError, msg unless path
3842

39-
Platform.assert_executable path
4043
path
4144
end
4245
end

rb/lib/selenium/webdriver/common/error.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,16 @@ class ElementClickInterceptedError < WebDriverError; end
227227
#
228228

229229
class UnsupportedOperationError < WebDriverError; end
230+
231+
#
232+
# Indicates that driver was not specified and could not be located.
233+
#
234+
235+
class NoSuchDriverError < WebDriverError
236+
def initialize(msg = '')
237+
super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}/driver_location")
238+
end
239+
end
230240
end # Error
231241
end # WebDriver
232242
end # Selenium

rb/lib/selenium/webdriver/common/proxy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def as_json(*)
152152
'socksUsername' => socks_username,
153153
'socksPassword' => socks_password,
154154
'socksVersion' => socks_version
155-
}.delete_if { |_k, v| v.nil? }
155+
}.compact
156156

157157
json_result if json_result.length > 1
158158
end

rb/lib/selenium/webdriver/common/selenium_manager.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ def driver_path(options)
4040
message = 'applicable driver not found; attempting to install with Selenium Manager (Beta)'
4141
WebDriver.logger.debug(message, id: :selenium_manager)
4242

43-
unless options.is_a?(Options)
44-
raise ArgumentError, "SeleniumManager requires a WebDriver::Options instance, not #{options.inspect}"
45-
end
46-
4743
command = generate_command(binary, options)
4844

4945
location = run(*command)
@@ -85,11 +81,18 @@ def binary
8581
'/linux/selenium-manager'
8682
end
8783
location = File.expand_path(path, __FILE__)
88-
unless location.is_a?(String) && File.exist?(location) && File.executable?(location)
89-
raise Error::WebDriverError, 'Unable to obtain Selenium Manager'
84+
85+
begin
86+
Platform.assert_file(location)
87+
Platform.assert_executable(location)
88+
rescue TypeError
89+
raise Error::WebDriverError,
90+
"Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object"
91+
rescue Error::WebDriverError => e
92+
raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}"
9093
end
9194

92-
WebDriver.logger.debug("Selenium Manager found at #{location}", id: :selenium_manager)
95+
WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager)
9396
location
9497
end
9598
end
@@ -102,7 +105,7 @@ def run(*command)
102105
json_output = stdout.empty? ? nil : JSON.parse(stdout)
103106
result = json_output&.dig('result', 'message')
104107
rescue StandardError => e
105-
raise Error::WebDriverError, "Unsuccessful command executed: #{command}", e.message
108+
raise Error::WebDriverError, "Unsuccessful command executed: #{command}; #{e.message}"
106109
end
107110

108111
(json_output&.fetch('logs') || []).each do |log|

rb/spec/unit/selenium/webdriver/chrome/driver_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def expect_request(body: nil, endpoint: nil)
6464

6565
it 'does not require any parameters' do
6666
allow(SeleniumManager).to receive(:driver_path).and_return('path')
67+
allow(Platform).to receive(:assert_file)
6768
allow(Platform).to receive(:assert_executable)
6869

6970
expect_request
@@ -73,6 +74,7 @@ def expect_request(body: nil, endpoint: nil)
7374

7475
it 'accepts provided Options as sole parameter' do
7576
allow(SeleniumManager).to receive(:driver_path).and_return('path')
77+
allow(Platform).to receive(:assert_file)
7678
allow(Platform).to receive(:assert_executable)
7779

7880
opts = {args: ['-f']}

rb/spec/unit/selenium/webdriver/chrome/service_spec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module Chrome
2727
let(:service_path) { "/path/to/#{Service::EXECUTABLE}" }
2828

2929
before do
30-
allow(Platform).to receive(:assert_executable).and_return(true)
30+
allow(Platform).to receive(:assert_executable)
3131
end
3232

3333
after { described_class.driver_path = nil }
@@ -113,6 +113,7 @@ module Chrome
113113

114114
it 'is created when :url is not provided' do
115115
allow(SeleniumManager).to receive(:driver_path).and_return('path')
116+
allow(Platform).to receive(:assert_file)
116117
allow(Platform).to receive(:assert_executable)
117118
allow(described_class).to receive(:new).and_return(service)
118119

@@ -122,6 +123,7 @@ module Chrome
122123

123124
it 'accepts :service without creating a new instance' do
124125
allow(SeleniumManager).to receive(:driver_path).and_return('path')
126+
allow(Platform).to receive(:assert_file)
125127
allow(Platform).to receive(:assert_executable)
126128
allow(described_class).to receive(:new)
127129

rb/spec/unit/selenium/webdriver/common/driver_finder_spec.rb

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module WebDriver
3131

3232
it 'accepts path set on class as String' do
3333
allow(SeleniumManager).to receive(:driver_path)
34+
allow(Platform).to receive(:assert_file)
3435
allow(Platform).to receive(:assert_executable)
3536

3637
service.driver_path = 'path'
@@ -42,6 +43,7 @@ module WebDriver
4243

4344
it 'accepts path set on class as proc' do
4445
allow(SeleniumManager).to receive(:driver_path)
46+
allow(Platform).to receive(:assert_file)
4547
allow(Platform).to receive(:assert_executable)
4648

4749
service.driver_path = proc { 'path' }
@@ -54,6 +56,7 @@ module WebDriver
5456

5557
it 'uses path from PATH' do
5658
allow(SeleniumManager).to receive(:driver_path)
59+
allow(Platform).to receive(:assert_file)
5760
allow(Platform).to receive(:assert_executable)
5861
allow(Platform).to receive(:find_binary).and_return('path')
5962

@@ -68,11 +71,8 @@ module WebDriver
6871
allow(SeleniumManager).to receive(:driver_path).and_raise(Error::WebDriverError)
6972

7073
expect {
71-
expect {
72-
described_class.path(options, service)
73-
}.to raise_error(WebDriver::Error::WebDriverError,
74-
/Unable to locate the #{driver} executable; for more information on how to install/)
75-
}.to have_warning(:selenium_manager)
74+
described_class.path(options, service)
75+
}.to raise_error(WebDriver::Error::NoSuchDriverError, %r{errors/driver_location})
7676
end
7777
end
7878

@@ -85,6 +85,7 @@ module WebDriver
8585

8686
it 'accepts path set on class as String' do
8787
allow(SeleniumManager).to receive(:driver_path)
88+
allow(Platform).to receive(:assert_file)
8889
allow(Platform).to receive(:assert_executable)
8990

9091
service.driver_path = 'path'
@@ -96,6 +97,7 @@ module WebDriver
9697

9798
it 'accepts path set on class as proc' do
9899
allow(SeleniumManager).to receive(:driver_path)
100+
allow(Platform).to receive(:assert_file)
99101
allow(Platform).to receive(:assert_executable)
100102

101103
service.driver_path = proc { 'path' }
@@ -108,6 +110,7 @@ module WebDriver
108110

109111
it 'uses path from PATH' do
110112
allow(SeleniumManager).to receive(:driver_path)
113+
allow(Platform).to receive(:assert_file)
111114
allow(Platform).to receive(:assert_executable)
112115
allow(Platform).to receive(:find_binary).and_return('path')
113116

@@ -122,11 +125,8 @@ module WebDriver
122125
allow(SeleniumManager).to receive(:driver_path).and_raise(Error::WebDriverError)
123126

124127
expect {
125-
expect {
126-
described_class.path(options, service)
127-
}.to raise_error(WebDriver::Error::WebDriverError,
128-
/Unable to locate the #{driver} executable; for more information on how to install/)
129-
}.to have_warning(:selenium_manager)
128+
described_class.path(options, service)
129+
}.to raise_error(WebDriver::Error::NoSuchDriverError, %r{errors/driver_location})
130130
end
131131
end
132132

@@ -139,6 +139,7 @@ module WebDriver
139139

140140
it 'accepts path set on class as String' do
141141
allow(SeleniumManager).to receive(:driver_path)
142+
allow(Platform).to receive(:assert_file)
142143
allow(Platform).to receive(:assert_executable)
143144

144145
service.driver_path = 'path'
@@ -150,6 +151,7 @@ module WebDriver
150151

151152
it 'accepts path set on class as proc' do
152153
allow(SeleniumManager).to receive(:driver_path)
154+
allow(Platform).to receive(:assert_file)
153155
allow(Platform).to receive(:assert_executable)
154156

155157
service.driver_path = proc { 'path' }
@@ -162,6 +164,7 @@ module WebDriver
162164

163165
it 'uses path from PATH' do
164166
allow(SeleniumManager).to receive(:driver_path)
167+
allow(Platform).to receive(:assert_file)
165168
allow(Platform).to receive(:assert_executable)
166169
allow(Platform).to receive(:find_binary).and_return('path')
167170

@@ -176,11 +179,8 @@ module WebDriver
176179
allow(SeleniumManager).to receive(:driver_path).and_raise(Error::WebDriverError)
177180

178181
expect {
179-
expect {
180-
described_class.path(options, service)
181-
}.to raise_error(WebDriver::Error::WebDriverError,
182-
/Unable to locate the #{driver} executable; for more information on how to install/)
183-
}.to have_warning(:selenium_manager)
182+
described_class.path(options, service)
183+
}.to raise_error(WebDriver::Error::NoSuchDriverError, %r{errors/driver_location})
184184
end
185185
end
186186

@@ -193,6 +193,7 @@ module WebDriver
193193

194194
it 'accepts path set on class as String' do
195195
allow(SeleniumManager).to receive(:driver_path)
196+
allow(Platform).to receive(:assert_file)
196197
allow(Platform).to receive(:assert_executable)
197198

198199
service.driver_path = 'path'
@@ -204,6 +205,7 @@ module WebDriver
204205

205206
it 'accepts path set on class as proc' do
206207
allow(SeleniumManager).to receive(:driver_path)
208+
allow(Platform).to receive(:assert_file)
207209
allow(Platform).to receive(:assert_executable)
208210

209211
service.driver_path = proc { 'path' }
@@ -216,6 +218,7 @@ module WebDriver
216218

217219
it 'uses path from PATH' do
218220
allow(SeleniumManager).to receive(:driver_path)
221+
allow(Platform).to receive(:assert_file)
219222
allow(Platform).to receive(:assert_executable)
220223
allow(Platform).to receive(:find_binary).and_return('path')
221224

@@ -230,11 +233,8 @@ module WebDriver
230233
allow(SeleniumManager).to receive(:driver_path).and_raise(Error::WebDriverError)
231234

232235
expect {
233-
expect {
234-
described_class.path(options, service)
235-
}.to raise_error(WebDriver::Error::WebDriverError,
236-
/Unable to locate the #{driver} executable; for more information on how to install/)
237-
}.to have_warning(:selenium_manager)
236+
described_class.path(options, service)
237+
}.to raise_error(WebDriver::Error::NoSuchDriverError, %r{errors/driver_location})
238238
end
239239
end
240240

@@ -247,6 +247,7 @@ module WebDriver
247247

248248
it 'accepts path set on class as String' do
249249
allow(SeleniumManager).to receive(:driver_path)
250+
allow(Platform).to receive(:assert_file)
250251
allow(Platform).to receive(:assert_executable)
251252

252253
service.driver_path = 'path'
@@ -258,6 +259,7 @@ module WebDriver
258259

259260
it 'accepts path set on class as proc' do
260261
allow(SeleniumManager).to receive(:driver_path)
262+
allow(Platform).to receive(:assert_file)
261263
allow(Platform).to receive(:assert_executable)
262264

263265
service.driver_path = proc { 'path' }
@@ -270,6 +272,7 @@ module WebDriver
270272

271273
it 'uses path from PATH' do
272274
allow(SeleniumManager).to receive(:driver_path)
275+
allow(Platform).to receive(:assert_file)
273276
allow(Platform).to receive(:assert_executable)
274277
allow(Platform).to receive(:find_binary).and_return('path')
275278

@@ -284,11 +287,8 @@ module WebDriver
284287
allow(SeleniumManager).to receive(:driver_path).and_raise(Error::WebDriverError)
285288

286289
expect {
287-
expect {
288-
described_class.path(options, service)
289-
}.to raise_error(WebDriver::Error::WebDriverError,
290-
/Unable to locate the #{driver} executable; for more information on how to install/)
291-
}.to have_warning(:selenium_manager)
290+
described_class.path(options, service)
291+
}.to raise_error(WebDriver::Error::NoSuchDriverError, %r{errors/driver_location})
292292
end
293293
end
294294
end

rb/spec/unit/selenium/webdriver/common/interactions/pointer_event_prop_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ module Interactions
2929

3030
def initialize(opts)
3131
@opts = opts
32+
super
3233
end
3334

3435
def assert_source(*); end

rb/spec/unit/selenium/webdriver/common/selenium_manager_spec.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ def stub_binary(binary)
3434

3535
it 'detects Windows' do
3636
stub_binary('/windows/selenium-manager.exe')
37+
allow(Platform).to receive(:assert_file)
3738
allow(Platform).to receive(:windows?).and_return(true)
3839

3940
expect(described_class.send(:binary)).to match(%r{/windows/selenium-manager\.exe$})
4041
end
4142

4243
it 'detects Mac' do
4344
stub_binary('/macos/selenium-manager')
45+
allow(Platform).to receive(:assert_file)
4446
allow(Platform).to receive(:windows?).and_return(false)
4547
allow(Platform).to receive(:mac?).and_return(true)
4648

@@ -49,6 +51,7 @@ def stub_binary(binary)
4951

5052
it 'detects Linux' do
5153
stub_binary('/linux/selenium-manager')
54+
allow(Platform).to receive(:assert_file)
5255
allow(Platform).to receive(:windows?).and_return(false)
5356
allow(Platform).to receive(:mac?).and_return(false)
5457
allow(Platform).to receive(:linux?).and_return(true)
@@ -61,7 +64,7 @@ def stub_binary(binary)
6164

6265
expect {
6366
described_class.send(:binary)
64-
}.to raise_error(Error::WebDriverError, /Unable to obtain Selenium Manager/)
67+
}.to raise_error(Error::WebDriverError, /Selenium Manager binary located, but not a file/)
6568
end
6669
end
6770

@@ -74,12 +77,6 @@ def stub_binary(binary)
7477
end
7578

7679
describe 'self.driver_path' do
77-
it 'errors if not an option' do
78-
expect {
79-
described_class.driver_path(Remote::Capabilities.new(browser_name: 'chrome'))
80-
}.to raise_error(ArgumentError, /SeleniumManager requires a WebDriver::Options instance/)
81-
end
82-
8380
it 'determines browser name by default' do
8481
allow(described_class).to receive(:run)
8582
allow(described_class).to receive(:binary).and_return('selenium-manager')

0 commit comments

Comments
 (0)