webdrivers 2.3.2 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
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,279 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::Edgedriver do
6
+ let(:edgedriver) { 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
+ before { edgedriver.remove }
17
+
18
+ describe '#update' do
19
+ context 'when evaluating #correct_binary?' do
20
+ it 'does not download when latest version and current version match' do
21
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.0'))
22
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0'))
23
+
24
+ edgedriver.update
25
+
26
+ expect(edgedriver.send(:exists?)).to be false
27
+ end
28
+
29
+ it 'does not download when offline, binary exists and is less than v70' do
30
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
31
+ allow(edgedriver).to receive(:exists?).and_return(true)
32
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new(69))
33
+
34
+ edgedriver.update
35
+
36
+ expect(File.exist?(edgedriver.driver_path)).to be false
37
+ end
38
+
39
+ it 'does not download when offline, binary exists and matches major browser version' do
40
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
41
+ allow(edgedriver).to receive(:exists?).and_return(true)
42
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
43
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
44
+
45
+ edgedriver.update
46
+
47
+ expect(File.exist?(edgedriver.driver_path)).to be false
48
+ end
49
+
50
+ it 'does not download when get raises exception, binary exists and matches major browser version' do
51
+ client_error = instance_double(Net::HTTPNotFound, class: Net::HTTPNotFound, code: 404, message: '')
52
+
53
+ allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
54
+ allow(edgedriver).to receive(:exists?).and_return(true)
55
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
56
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
57
+
58
+ edgedriver.update
59
+
60
+ expect(File.exist?(edgedriver.driver_path)).to be false
61
+ end
62
+
63
+ it 'raises ConnectionError when offline, and binary does not match major browser version' do
64
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
65
+ allow(edgedriver).to receive(:exists?).and_return(true)
66
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
67
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
68
+
69
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
70
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
71
+ end
72
+
73
+ it 'raises ConnectionError when offline, and no binary exists' do
74
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
75
+ allow(edgedriver).to receive(:exists?).and_return(false)
76
+
77
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
78
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
79
+ end
80
+ end
81
+
82
+ context 'when correct binary is found' do
83
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(true) }
84
+
85
+ it 'does not download' do
86
+ edgedriver.update
87
+
88
+ expect(edgedriver.current_version).to be_nil
89
+ end
90
+
91
+ it 'does not raise exception if offline' do
92
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
93
+
94
+ edgedriver.update
95
+
96
+ expect(edgedriver.current_version).to be_nil
97
+ end
98
+ end
99
+
100
+ context 'when correct binary is not found' do
101
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(false) }
102
+
103
+ it 'downloads binary' do
104
+ edgedriver.update
105
+
106
+ expect(edgedriver.current_version).not_to be_nil
107
+ end
108
+
109
+ it 'raises ConnectionError if offline' do
110
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
111
+
112
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
113
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
114
+ end
115
+ end
116
+
117
+ it 'makes network calls if cached driver does not match the browser' do
118
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
119
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('71.0.3578.137')
120
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('73.0.3683.68')
121
+ allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68'.encode('UTF-16'))
122
+ allow(Webdrivers::System).to receive(:download)
123
+
124
+ edgedriver.update
125
+
126
+ expect(Webdrivers::Network).to have_received(:get).twice
127
+ end
128
+
129
+ context 'when required version is 0' do
130
+ it 'downloads the latest version' do
131
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('77.0.207.0'))
132
+ edgedriver.required_version = 0
133
+ edgedriver.update
134
+ expect(edgedriver.current_version.version).to eq('77.0.207.0')
135
+ end
136
+ end
137
+
138
+ context 'when required version is nil' do
139
+ it 'downloads the latest version' do
140
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('77.0.207.0'))
141
+ edgedriver.required_version = nil
142
+ edgedriver.update
143
+ expect(edgedriver.current_version.version).to eq('77.0.207.0')
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#current_version' do
149
+ it 'returns nil if binary does not exist on the system' do
150
+ allow(edgedriver).to receive(:driver_path).and_return('')
151
+
152
+ expect(edgedriver.current_version).to be_nil
153
+ end
154
+
155
+ it 'returns a Gem::Version instance if binary is on the system' do
156
+ allow(edgedriver).to receive(:exists?).and_return(true)
157
+ allow(Webdrivers::System).to receive(:call)
158
+ .with(edgedriver.driver_path, '--version')
159
+ .and_return '71.0.3578.137'
160
+
161
+ expect(edgedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
162
+ end
163
+ end
164
+
165
+ describe '#latest_version' do
166
+ it 'returns the correct point release for a production version' do
167
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
168
+
169
+ expect(edgedriver.latest_version).to be_between(Gem::Version.new('77.0.207.0'), Gem::Version.new('78'))
170
+ end
171
+
172
+ it 'raises VersionError for beta version' do
173
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('100.0.0')
174
+ msg = 'Unable to find latest point release version for 100.0.0. '\
175
+ 'You appear to be using a non-production version of Edge. '\
176
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
177
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net/'
178
+
179
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
180
+ end
181
+
182
+ it 'raises VersionError for unknown version' do
183
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.9999')
184
+ msg = 'Unable to find latest point release version for 77.0.9999. '\
185
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
186
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net/'
187
+
188
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
189
+ end
190
+
191
+ it 'raises ConnectionError when offline' do
192
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
193
+
194
+ msg = %r{^Can not reach https://msedgedriver.azureedge.net}
195
+ expect { edgedriver.latest_version }.to raise_error(Webdrivers::ConnectionError, msg)
196
+ end
197
+
198
+ it 'creates cached file' do
199
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
200
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
201
+
202
+ edgedriver.latest_version
203
+ expect(File.exist?("#{Webdrivers::System.install_dir}/msedgedriver.version")).to eq true
204
+ end
205
+
206
+ it 'does not make network calls if cache is valid and driver exists' do
207
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
208
+ Webdrivers::System.cache_version('msedgedriver', '82.0.445.0')
209
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('82.0.445.0')
210
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('82.0.445.0')
211
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
212
+ allow(Webdrivers::Network).to receive(:get)
213
+
214
+ expect(edgedriver.latest_version).to eq Gem::Version.new('82.0.445.0')
215
+
216
+ expect(Webdrivers::Network).not_to have_received(:get)
217
+ end
218
+
219
+ it 'makes network calls if cache is expired' do
220
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
221
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
222
+ allow(Webdrivers::System).to receive(:valid_cache?).and_return(false)
223
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
224
+
225
+ expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
226
+
227
+ expect(Webdrivers::Network).to have_received(:get)
228
+ expect(Webdrivers::System).to have_received(:valid_cache?)
229
+ end
230
+ end
231
+
232
+ describe '#required_version=' do
233
+ after { edgedriver.required_version = nil }
234
+
235
+ it 'returns the version specified as a Float' do
236
+ edgedriver.required_version = 73.0
237
+
238
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
239
+ end
240
+
241
+ it 'returns the version specified as a String' do
242
+ edgedriver.required_version = '73.0'
243
+
244
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
245
+ end
246
+ end
247
+
248
+ describe '#remove' do
249
+ it 'removes existing edgedriver' do
250
+ edgedriver.update
251
+
252
+ edgedriver.remove
253
+ expect(edgedriver.current_version).to be_nil
254
+ end
255
+
256
+ it 'does not raise exception if no edgedriver found' do
257
+ expect { edgedriver.remove }.not_to raise_error
258
+ end
259
+ end
260
+
261
+ describe '#driver_path' do
262
+ it 'returns full location of binary' do
263
+ expected_bin = "msedgedriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
264
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
265
+ expect(edgedriver.driver_path).to eq(expected_path)
266
+ end
267
+ end
268
+
269
+ describe '#browser_version' do
270
+ it 'returns a Gem::Version object' do
271
+ expect(edgedriver.browser_version).to be_an_instance_of(Gem::Version)
272
+ end
273
+
274
+ it 'returns currently installed Edge version' do
275
+ allow(Webdrivers::EdgeFinder).to receive(:version).and_return('72.0.0.0')
276
+ expect(edgedriver.browser_version).to be Gem::Version.new('72.0.0.0')
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::Geckodriver do
6
+ let(:geckodriver) { described_class }
7
+
8
+ before do
9
+ geckodriver.remove
10
+ geckodriver.required_version = nil
11
+ end
12
+
13
+ describe '#update' do
14
+ context 'when evaluating #correct_binary?' do
15
+ it 'does not download when latest version and current version match' do
16
+ allow(geckodriver).to receive(:latest_version).and_return(Gem::Version.new('0.3.0'))
17
+ allow(geckodriver).to receive(:current_version).and_return(Gem::Version.new('0.3.0'))
18
+
19
+ geckodriver.update
20
+
21
+ expect(geckodriver.send(:exists?)).to be false
22
+ end
23
+
24
+ it 'does not download when offline, but binary exists' do
25
+ allow(Webdrivers::System).to receive(:call).and_return('geckodriver 0.24.0 ( 2019-01-28)')
26
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
27
+ allow(geckodriver).to receive(:exists?).and_return(true)
28
+
29
+ geckodriver.update
30
+
31
+ expect(File.exist?(geckodriver.driver_path)).to be false
32
+ end
33
+
34
+ it 'raises ConnectionError when offline, and no binary exists' do
35
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
36
+ allow(geckodriver).to receive(:exists?).and_return(false)
37
+
38
+ expect { geckodriver.update }.to raise_error(Webdrivers::ConnectionError)
39
+ end
40
+ end
41
+
42
+ context 'when correct binary is found' do
43
+ before { allow(geckodriver).to receive(:correct_binary?).and_return(true) }
44
+
45
+ it 'does not download' do
46
+ geckodriver.update
47
+
48
+ expect(geckodriver.current_version).to be_nil
49
+ end
50
+
51
+ it 'does not raise exception if offline' do
52
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
53
+
54
+ geckodriver.update
55
+
56
+ expect(geckodriver.current_version).to be_nil
57
+ end
58
+ end
59
+
60
+ context 'when correct binary is not found' do
61
+ before { allow(geckodriver).to receive(:correct_binary?).and_return(false) }
62
+
63
+ it 'downloads binary' do
64
+ geckodriver.update
65
+
66
+ expect(geckodriver.current_version).not_to be_nil
67
+ end
68
+
69
+ it 'raises ConnectionError if offline' do
70
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
71
+
72
+ msg = %r{Can not reach https://github.com/mozilla/geckodriver/releases}
73
+ expect { geckodriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
74
+ end
75
+ end
76
+
77
+ it 'finds the required version from parsed downloads page' do
78
+ base = 'https://github.com/mozilla/geckodriver/releases/download'
79
+ url = %r{#{base}\/v0\.2\.0\/geckodriver-v0\.2\.0-}
80
+
81
+ allow(Webdrivers::System).to receive(:download).with(url, geckodriver.driver_path)
82
+
83
+ geckodriver.required_version = '0.2.0'
84
+ geckodriver.update
85
+
86
+ expect(Webdrivers::System).to have_received(:download).with(url, geckodriver.driver_path)
87
+ end
88
+
89
+ it 'does something when a wrong version is supplied' do
90
+ geckodriver.required_version = '0.2.0'
91
+
92
+ msg = /Net::HTTPServerException: 404 "Not Found"/
93
+ expect { geckodriver.update }.to raise_error(StandardError, msg)
94
+ end
95
+ end
96
+
97
+ describe '#current_version' do
98
+ it 'returns nil if binary does not exist on the system' do
99
+ allow(geckodriver).to receive(:driver_path).and_return('')
100
+
101
+ expect(geckodriver.current_version).to be_nil
102
+ end
103
+
104
+ it 'returns a Gem::Version instance if binary is on the system' do
105
+ allow(geckodriver).to receive(:exists?).and_return(true)
106
+
107
+ return_value = "geckodriver 0.24.0 ( 2019-01-28)
108
+
109
+ The source code of this program is available from
110
+ testing/geckodriver in https://hg.mozilla.org/mozilla-central.
111
+
112
+ This program is subject to the terms of the Mozilla Public License 2.0.
113
+ You can obtain a copy of the license at https://mozilla.org/MPL/2.0/"
114
+
115
+ allow(Webdrivers::System).to receive(:call).with(geckodriver.driver_path, '--version').and_return return_value
116
+
117
+ expect(geckodriver.current_version).to eq Gem::Version.new('0.24.0')
118
+ end
119
+ end
120
+
121
+ describe '#latest_version' do
122
+ it 'finds the latest version directly' do
123
+ url = 'https://github.com/mozilla/geckodriver/releases/tag/v0.24.0'
124
+ allow(Webdrivers::Network).to receive(:get_url).and_return(url)
125
+
126
+ geckodriver.update
127
+
128
+ expect(geckodriver.latest_version).to eq Gem::Version.new('0.24.0')
129
+ end
130
+
131
+ it 'creates cached file' do
132
+ allow(Webdrivers::Network).to receive(:get).and_return('0.24.0')
133
+
134
+ geckodriver.latest_version
135
+ expect(File.exist?("#{Webdrivers::System.install_dir}/geckodriver.version")).to eq true
136
+ end
137
+
138
+ it 'does not make network calls if cache is valid and driver exists' do
139
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
140
+ Webdrivers::System.cache_version('geckodriver', '0.23.0')
141
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
142
+ allow(Webdrivers::Network).to receive(:get)
143
+
144
+ expect(geckodriver.latest_version).to eq Gem::Version.new('0.23.0')
145
+
146
+ expect(Webdrivers::Network).not_to have_received(:get)
147
+ end
148
+
149
+ it 'makes a network call if cache is expired' do
150
+ Webdrivers::System.cache_version('geckodriver', '0.23.0')
151
+ url = 'https://github.com/mozilla/geckodriver/releases/tag/v0.24.0'
152
+ allow(Webdrivers::Network).to receive(:get_url).and_return(url)
153
+ allow(Webdrivers::System).to receive(:valid_cache?)
154
+
155
+ expect(geckodriver.latest_version).to eq Gem::Version.new('0.24.0')
156
+
157
+ expect(Webdrivers::Network).to have_received(:get_url)
158
+ expect(Webdrivers::System).to have_received(:valid_cache?)
159
+ end
160
+ end
161
+
162
+ describe '#required_version=' do
163
+ it 'returns the version specified as a Float' do
164
+ geckodriver.required_version = 0.12
165
+
166
+ expect(geckodriver.required_version).to eq Gem::Version.new('0.12')
167
+ end
168
+
169
+ it 'returns the version specified as a String' do
170
+ geckodriver.required_version = '0.12.1'
171
+
172
+ expect(geckodriver.required_version).to eq Gem::Version.new('0.12.1')
173
+ end
174
+ end
175
+
176
+ describe '#remove' do
177
+ it 'removes existing geckodriver' do
178
+ geckodriver.update
179
+
180
+ geckodriver.remove
181
+ expect(geckodriver.current_version).to be_nil
182
+ end
183
+
184
+ it 'does not raise exception if no geckodriver found' do
185
+ expect { geckodriver.remove }.not_to raise_error
186
+ end
187
+ end
188
+
189
+ describe '#install_dir' do
190
+ it 'uses ~/.webdrivers as default value' do
191
+ expect(Webdrivers::System.install_dir).to include('.webdriver')
192
+ end
193
+
194
+ it 'uses provided value' do
195
+ install_dir = File.expand_path(File.join(ENV['HOME'], '.webdrivers2'))
196
+ Webdrivers.install_dir = install_dir
197
+
198
+ expect(Webdrivers::System.install_dir).to eq install_dir
199
+ ensure
200
+ Webdrivers.install_dir = nil
201
+ end
202
+ end
203
+
204
+ describe '#driver_path' do
205
+ it 'returns full location of binary' do
206
+ expected_bin = "geckodriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
207
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
208
+ expect(geckodriver.driver_path).to eq(expected_path)
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::IEdriver do
6
+ let(:iedriver) { described_class }
7
+
8
+ before do
9
+ if ENV['CI'] && !Selenium::WebDriver::Platform.windows?
10
+ skip('Only run IE tests on Windows on CI because rate limiting')
11
+ end
12
+
13
+ iedriver.remove
14
+ iedriver.required_version = nil
15
+ end
16
+
17
+ describe '#update' do
18
+ context 'when evaluating #correct_binary?' do
19
+ it 'does not download when latest version and current version match' do
20
+ allow(iedriver).to receive(:latest_version).and_return(Gem::Version.new('0.3.0'))
21
+ allow(iedriver).to receive(:current_version).and_return(Gem::Version.new('0.3.0'))
22
+
23
+ iedriver.update
24
+
25
+ expect(iedriver.send(:exists?)).to be false
26
+ end
27
+
28
+ it 'does not download when offline, but binary exists' do
29
+ allow(Webdrivers::System).to receive(:call).and_return('something IEDriverServer.exe 3.5.1 something else')
30
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
31
+ allow(iedriver).to receive(:exists?).and_return(true)
32
+
33
+ iedriver.update
34
+
35
+ expect(File.exist?(iedriver.driver_path)).to be false
36
+ end
37
+
38
+ it 'raises ConnectionError when offline, and no binary exists' do
39
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
40
+ allow(iedriver).to receive(:exists?).and_return(false)
41
+
42
+ expect { iedriver.update }.to raise_error(Webdrivers::ConnectionError)
43
+ end
44
+ end
45
+
46
+ context 'when correct binary is found' do
47
+ before { allow(iedriver).to receive(:correct_binary?).and_return(true) }
48
+
49
+ it 'does not download' do
50
+ iedriver.update
51
+
52
+ expect(iedriver.current_version).to be_nil
53
+ end
54
+
55
+ it 'does not raise exception if offline' do
56
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
57
+
58
+ iedriver.update
59
+
60
+ expect(iedriver.current_version).to be_nil
61
+ end
62
+ end
63
+
64
+ context 'when correct binary is not found' do
65
+ before { allow(iedriver).to receive(:correct_binary?).and_return(false) }
66
+
67
+ it 'downloads binary' do
68
+ iedriver.update
69
+
70
+ expect(File.exist?(iedriver.driver_path)).to eq true
71
+ end
72
+
73
+ it 'raises ConnectionError if offline' do
74
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
75
+
76
+ msg = %r{Can not reach https://api.github.com/repos/seleniumhq/selenium/releases}
77
+ expect { iedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#current_version' do
83
+ it 'returns nil if binary does not exist on the system' do
84
+ allow(iedriver).to receive(:driver_path).and_return('')
85
+
86
+ expect(iedriver.current_version).to be_nil
87
+ end
88
+
89
+ it 'returns a Gem::Version instance if binary is on the system' do
90
+ allow(iedriver).to receive(:exists?).and_return(true)
91
+
92
+ return_value = 'something IEDriverServer.exe 3.5.1 something else'
93
+
94
+ allow(Webdrivers::System).to receive(:call).with(iedriver.driver_path, '--version').and_return return_value
95
+
96
+ expect(iedriver.current_version).to eq Gem::Version.new('3.5.1')
97
+ end
98
+ end
99
+
100
+ describe '#latest_version' do
101
+ it 'finds the latest version from parsed hash' do
102
+ base = 'https://selenium-release.storage.googleapis.com/'
103
+ hash = {Gem::Version.new('3.4.0') => "#{base}/3.4/IEDriverServer_Win32_3.4.0.zip",
104
+ Gem::Version.new('3.5.0') => "#{base}/3.5/IEDriverServer_Win32_3.5.0.zip",
105
+ Gem::Version.new('3.5.1') => "#{base}/3.5/IEDriverServer_Win32_3.5.1.zip"}
106
+ allow(iedriver).to receive(:downloads).and_return(hash)
107
+
108
+ expect(iedriver.latest_version).to eq Gem::Version.new('3.5.1')
109
+ end
110
+
111
+ it 'correctly parses the downloads page' do
112
+ expect(iedriver.send(:downloads)).not_to be_empty
113
+ end
114
+
115
+ it 'creates cached file' do
116
+ json = '[{"assets": [{"name":"IEDriverServer_Win32_3.150.0.zip"}]}]'
117
+ allow(Webdrivers::Network).to receive(:get).and_return(json)
118
+
119
+ iedriver.latest_version
120
+ expect(File.exist?("#{Webdrivers::System.install_dir}/IEDriverServer.version")).to eq true
121
+ end
122
+
123
+ it 'does not make network calls if cache is valid and driver exists' do
124
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
125
+ Webdrivers::System.cache_version('IEDriverServer', '3.4.0')
126
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
127
+ allow(Webdrivers::Network).to receive(:get)
128
+
129
+ expect(iedriver.latest_version).to eq Gem::Version.new('3.4.0')
130
+
131
+ expect(Webdrivers::Network).not_to have_received(:get)
132
+ end
133
+
134
+ it 'makes a network call if cache is expired' do
135
+ Webdrivers::System.cache_version('IEDriverServer', '3.4.0')
136
+ base = 'https://selenium-release.storage.googleapis.com/'
137
+ hash = {Gem::Version.new('3.4.0') => "#{base}/3.4/IEDriverServer_Win32_3.4.0.zip",
138
+ Gem::Version.new('3.5.0') => "#{base}/3.5/IEDriverServer_Win32_3.5.0.zip",
139
+ Gem::Version.new('3.5.1') => "#{base}/3.5/IEDriverServer_Win32_3.5.1.zip"}
140
+ allow(iedriver).to receive(:downloads).and_return(hash)
141
+ allow(Webdrivers::System).to receive(:valid_cache?)
142
+
143
+ expect(iedriver.latest_version).to eq Gem::Version.new('3.5.1')
144
+ expect(iedriver).to have_received(:downloads)
145
+ expect(Webdrivers::System).to have_received(:valid_cache?)
146
+ end
147
+ end
148
+
149
+ describe '#required_version=' do
150
+ it 'returns the version specified as a Float' do
151
+ iedriver.required_version = 0.12
152
+
153
+ expect(iedriver.required_version).to eq Gem::Version.new('0.12')
154
+ end
155
+
156
+ it 'returns the version specified as a String' do
157
+ iedriver.required_version = '0.12.1'
158
+
159
+ expect(iedriver.required_version).to eq Gem::Version.new('0.12.1')
160
+ end
161
+ end
162
+
163
+ describe '#remove' do
164
+ it 'removes existing iedriver' do
165
+ iedriver.update
166
+
167
+ iedriver.remove
168
+ expect(iedriver.current_version).to be_nil
169
+ end
170
+
171
+ it 'does not raise exception if no iedriver found' do
172
+ expect { iedriver.remove }.not_to raise_error
173
+ end
174
+ end
175
+
176
+ describe '#install_dir' do
177
+ it 'uses ~/.webdrivers as default value' do
178
+ expect(Webdrivers::System.install_dir).to include('.webdriver')
179
+ end
180
+
181
+ it 'uses provided value' do
182
+ install_dir = File.expand_path(File.join(ENV['HOME'], '.webdrivers2'))
183
+ Webdrivers.install_dir = install_dir
184
+
185
+ expect(Webdrivers::System.install_dir).to eq install_dir
186
+ ensure
187
+ Webdrivers.install_dir = nil
188
+ end
189
+ end
190
+
191
+ describe '#driver_path' do
192
+ it 'returns full location of binary' do
193
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/IEDriverServer.exe"
194
+ expect(iedriver.driver_path).to eq(expected_path)
195
+ end
196
+ end
197
+ end