webdrivers 4.0.0 → 5.2.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.
@@ -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
@@ -19,8 +19,6 @@ namespace :webdrivers do
19
19
  desc 'Remove and download updated geckodriver if necessary'
20
20
  task :update, [:version] do |_, args|
21
21
  args.with_defaults(version: 0)
22
- Webdrivers.cache_time = ENV.fetch('WD_CACHE_TIME', 86_400)
23
- Webdrivers.install_dir = ENV.fetch('WD_INSTALL_DIR', nil)
24
22
  Webdrivers::Geckodriver.required_version = args.version
25
23
  Webdrivers::Geckodriver.update
26
24
  Webdrivers.logger.info "Updated to geckodriver #{Webdrivers::Geckodriver.current_version}"
@@ -19,8 +19,6 @@ namespace :webdrivers do
19
19
  desc 'Remove and download updated IEDriverServer if necessary'
20
20
  task :update, [:version] do |_, args|
21
21
  args.with_defaults(version: 0)
22
- Webdrivers.cache_time = ENV.fetch('WD_CACHE_TIME', 86_400)
23
- Webdrivers.install_dir = ENV.fetch('WD_INSTALL_DIR', nil)
24
22
  Webdrivers::IEdriver.required_version = args.version
25
23
  Webdrivers::IEdriver.update
26
24
  Webdrivers.logger.info "Updated to IEDriverServer #{Webdrivers::IEdriver.current_version}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Webdrivers
4
- VERSION = '4.0.0'
4
+ VERSION = '5.2.0'
5
5
  end
data/lib/webdrivers.rb CHANGED
@@ -2,5 +2,6 @@
2
2
 
3
3
  require 'webdrivers/chromedriver'
4
4
  require 'webdrivers/geckodriver'
5
+ require 'webdrivers/edgedriver'
5
6
  require 'webdrivers/iedriver'
6
7
  require 'webdrivers/railtie' if defined?(Rails)
@@ -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
@@ -31,7 +31,7 @@ describe Webdrivers::Chromedriver do
31
31
  it 'does not download when offline, binary exists and matches major browser version' do
32
32
  allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
33
33
  allow(chromedriver).to receive(:exists?).and_return(true)
34
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
34
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
35
35
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
36
36
 
37
37
  chromedriver.update
@@ -44,7 +44,7 @@ describe Webdrivers::Chromedriver do
44
44
 
45
45
  allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
46
46
  allow(chromedriver).to receive(:exists?).and_return(true)
47
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
47
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
48
48
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
49
49
 
50
50
  chromedriver.update
@@ -55,7 +55,7 @@ describe Webdrivers::Chromedriver do
55
55
  it 'raises ConnectionError when offline, and binary does not match major browser version' do
56
56
  allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
57
57
  allow(chromedriver).to receive(:exists?).and_return(true)
58
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
58
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
59
59
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
60
60
 
