webdrivers 2.3.2 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +204 -56
  3. data/LICENSE.txt +2 -2
  4. data/README.md +253 -17
  5. data/lib/webdrivers/Rakefile +6 -0
  6. data/lib/webdrivers/chrome_finder.rb +127 -0
  7. data/lib/webdrivers/chromedriver.rb +131 -23
  8. data/lib/webdrivers/common.rb +145 -70
  9. data/lib/webdrivers/edge_finder.rb +99 -0
  10. data/lib/webdrivers/edgedriver.rb +87 -17
  11. data/lib/webdrivers/geckodriver.rb +46 -25
  12. data/lib/webdrivers/iedriver.rb +51 -18
  13. data/lib/webdrivers/logger.rb +111 -0
  14. data/lib/webdrivers/network.rb +63 -0
  15. data/lib/webdrivers/railtie.rb +15 -0
  16. data/lib/webdrivers/system.rb +197 -0
  17. data/lib/webdrivers/tasks/chromedriver.rake +44 -0
  18. data/lib/webdrivers/tasks/edgedriver.rake +44 -0
  19. data/lib/webdrivers/tasks/geckodriver.rake +44 -0
  20. data/lib/webdrivers/tasks/iedriver.rake +44 -0
  21. data/lib/webdrivers/version.rb +5 -0
  22. data/lib/webdrivers.rb +7 -9
  23. data/spec/spec_helper.rb +18 -2
  24. data/spec/webdrivers/chrome_finder_spec.rb +103 -0
  25. data/spec/webdrivers/chromedriver_spec.rb +276 -0
  26. data/spec/webdrivers/edge_finder_spec.rb +58 -0
  27. data/spec/webdrivers/edgedriver_spec.rb +279 -0
  28. data/spec/webdrivers/geckodriver_spec.rb +211 -0
  29. data/spec/webdrivers/i_edriver_spec.rb +197 -0
  30. data/spec/webdrivers/system_spec.rb +79 -0
  31. data/spec/webdrivers/webdrivers_spec.rb +80 -0
  32. data/spec/webdrivers_proxy_support_spec.rb +53 -0
  33. metadata +157 -43
  34. data/.gitignore +0 -6
  35. data/.travis.yml +0 -3
  36. data/Gemfile +0 -4
  37. data/Rakefile +0 -6
  38. data/bin/IEDriverServer +0 -5
  39. data/bin/MicrosoftWebDriver +0 -5
  40. data/bin/chromedriver +0 -5
  41. data/bin/geckodriver +0 -5
  42. data/bin/phantomjs +0 -5
  43. data/lib/webdrivers/phantomjs.rb +0 -40
  44. data/spec/chromedriver_spec.rb +0 -36
  45. data/spec/edgedriver_spec.rb +0 -24
  46. data/spec/geckodriver_spec.rb +0 -36
  47. data/spec/iedriver_spec.rb +0 -27
  48. data/spec/phantomjs_spec.rb +0 -36
  49. data/webdrivers.gemspec +0 -24
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :webdrivers do
4
+ require 'webdrivers/chromedriver'
5
+
6
+ namespace :chromedriver do
7
+ Webdrivers.logger.level = :info
8
+
9
+ desc 'Print current chromedriver version'
10
+ task :version do
11
+ gem_ver = Webdrivers::Chromedriver.current_version
12
+ if gem_ver
13
+ Webdrivers.logger.info "chromedriver #{gem_ver.version}"
14
+ else
15
+ Webdrivers.logger.warn 'No existing chromedriver found.'
16
+ end
17
+ end
18
+
19
+ desc 'Remove and download updated chromedriver if necessary'
20
+ task :update, [:version] do |_, args|
21
+ args.with_defaults(version: 0)
22
+ Webdrivers::Chromedriver.required_version = args.version
23
+ Webdrivers::Chromedriver.update
24
+ Webdrivers.logger.info "Updated to chromedriver #{Webdrivers::Chromedriver.current_version}"
25
+ end
26
+
27
+ desc 'Force remove chromedriver'
28
+ task :remove do
29
+ unless File.exist? Webdrivers::Chromedriver.driver_path
30
+ Webdrivers.logger.info 'No existing chromedriver to remove.'
31
+ next # Return early
32
+ end
33
+
34
+ cur_version = Webdrivers::Chromedriver.current_version
35
+ Webdrivers::Chromedriver.remove
36
+
37
+ if File.exist? Webdrivers::Chromedriver.driver_path # Failed for some reason
38
+ Webdrivers.logger.error 'Failed to remove chromedriver. Please try removing manually.'
39
+ else
40
+ Webdrivers.logger.info "Removed chromedriver #{cur_version}."
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :webdrivers do
4
+ require 'webdrivers/edgedriver'
5
+
6
+ namespace :edgedriver do
7
+ Webdrivers.logger.level = :info
8
+
9
+ desc 'Print current edgedriver version'
10
+ task :version do
11
+ gem_ver = Webdrivers::Edgedriver.current_version
12
+ if gem_ver
13
+ Webdrivers.logger.info "edgedriver #{gem_ver.version}"
14
+ else
15
+ Webdrivers.logger.warn 'No existing edgedriver found.'
16
+ end
17
+ end
18
+
19
+ desc 'Remove and download updated edgedriver if necessary'
20
+ task :update, [:version] do |_, args|
21
+ args.with_defaults(version: 0)
22
+ Webdrivers::Edgedriver.required_version = args.version
23
+ Webdrivers::Edgedriver.update
24
+ Webdrivers.logger.info "Updated to edgedriver #{Webdrivers::Edgedriver.current_version}"
25
+ end
26
+
27
+ desc 'Force remove edgedriver'
28
+ task :remove do
29
+ unless File.exist? Webdrivers::Edgedriver.driver_path
30
+ Webdrivers.logger.info 'No existing edgedriver to remove.'
31
+ next # Return early
32
+ end
33
+
34
+ cur_version = Webdrivers::Edgedriver.current_version
35
+ Webdrivers::Edgedriver.remove
36
+
37
+ if File.exist? Webdrivers::Edgedriver.driver_path # Failed for some reason
38
+ Webdrivers.logger.error 'Failed to remove edgedriver. Please try removing manually.'
39
+ else
40
+ Webdrivers.logger.info "Removed edgedriver #{cur_version}."
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :webdrivers do
4
+ require 'webdrivers/geckodriver'
5
+
6
+ namespace :geckodriver do
7
+ Webdrivers.logger.level = :info
8
+
9
+ desc 'Print current geckodriver version'
10
+ task :version do
11
+ gem_ver = Webdrivers::Geckodriver.current_version
12
+ if gem_ver
13
+ Webdrivers.logger.info "geckodriver #{gem_ver.version}"
14
+ else
15
+ Webdrivers.logger.warn 'No existing geckodriver found.'
16
+ end
17
+ end
18
+
19
+ desc 'Remove and download updated geckodriver if necessary'
20
+ task :update, [:version] do |_, args|
21
+ args.with_defaults(version: 0)
22
+ Webdrivers::Geckodriver.required_version = args.version
23
+ Webdrivers::Geckodriver.update
24
+ Webdrivers.logger.info "Updated to geckodriver #{Webdrivers::Geckodriver.current_version}"
25
+ end
26
+
27
+ desc 'Force remove geckodriver'
28
+ task :remove do
29
+ unless File.exist? Webdrivers::Geckodriver.driver_path
30
+ Webdrivers.logger.info 'No existing geckodriver to remove.'
31
+ next # Return early
32
+ end
33
+
34
+ cur_version = Webdrivers::Geckodriver.current_version
35
+ Webdrivers::Geckodriver.remove
36
+
37
+ if File.exist? Webdrivers::Geckodriver.driver_path # Failed for some reason
38
+ Webdrivers.logger.error 'Failed to remove geckodriver. Please try removing manually.'
39
+ else
40
+ Webdrivers.logger.info "Removed geckodriver #{cur_version}."
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :webdrivers do
4
+ require 'webdrivers/iedriver'
5
+
6
+ namespace :iedriver do
7
+ Webdrivers.logger.level = :info
8
+
9
+ desc 'Print current IEDriverServer version'
10
+ task :version do
11
+ gem_ver = Webdrivers::IEdriver.current_version
12
+ if gem_ver
13
+ Webdrivers.logger.info "IEDriverServer #{gem_ver.version}"
14
+ else
15
+ Webdrivers.logger.warn 'No existing IEDriverServer found.'
16
+ end
17
+ end
18
+
19
+ desc 'Remove and download updated IEDriverServer if necessary'
20
+ task :update, [:version] do |_, args|
21
+ args.with_defaults(version: 0)
22
+ Webdrivers::IEdriver.required_version = args.version
23
+ Webdrivers::IEdriver.update
24
+ Webdrivers.logger.info "Updated to IEDriverServer #{Webdrivers::IEdriver.current_version}"
25
+ end
26
+
27
+ desc 'Force remove IEDriverServer'
28
+ task :remove do
29
+ unless File.exist? Webdrivers::IEdriver.driver_path
30
+ Webdrivers.logger.info 'No existing IEDriverServer to remove.'
31
+ next # Return early
32
+ end
33
+
34
+ cur_version = Webdrivers::IEdriver.current_version
35
+ Webdrivers::IEdriver.remove
36
+
37
+ if File.exist? Webdrivers::IEdriver.driver_path # Failed for some reason
38
+ Webdrivers.logger.error 'Failed to remove IEDriverServer. Please try removing manually.'
39
+ else
40
+ Webdrivers.logger.info "Removed IEDriverServer #{cur_version}."
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Webdrivers
4
+ VERSION = '4.7.0'
5
+ end
data/lib/webdrivers.rb CHANGED
@@ -1,9 +1,7 @@
1
- require "webdrivers/common"
2
- require "webdrivers/chromedriver"
3
- require "webdrivers/edgedriver"
4
- require "webdrivers/geckodriver"
5
- require "webdrivers/iedriver"
6
- require "webdrivers/phantomjs"
7
- require 'fileutils'
8
- require 'rbconfig'
9
- require 'open-uri'
1
+ # frozen_string_literal: true
2
+
3
+ require 'webdrivers/chromedriver'
4
+ require 'webdrivers/geckodriver'
5
+ require 'webdrivers/edgedriver'
6
+ require 'webdrivers/iedriver'
7
+ require 'webdrivers/railtie' if defined?(Rails)
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,18 @@
1
- require "rspec"
2
- require "webdrivers"
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ require 'rspec'
7
+ require 'webdrivers'
8
+
9
+ RSpec.configure do |config|
10
+ config.filter_run_including focus: true unless ENV['CI']
11
+ config.run_all_when_everything_filtered = true
12
+ config.expect_with :rspec do |expectations|
13
+ expectations.syntax = :expect
14
+ end
15
+ config.mock_with :rspec do |mocks|
16
+ mocks.verify_partial_doubles = true
17
+ end
18
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::ChromeFinder do
6
+ let(:chrome_finder) { described_class }
7
+
8
+ context 'when the user relies on the gem to figure out the location of Chrome' do
9
+ it 'determines the location correctly based on the current OS' do
10
+ expect { chrome_finder.location }.not_to raise_error
11
+ end
12
+ end
13
+
14
+ context 'when the user provides a path to the Chrome binary' do
15
+ it 'uses Selenium::WebDriver::Chrome.path when it is defined' do
16
+ Selenium::WebDriver::Chrome.path = chrome_finder.location
17
+ locations = %i[win_location mac_location linux_location]
18
+ allow(chrome_finder).to receive_messages(locations)
19
+
20
+ expect(chrome_finder.version).not_to be_nil
21
+ locations.each { |loc| expect(chrome_finder).not_to have_received(loc) }
22
+ end
23
+ end
24
+
25
+ it "uses ENV['WD_CHROME_PATH'] when it is defined" do
26
+ allow(ENV).to receive(:[]).with('WD_CHROME_PATH').and_return(chrome_finder.location)
27
+ locations = %i[win_location mac_location linux_location]
28
+ allow(chrome_finder).to receive_messages(locations)
29
+
30
+ expect(chrome_finder.version).not_to be_nil
31
+ locations.each { |loc| expect(chrome_finder).not_to have_received(loc) }
32
+ end
33
+
34
+ it 'uses Selenium::WebDriver::Chrome.path over WD_CHROME_PATH' do
35
+ Selenium::WebDriver::Chrome.path = chrome_finder.location
36
+ allow(ENV).to receive(:[]).with('WD_CHROME_PATH').and_return('my_wd_chrome_path')
37
+ expect(chrome_finder.version).not_to be_nil
38
+ expect(ENV).not_to have_received(:[]).with('WD_CHROME_PATH')
39
+ end
40
+
41
+ context 'when Chrome is not installed' do
42
+ it 'raises BrowserNotFound' do
43
+ locations = %i[win_location mac_location linux_location]
44
+ allow(chrome_finder).to receive_messages(locations)
45
+ allow(chrome_finder).to receive(:user_defined_location).and_return(nil)
46
+
47
+ expect { chrome_finder.version }.to raise_error(Webdrivers::BrowserNotFound)
48
+ end
49
+ end
50
+
51
+ context 'when running in WSL' do
52
+ before do
53
+ skip "The current platform cannot be WSL, as it's not Linux" unless Selenium::WebDriver::Platform.linux?
54
+
55
+ allow(Webdrivers::System).to receive(:wsl_v1?).and_return(true)
56
+ allow(Webdrivers::System).to receive(:to_wsl_path).and_return('')
57
+ allow(Webdrivers::System).to receive(:to_win32_path).and_return('')
58
+ end
59
+
60
+ it 'checks Windows locations for Chrome' do
61
+ drive = 'c'
62
+ user = 'WinUser'
63
+ file = 'chrome.exe'
64
+ path = [
65
+ '/home/wsl-user/.local/bin',
66
+ '/usr/local/bin',
67
+ '/usr/local/games',
68
+ '/usr/bin',
69
+ "/#{drive}/Users/#{user}/AppData/Local/Microsoft/WindowsApps",
70
+ '/snap/bin'
71
+ ].join ':'
72
+
73
+ allow(chrome_finder).to receive(:user_defined_location).and_return(nil)
74
+ allow(ENV).to receive(:[]).with('WD_CHROME_PATH').and_return(nil)
75
+ allow(ENV).to receive(:[]).with('PATH').and_return(path)
76
+ allow(File).to receive(:exist?).and_return(false)
77
+
78
+ locations = [
79
+ "#{drive}:\\Users\\#{user}\\AppData\\Local\\Google\\Chrome\\Application\\#{file}",
80
+ "#{drive}:\\Program Files (x86)\\Chromium\\Application\\#{file}",
81
+ "#{drive}:\\Program Files\\Google\\Chrome\\Application\\#{file}"
82
+ ]
83
+
84
+ # CIs don't support WSL yet, so our mocks lead to the error path for simplicity
85
+ expect { chrome_finder.location }.to raise_error(Webdrivers::BrowserNotFound)
86
+
87
+ locations.each do |dir|
88
+ expect(Webdrivers::System).to have_received(:to_wsl_path).with(dir)
89
+ end
90
+ end
91
+
92
+ it 'uses win_version to get the Chrome version using win32 path' do
93
+ allow(chrome_finder).to receive(:win_version).and_return('')
94
+ allow(File).to receive(:exist?).and_return(true)
95
+
96
+ # CIs don't support WSL yet, so our mocks lead to the error path for simplicity
97
+ expect { chrome_finder.version }.to raise_error(Webdrivers::VersionError)
98
+
99
+ expect(Webdrivers::System).to have_received(:to_win32_path)
100
+ expect(chrome_finder).to have_received(:win_version)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::Chromedriver do
6
+ let(:chromedriver) { described_class }
7
+
8
+ before { chromedriver.remove }
9
+
10
+ describe '#update' do
11
+ context 'when evaluating #correct_binary?' do
12
+ it 'does not download when latest version and current version match' do
13
+ allow(chromedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.0'))
14
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0'))
15
+
16
+ chromedriver.update
17
+
18
+ expect(chromedriver.send(:exists?)).to be false
19
+ end
20
+
21
+ it 'does not download when offline, binary exists and is less than v70' do
22
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
23
+ allow(chromedriver).to receive(:exists?).and_return(true)
24
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new(69))
25
+
26
+ chromedriver.update
27
+
28
+ expect(File.exist?(chromedriver.driver_path)).to be false
29
+ end
30
+
31
+ it 'does not download when offline, binary exists and matches major browser version' do
32
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
33
+ allow(chromedriver).to receive(:exists?).and_return(true)
34
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
35
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
36
+
37
+ chromedriver.update
38
+
39
+ expect(File.exist?(chromedriver.driver_path)).to be false
40
+ end
41
+
42
+ it 'does not download when get raises exception, binary exists and matches major browser version' do
43
+ client_error = instance_double(Net::HTTPNotFound, class: Net::HTTPNotFound, code: 404, message: '')
44
+
45
+ allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
46
+ allow(chromedriver).to receive(:exists?).and_return(true)
47
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
48
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
49
+
50
+ chromedriver.update
51
+
52
+ expect(File.exist?(chromedriver.driver_path)).to be false
53
+ end
54
+
55
+ it 'raises ConnectionError when offline, and binary does not match major browser version' do
56
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
57
+ allow(chromedriver).to receive(:exists?).and_return(true)
58
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
59
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
60
+
61
+ msg = %r{Can not reach https://chromedriver.storage.googleapis.com}
62
+ expect { chromedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
63
+ end
64
+
65
+ it 'raises ConnectionError when offline, and no binary exists' do
66
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
67
+ allow(chromedriver).to receive(:exists?).and_return(false)
68
+
69
+ msg = %r{Can not reach https://chromedriver.storage.googleapis.com}
70
+ expect { chromedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
71
+ end
72
+ end
73
+
74
+ context 'when correct binary is found' do
75
+ before { allow(chromedriver).to receive(:correct_binary?).and_return(true) }
76
+
77
+ it 'does not download' do
78
+ chromedriver.update
79
+
80
+ expect(chromedriver.current_version).to be_nil
81
+ end
82
+
83
+ it 'does not raise exception if offline' do
84
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
85
+
86
+ chromedriver.update
87
+
88
+ expect(chromedriver.current_version).to be_nil
89
+ end
90
+ end
91
+
92
+ context 'when correct binary is not found' do
93
+ before { allow(chromedriver).to receive(:correct_binary?).and_return(false) }
94
+
95
+ it 'downloads binary' do
96
+ chromedriver.update
97
+
98
+ expect(chromedriver.current_version).not_to be_nil
99
+ end
100
+
101
+ it 'raises ConnectionError if offline' do
102
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
103
+
104
+ msg = %r{Can not reach https://chromedriver.storage.googleapis.com/}
105
+ expect { chromedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
106
+ end
107
+ end
108
+
109
+ it 'makes network calls if cached driver does not match the browser' do
110
+ Webdrivers::System.cache_version('chromedriver', '71.0.3578.137')
111
+ allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('71.0.3578.137'))
112
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
113
+ allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68')
114
+ allow(Webdrivers::System).to receive(:download)
115
+
116
+ chromedriver.update
117
+
118
+ expect(Webdrivers::Network).to have_received(:get).twice
119
+ end
120
+
121
+ context 'when required version is 0' do
122
+ it 'downloads the latest version' do
123
+ allow(chromedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.3626.7'))
124
+ chromedriver.required_version = 0
125
+ chromedriver.update
126
+ expect(chromedriver.current_version.version).to eq('72.0.3626.7')
127
+ end
128
+ end
129
+
130
+ context 'when required version is nil' do
131
+ it 'downloads the latest version' do
132
+ allow(chromedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.3626.7'))
133
+ chromedriver.required_version = nil
134
+ chromedriver.update
135
+ expect(chromedriver.current_version.version).to eq('72.0.3626.7')
136
+ end
137
+ end
138
+ end
139
+
140
+ describe '#current_version' do
141
+ it 'returns nil if binary does not exist on the system' do
142
+ allow(chromedriver).to receive(:driver_path).and_return('')
143
+
144
+ expect(chromedriver.current_version).to be_nil
145
+ end
146
+
147
+ it 'returns a Gem::Version instance if binary is on the system' do
148
+ allow(chromedriver).to receive(:exists?).and_return(true)
149
+ allow(Webdrivers::System).to receive(:call)
150
+ .with(chromedriver.driver_path, '--version')
151
+ .and_return '71.0.3578.137'
152
+
153
+ expect(chromedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
154
+ end
155
+ end
156
+
157
+ describe '#latest_version' do
158
+ it 'returns 2.41 if the browser version is less than 70' do
159
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('69.0.0')
160
+
161
+ expect(chromedriver.latest_version).to eq(Gem::Version.new('2.41'))
162
+ end
163
+
164
+ it 'returns the correct point release for a production version greater than 70' do
165
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('71.0.3578.9999')
166
+
167
+ expect(chromedriver.latest_version).to eq Gem::Version.new('71.0.3578.137')
168
+ end
169
+
170
+ it 'raises VersionError for beta version' do
171
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('100.0.0')
172
+ msg = 'Unable to find latest point release version for 100.0.0. '\
173
+ 'You appear to be using a non-production version of Chrome. '\
174
+ 'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
175
+ 'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
176
+
177
+ expect { chromedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
178
+ end
179
+
180
+ it 'raises VersionError for unknown version' do
181
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('72.0.9999.0000')
182
+ msg = 'Unable to find latest point release version for 72.0.9999. '\
183
+ 'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
184
+ 'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
185
+
186
+ expect { chromedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
187
+ end
188
+
189
+ it 'raises ConnectionError when offline' do
190
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
191
+
192
+ msg = %r{^Can not reach https://chromedriver.storage.googleapis.com}
193
+ expect { chromedriver.latest_version }.to raise_error(Webdrivers::ConnectionError, msg)
194
+ end
195
+
196
+ it 'creates cached file' do
197
+ allow(Webdrivers::Network).to receive(:get).and_return('71.0.3578.137')
198
+
199
+ chromedriver.latest_version
200
+ expect(File.exist?("#{Webdrivers::System.install_dir}/chromedriver.version")).to eq true
201
+ end
202
+
203
+ it 'does not make network calls if cache is valid and driver exists' do
204
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
205
+ Webdrivers::System.cache_version('chromedriver', '71.0.3578.137')
206
+ allow(chromedriver).to receive(:current_version).and_return Gem::Version.new('71.0.3578.137')
207
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('71.0.3578.137')
208
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
209
+ allow(Webdrivers::Network).to receive(:get)
210
+
211
+ expect(chromedriver.latest_version).to eq Gem::Version.new('71.0.3578.137')
212
+
213
+ expect(Webdrivers::Network).not_to have_received(:get)
214
+ end
215
+
216
+ it 'makes network calls if cache is expired' do
217
+ Webdrivers::System.cache_version('chromedriver', '71.0.3578.137')
218
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('71.0.3578.137')
219
+ allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68')
220
+ allow(Webdrivers::System).to receive(:valid_cache?).and_return(false)
221
+
222
+ expect(chromedriver.latest_version).to eq Gem::Version.new('73.0.3683.68')
223
+
224
+ expect(Webdrivers::Network).to have_received(:get)
225
+ expect(Webdrivers::System).to have_received(:valid_cache?)
226
+ end
227
+ end
228
+
229
+ describe '#required_version=' do
230
+ after { chromedriver.required_version = nil }
231
+
232
+ it 'returns the version specified as a Float' do
233
+ chromedriver.required_version = 73.0
234
+
235
+ expect(chromedriver.required_version).to eq Gem::Version.new('73.0')
236
+ end
237
+
238
+ it 'returns the version specified as a String' do
239
+ chromedriver.required_version = '73.0'
240
+
241
+ expect(chromedriver.required_version).to eq Gem::Version.new('73.0')
242
+ end
243
+ end
244
+
245
+ describe '#remove' do
246
+ it 'removes existing chromedriver' do
247
+ chromedriver.update
248
+
249
+ chromedriver.remove
250
+ expect(chromedriver.current_version).to be_nil
251
+ end
252
+
253
+ it 'does not raise exception if no chromedriver found' do
254
+ expect { chromedriver.remove }.not_to raise_error
255
+ end
256
+ end
257
+
258
+ describe '#driver_path' do
259
+ it 'returns full location of binary' do
260
+ expected_bin = "chromedriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
261
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
262
+ expect(chromedriver.driver_path).to eq(expected_path)
263
+ end
264
+ end
265
+
266
+ describe '#browser_version' do
267
+ it 'returns a Gem::Version object' do
268
+ expect(chromedriver.browser_version).to be_an_instance_of(Gem::Version)
269
+ end
270
+
271
+ it 'returns currently installed Chrome version' do
272
+ allow(Webdrivers::ChromeFinder).to receive(:version).and_return('72.0.0.0')
273
+ expect(chromedriver.browser_version).to be Gem::Version.new('72.0.0.0')
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::EdgeFinder do
6
+ let(:edge_finder) { described_class }
7
+
8
+ before(:all) do # rubocop:disable RSpec/BeforeAfterAll
9
+ if Selenium::WebDriver::VERSION[0].to_i < 4
10
+ skip 'The current selenium-webdriver does not include Chromium based Edge support'
11
+ elsif Webdrivers::System.platform == 'linux'
12
+ skip 'Edge is not yet supported on Linux'
13
+ end
14
+ end
15
+
16
+ context 'when the user relies on the gem to figure out the location of Edge' do
17
+ it 'determines the location correctly based on the current OS' do
18
+ expect { edge_finder.location }.not_to raise_error
19
+ end
20
+ end
21
+
22
+ context 'when the user provides a path to the Edge binary' do
23
+ it 'uses Selenium::WebDriver::Edge.path when it is defined' do
24
+ Selenium::WebDriver::Edge.path = edge_finder.location
25
+ locations = %i[win_location mac_location linux_location]
26
+ allow(edge_finder).to receive_messages(locations)
27
+
28
+ expect(edge_finder.version).not_to be_nil
29
+ locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
30
+ end
31
+
32
+ it "uses ENV['WD_EDGE_PATH'] when it is defined" do
33
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return(edge_finder.location)
34
+ locations = %i[win_location mac_location linux_location]
35
+ allow(edge_finder).to receive_messages(locations)
36
+
37
+ expect(edge_finder.version).not_to be_nil
38
+ locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
39
+ end
40
+
41
+ it 'uses Selenium::WebDriver::Edge.path over WD_EDGE_PATH' do
42
+ Selenium::WebDriver::Edge.path = edge_finder.location
43
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return('my_wd_chrome_path')
44
+ expect(edge_finder.version).not_to be_nil
45
+ expect(ENV).not_to have_received(:[]).with('WD_EDGE_PATH')
46
+ end
47
+ end
48
+
49
+ context 'when Edge is not installed' do
50
+ it 'raises BrowserNotFound' do
51
+ locations = %i[win_location mac_location linux_location]
52
+ allow(edge_finder).to receive_messages(locations)
53
+ allow(edge_finder).to receive(:user_defined_location).and_return(nil)
54
+
55
+ expect { edge_finder.version }.to raise_error(Webdrivers::BrowserNotFound)
56
+ end
57
+ end
58
+ end