61
61
  msg = %r{Can not reach https://chromedriver.storage.googleapis.com}
@@ -106,9 +106,10 @@ describe Webdrivers::Chromedriver do
106
106
  end
107
107
  end
108
108
 
109
- it 'makes a network call if cached driver does not match the browser' do
109
+ it 'makes network calls if cached driver does not match the browser' do
110
110
  Webdrivers::System.cache_version('chromedriver', '71.0.3578.137')
111
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
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'))
112
113
  allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68')
113
114
  allow(Webdrivers::System).to receive(:download)
114
115
 
@@ -146,7 +147,7 @@ describe Webdrivers::Chromedriver do
146
147
  it 'returns a Gem::Version instance if binary is on the system' do
147
148
  allow(chromedriver).to receive(:exists?).and_return(true)
148
149
  allow(Webdrivers::System).to receive(:call)
149
- .with("#{chromedriver.driver_path} --version")
150
+ .with(chromedriver.driver_path, '--version')
150
151
  .and_return '71.0.3578.137'
151
152
 
152
153
  expect(chromedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
@@ -155,20 +156,20 @@ describe Webdrivers::Chromedriver do
155
156
 
156
157
  describe '#latest_version' do
157
158
  it 'returns 2.41 if the browser version is less than 70' do
158
- allow(chromedriver).to receive(:chrome_version).and_return('69.0.0')
159
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('69.0.0')
159
160
 
160
161
  expect(chromedriver.latest_version).to eq(Gem::Version.new('2.41'))
161
162
  end
162
163
 
163
164
  it 'returns the correct point release for a production version greater than 70' do
164
- allow(chromedriver).to receive(:chrome_version).and_return '71.0.3578.9999'
165
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('71.0.3578.9999')
165
166
 
166
167
  expect(chromedriver.latest_version).to eq Gem::Version.new('71.0.3578.137')
167
168
  end
168
169
 
169
170
  it 'raises VersionError for beta version' do
170
- allow(chromedriver).to receive(:chrome_version).and_return('100.0.0')
171
- msg = 'Unable to find latest point release version for 100.0.0. '\
171
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('999.0.0')
172
+ msg = 'Unable to find latest point release version for 999.0.0. '\
172
173
  'You appear to be using a non-production version of Chrome. '\
173
174
  'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
174
175
  'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
@@ -177,7 +178,7 @@ describe Webdrivers::Chromedriver do
177
178
  end
178
179
 
179
180
  it 'raises VersionError for unknown version' do
180
- allow(chromedriver).to receive(:chrome_version).and_return('72.0.9999.0000')
181
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('72.0.9999.0000')
181
182
  msg = 'Unable to find latest point release version for 72.0.9999. '\
182
183
  'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
183
184
  'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
@@ -199,9 +200,12 @@ describe Webdrivers::Chromedriver do
199
200
  expect(File.exist?("#{Webdrivers::System.install_dir}/chromedriver.version")).to eq true
200
201
  end
201
202
 
202
- it 'does not make network call if cache is valid' do
203
+ it 'does not make network calls if cache is valid and driver exists' do
203
204
  allow(Webdrivers).to receive(:cache_time).and_return(3600)
204
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)
205
209
  allow(Webdrivers::Network).to receive(:get)
206
210
 
207
211
  expect(chromedriver.latest_version).to eq Gem::Version.new('71.0.3578.137')
@@ -209,10 +213,11 @@ describe Webdrivers::Chromedriver do
209
213
  expect(Webdrivers::Network).not_to have_received(:get)
210
214
  end
211
215
 
212
- it 'makes a network call if cache is expired' do
216
+ it 'makes network calls if cache is expired' do
213
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')
214
219
  allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68')
215
- allow(Webdrivers::System).to receive(:valid_cache?)
220
+ allow(Webdrivers::System).to receive(:valid_cache?).and_return(false)
216
221
 
217
222
  expect(chromedriver.latest_version).to eq Gem::Version.new('73.0.3683.68')
218
223
 
@@ -252,7 +257,20 @@ describe Webdrivers::Chromedriver do
252
257
 
253
258
  describe '#driver_path' do
254
259
  it 'returns full location of binary' do
255
- expect(chromedriver.driver_path).to match("#{File.join(ENV['HOME'])}/.webdrivers/chromedriver")
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')
256
274
  end
257
275
  end
258
276
  end
@@ -0,0 +1,52 @@
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 { skip 'Edge is not yet supported on Linux' if Webdrivers::System.platform == 'linux' }
9
+
10
+ context 'when the user relies on the gem to figure out the location of Edge' do
11
+ it 'determines the location correctly based on the current OS' do
12
+ expect { edge_finder.location }.not_to raise_error
13
+ end
14
+ end
15
+
16
+ context 'when the user provides a path to the Edge binary' do
17
+ it 'uses Selenium::WebDriver::Edge.path when it is defined' do
18
+ Selenium::WebDriver::Edge.path = edge_finder.location
19
+ locations = %i[win_location mac_location linux_location]
20
+ allow(edge_finder).to receive_messages(locations)
21
+
22
+ expect(edge_finder.version).not_to be_nil
23
+ locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
24
+ end
25
+
26
+ it "uses ENV['WD_EDGE_PATH'] when it is defined" do
27
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return(edge_finder.location)
28
+ locations = %i[win_location mac_location linux_location]
29
+ allow(edge_finder).to receive_messages(locations)
30
+
31
+ expect(edge_finder.version).not_to be_nil
32
+ locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
33
+ end
34
+
35
+ it 'uses Selenium::WebDriver::Edge.path over WD_EDGE_PATH' do
36
+ Selenium::WebDriver::Edge.path = edge_finder.location
37
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return('my_wd_chrome_path')
38
+ expect(edge_finder.version).not_to be_nil
39
+ expect(ENV).not_to have_received(:[]).with('WD_EDGE_PATH')
40
+ end
41
+ end
42
+
43
+ context 'when Edge is not installed' do
44
+ it 'raises BrowserNotFound' do
45
+ locations = %i[win_location mac_location linux_location]
46
+ allow(edge_finder).to receive_messages(locations)
47
+ allow(edge_finder).to receive(:user_defined_location).and_return(nil)
48
+
49
+ expect { edge_finder.version }.to raise_error(Webdrivers::BrowserNotFound)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,273 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::Edgedriver do
6
+ let(:edgedriver) { described_class }
7
+
8
+ before do
9
+ edgedriver.remove
10
+ end
11
+
12
+ describe '#update' do
13
+ context 'when evaluating #correct_binary?' do
14
+ it 'does not download when latest version and current version match' do
15
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.0'))
16
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0'))
17
+
18
+ edgedriver.update
19
+
20
+ expect(edgedriver.send(:exists?)).to be false
21
+ end
22
+
23
+ it 'does not download when offline, binary exists and is less than v70' do
24
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
25
+ allow(edgedriver).to receive(:exists?).and_return(true)
26
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new(69))
27
+
28
+ edgedriver.update
29
+
30
+ expect(File.exist?(edgedriver.driver_path)).to be false
31
+ end
32
+
33
+ it 'does not download when offline, binary exists and matches major browser version' do
34
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
35
+ allow(edgedriver).to receive(:exists?).and_return(true)
36
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
37
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
38
+
39
+ edgedriver.update
40
+
41
+ expect(File.exist?(edgedriver.driver_path)).to be false
42
+ end
43
+
44
+ it 'does not download when get raises exception, binary exists and matches major browser version' do
45
+ client_error = instance_double(Net::HTTPNotFound, class: Net::HTTPNotFound, code: 404, message: '')
46
+
47
+ allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
48
+ allow(edgedriver).to receive(:exists?).and_return(true)
49
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
50
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
51
+
52
+ edgedriver.update
53
+
54
+ expect(File.exist?(edgedriver.driver_path)).to be false
55
+ end
56
+
57
+ it 'raises ConnectionError when offline, and binary does not match major browser version' do
58
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
59
+ allow(edgedriver).to receive(:exists?).and_return(true)
60
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
61
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
62
+
63
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
64
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
65
+ end
66
+
67
+ it 'raises ConnectionError when offline, and no binary exists' do
68
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
69
+ allow(edgedriver).to receive(:exists?).and_return(false)
70
+
71
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
72
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
73
+ end
74
+ end
75
+
76
+ context 'when correct binary is found' do
77
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(true) }
78
+
79
+ it 'does not download' do
80
+ edgedriver.update
81
+
82
+ expect(edgedriver.current_version).to be_nil
83
+ end
84
+
85
+ it 'does not raise exception if offline' do
86
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
87
+
88
+ edgedriver.update
89
+
90
+ expect(edgedriver.current_version).to be_nil
91
+ end
92
+ end
93
+
94
+ context 'when correct binary is not found' do
95
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(false) }
96
+
97
+ it 'downloads binary' do
98
+ edgedriver.update
99
+
100
+ expect(edgedriver.current_version).not_to be_nil
101
+ end
102
+
103
+ it 'raises ConnectionError if offline' do
104
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
105
+
106
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
107
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
108
+ end
109
+ end
110
+
111
+ it 'makes network calls if cached driver does not match the browser' do
112
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
113
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('71.0.3578.137')
114
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('73.0.3683.68')
115
+ allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68'.encode('UTF-16'))
116
+ allow(Webdrivers::System).to receive(:download)
117
+
118
+ edgedriver.update
119
+
120
+ expect(Webdrivers::Network).to have_received(:get).twice
121
+ end
122
+
123
+ context 'when required version is 0' do
124
+ it 'downloads the latest version' do
125
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('98.0.1089.1'))
126
+ edgedriver.required_version = 0
127
+ edgedriver.update
128
+ expect(edgedriver.current_version.version).to eq('98.0.1089.1')
129
+ end
130
+ end
131
+
132
+ context 'when required version is nil' do
133
+ it 'downloads the latest version' do
134
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('98.0.1089.1'))
135
+ edgedriver.required_version = nil
136
+ edgedriver.update
137
+ expect(edgedriver.current_version.version).to eq('98.0.1089.1')
138
+ end
139
+ end
140
+ end
141
+
142
+ describe '#current_version' do
143
+ it 'returns nil if binary does not exist on the system' do
144
+ allow(edgedriver).to receive(:driver_path).and_return('')
145
+
146
+ expect(edgedriver.current_version).to be_nil
147
+ end
148
+
149
+ it 'returns a Gem::Version instance if binary is on the system' do
150
+ allow(edgedriver).to receive(:exists?).and_return(true)
151
+ allow(Webdrivers::System).to receive(:call)
152
+ .with(edgedriver.driver_path, '--version')
153
+ .and_return '71.0.3578.137'
154
+
155
+ expect(edgedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
156
+ end
157
+ end
158
+
159
+ describe '#latest_version' do
160
+ it 'returns the correct point release for a production version' do
161
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
162
+
163
+ expect(edgedriver.latest_version).to be_between(Gem::Version.new('77.0.207.0'), Gem::Version.new('78'))
164
+ end
165
+
166
+ it 'raises VersionError for beta version' do
167
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('999.0.0')
168
+ msg = 'Unable to find latest point release version for 999.0.0. '\
169
+ 'You appear to be using a non-production version of Edge. '\
170
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
171
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net'
172
+
173
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
174
+ end
175
+
176
+ it 'raises VersionError for unknown version' do
177
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.9999')
178
+ msg = 'Unable to find latest point release version for 77.0.9999. '\
179
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
180
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net'
181
+
182
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
183
+ end
184
+
185
+ it 'raises ConnectionError when offline' do
186
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
187
+
188
+ msg = %r{^Can not reach https://msedgedriver.azureedge.net}
189
+ expect { edgedriver.latest_version }.to raise_error(Webdrivers::ConnectionError, msg)
190
+ end
191
+
192
+ it 'creates cached file' do
193
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
194
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
195
+
196
+ edgedriver.latest_version
197
+ expect(File.exist?("#{Webdrivers::System.install_dir}/msedgedriver.version")).to eq true
198
+ end
199
+
200
+ it 'does not make network calls if cache is valid and driver exists' do
201
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
202
+ Webdrivers::System.cache_version('msedgedriver', '82.0.445.0')
203
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('82.0.445.0')
204
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('82.0.445.0')
205
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
206
+ allow(Webdrivers::Network).to receive(:get)
207
+
208
+ expect(edgedriver.latest_version).to eq Gem::Version.new('82.0.445.0')
209
+
210
+ expect(Webdrivers::Network).not_to have_received(:get)
211
+ end
212
+
213
+ it 'makes network calls if cache is expired' do
214
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
215
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
216
+ allow(Webdrivers::System).to receive(:valid_cache?).and_return(false)
217
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
218
+
219
+ expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
220
+
221
+ expect(Webdrivers::Network).to have_received(:get)
222
+ expect(Webdrivers::System).to have_received(:valid_cache?)
223
+ end
224
+ end
225
+
226
+ describe '#required_version=' do
227
+ after { edgedriver.required_version = nil }
228
+
229
+ it 'returns the version specified as a Float' do
230
+ edgedriver.required_version = 73.0
231
+
232
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
233
+ end
234
+
235
+ it 'returns the version specified as a String' do
236
+ edgedriver.required_version = '73.0'
237
+
238
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
239
+ end
240
+ end
241
+
242
+ describe '#remove' do
243
+ it 'removes existing edgedriver' do
244
+ edgedriver.update
245
+
246
+ edgedriver.remove
247
+ expect(edgedriver.current_version).to be_nil
248
+ end
249
+
250
+ it 'does not raise exception if no edgedriver found' do
251
+ expect { edgedriver.remove }.not_to raise_error
252
+ end
253
+ end
254
+
255
+ describe '#driver_path' do
256
+ it 'returns full location of binary' do
257
+ expected_bin = "msedgedriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
258
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
259
+ expect(edgedriver.driver_path).to eq(expected_path)
260
+ end
261
+ end
262
+
263
+ describe '#browser_version' do
264
+ it 'returns a Gem::Version object' do
265
+ expect(edgedriver.browser_version).to be_an_instance_of(Gem::Version)
266
+ end
267
+
268
+ it 'returns currently installed Edge version' do
269
+ allow(Webdrivers::EdgeFinder).to receive(:version).and_return('72.0.0.0')
270
+ expect(edgedriver.browser_version).to be Gem::Version.new('72.0.0.0')
271
+ end
272
+ end
273
+ end