webdrivers 4.3.0 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,16 +44,19 @@ module Webdrivers
44
44
  end
45
45
 
46
46
  def downloads
47
- doc = Nokogiri::XML.parse(Network.get(base_url))
48
- items = doc.css('Key').collect(&:text)
49
- items.select! { |item| item.include?('IEDriverServer_Win32') }
50
- ds = items.each_with_object({}) do |item, hash|
51
- key = normalize_version item[/([^_]+)\.zip/, 1]
52
- hash[key] = "#{base_url}#{item}"
47
+ ds = download_manifest.each_with_object({}) do |item, hash|
48
+ version = normalize_version item[/([^_]+)\.zip/, 1]
49
+ hash[version] = "#{base_url}#{item}"
53
50
  end
54
51
  Webdrivers.logger.debug "Versions now located on downloads site: #{ds.keys}"
55
52
  ds
56
53
  end
54
+
55
+ def download_manifest
56
+ doc = Nokogiri::XML.parse(Network.get(base_url))
57
+ items = doc.css('Key').collect(&:text)
58
+ items.select { |item| item.include?('IEDriverServer_Win32') }
59
+ end
57
60
  end
58
61
  end
59
62
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'net/http'
4
+
3
5
  module Webdrivers
4
6
  #
5
7
  # @api private
@@ -148,6 +148,35 @@ module Webdrivers
148
148
  end
149
149
  end
150
150
 
151
+ def apple_m1_architecture?
152
+ if platform == 'mac' && RUBY_PLATFORM.include?('arm64-darwin')
153
+ Webdrivers.logger.debug 'Apple architecture: M1 (arm64-darwin)'
154
+ return true
155
+ end
156
+
157
+ Webdrivers.logger.debug 'Apple architecture: Intel (mac64)'
158
+ false
159
+ end
160
+
161
+ # @return [TrueClass, FalseClass]
162
+ def wsl_v1?
163
+ platform == 'linux' && File.open('/proc/version').read.include?('Microsoft')
164
+ end
165
+
166
+ # @param [String] path
167
+ # @return [String]
168
+ def to_win32_path(path)
169
+ return path if /[a-z]:\\/iu.match?(path)
170
+
171
+ call("wslpath -w '#{path}'").chomp
172
+ end
173
+
174
+ # @param [String] path
175
+ # @return [String]
176
+ def to_wsl_path(path)
177
+ call("wslpath -u '#{path}'").chomp
178
+ end
179
+
151
180
  def bitsize
152
181
  Selenium::WebDriver::Platform.bitsize
153
182
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Webdrivers
4
- VERSION = '4.3.0'
4
+ VERSION = '4.6.0'
5
5
  end
@@ -47,4 +47,57 @@ describe Webdrivers::ChromeFinder do
47
47
  expect { chrome_finder.version }.to raise_error(Webdrivers::BrowserNotFound)
48
48
  end
49
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
50
103
  end
@@ -106,15 +106,16 @@ 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(:current_version).and_return(Gem::Version.new('71.0.3578.137'))
111
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
 
115
116
  chromedriver.update
116
117
 
117
- expect(Webdrivers::Network).to have_received(:get).once
118
+ expect(Webdrivers::Network).to have_received(:get).twice
118
119
  end
119
120
 
120
121
  context 'when required version is 0' do
@@ -155,19 +156,19 @@ 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(:browser_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(:browser_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(:browser_version).and_return('100.0.0')
171
+ allow(chromedriver).to receive(:browser_version).and_return Gem::Version.new('100.0.0')
171
172
  msg = 'Unable to find latest point release version for 100.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>` '\
@@ -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(:browser_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
 
@@ -6,9 +6,7 @@ describe Webdrivers::EdgeFinder do
6
6
  let(:edge_finder) { described_class }
7
7
 
8
8
  before(:all) do # rubocop:disable RSpec/BeforeAfterAll
9
- # Skip these tests if version of selenium-webdriver being tested with doesn't
10
- # have Chromium based Edge support
11
- unless defined?(Selenium::WebDriver::EdgeChrome)
9
+ if Selenium::WebDriver::VERSION[0].to_i < 4
12
10
  skip "The current selenium-webdriver doesn't include Chromium based Edge support"
13
11
  end
14
12
  end
@@ -20,8 +18,8 @@ describe Webdrivers::EdgeFinder do
20
18
  end
21
19
 
22
20
  context 'when the user provides a path to the Edge binary' do
23
- it 'uses Selenium::WebDriver::EdgeChrome.path when it is defined' do
24
- Selenium::WebDriver::EdgeChrome.path = edge_finder.location
21
+ it 'uses Selenium::WebDriver::Edge.path when it is defined' do
22
+ Selenium::WebDriver::Edge.path = edge_finder.location
25
23
  locations = %i[win_location mac_location linux_location]
26
24
  allow(edge_finder).to receive_messages(locations)
27
25
 
@@ -29,8 +27,8 @@ describe Webdrivers::EdgeFinder do
29
27
  locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
30
28
  end
31
29
 
32
- it "uses ENV['WD_EDGE_CHROME_PATH'] when it is defined" do
33
- allow(ENV).to receive(:[]).with('WD_EDGE_CHROME_PATH').and_return(edge_finder.location)
30
+ it "uses ENV['WD_EDGE_PATH'] when it is defined" do
31
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return(edge_finder.location)
34
32
  locations = %i[win_location mac_location linux_location]
35
33
  allow(edge_finder).to receive_messages(locations)
36
34
 
@@ -38,11 +36,11 @@ describe Webdrivers::EdgeFinder do
38
36
  locations.each { |loc| expect(edge_finder).not_to have_received(loc) }
39
37
  end
40
38
 
41
- it 'uses Selenium::WebDriver::EdgeChrome.path over WD_EDGE_CHROME_PATH' do
42
- Selenium::WebDriver::EdgeChrome.path = edge_finder.location
43
- allow(ENV).to receive(:[]).with('WD_EDGE_CHROME_PATH').and_return('my_wd_chrome_path')
39
+ it 'uses Selenium::WebDriver::Edge.path over WD_EDGE_PATH' do
40
+ Selenium::WebDriver::Edge.path = edge_finder.location
41
+ allow(ENV).to receive(:[]).with('WD_EDGE_PATH').and_return('my_wd_chrome_path')
44
42
  expect(edge_finder.version).not_to be_nil
45
- expect(ENV).not_to have_received(:[]).with('WD_EDGE_CHROME_PATH')
43
+ expect(ENV).not_to have_received(:[]).with('WD_EDGE_PATH')
46
44
  end
47
45
  end
48
46
 
@@ -6,9 +6,7 @@ describe Webdrivers::Edgedriver do
6
6
  let(:edgedriver) { described_class }
7
7
 
8
8
  before(:all) do # rubocop:disable RSpec/BeforeAfterAll
9
- # Skip these tests if version of selenium-webdriver being tested with doesn't
10
- # have Chromium based Edge support
11
- unless defined?(Selenium::WebDriver::EdgeChrome)
9
+ if Selenium::WebDriver::VERSION[0].to_i < 4
12
10
  skip "The current selenium-webdriver doesn't include Chromium based Edge support"
13
11
  end
14
12
  end
@@ -114,15 +112,16 @@ describe Webdrivers::Edgedriver do
114
112
  end
115
113
  end
116
114
 
117
- it 'makes a network call if cached driver does not match the browser' do
115
+ it 'makes network calls if cached driver does not match the browser' do
118
116
  Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
119
- allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
117
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('71.0.3578.137')
118
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('73.0.3683.68')
120
119
  allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68'.encode('UTF-16'))
121
120
  allow(Webdrivers::System).to receive(:download)
122
121
 
123
122
  edgedriver.update
124
123
 
125
- expect(Webdrivers::Network).to have_received(:get).once
124
+ expect(Webdrivers::Network).to have_received(:get).twice
126
125
  end
127
126
 
128
127
  context 'when required version is 0' do
@@ -163,13 +162,13 @@ describe Webdrivers::Edgedriver do
163
162
 
164
163
  describe '#latest_version' do
165
164
  it 'returns the correct point release for a production version' do
166
- allow(edgedriver).to receive(:browser_version).and_return '77.0.207.0'
165
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
167
166
 
168
167
  expect(edgedriver.latest_version).to be_between(Gem::Version.new('77.0.207.0'), Gem::Version.new('78'))
169
168
  end
170
169
 
171
170
  it 'raises VersionError for beta version' do
172
- allow(edgedriver).to receive(:browser_version).and_return('100.0.0')
171
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('100.0.0')
173
172
  msg = 'Unable to find latest point release version for 100.0.0. '\
174
173
  'You appear to be using a non-production version of Edge. '\
175
174
  'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
@@ -196,28 +195,31 @@ describe Webdrivers::Edgedriver do
196
195
  end
197
196
 
198
197
  it 'creates cached file' do
199
- allow(edgedriver).to receive(:browser_version).and_return('77.0.207.0')
198
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
200
199
  allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
201
200
 
202
201
  edgedriver.latest_version
203
202
  expect(File.exist?("#{Webdrivers::System.install_dir}/msedgedriver.version")).to eq true
204
203
  end
205
204
 
206
- it 'does not make network call if cache is valid' do
205
+ it 'does not make network calls if cache is valid and driver exists' do
207
206
  allow(Webdrivers).to receive(:cache_time).and_return(3600)
208
- Webdrivers::System.cache_version('msedgedriver', '77.0.207.0')
207
+ Webdrivers::System.cache_version('msedgedriver', '82.0.445.0')
208
+ allow(edgedriver).to receive(:current_version).and_return Gem::Version.new('82.0.445.0')
209
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('82.0.445.0')
210
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
209
211
  allow(Webdrivers::Network).to receive(:get)
210
212
 
211
- expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
213
+ expect(edgedriver.latest_version).to eq Gem::Version.new('82.0.445.0')
212
214
 
213
215
  expect(Webdrivers::Network).not_to have_received(:get)
214
216
  end
215
217
 
216
- it 'makes a network call if cache is expired' do
218
+ it 'makes network calls if cache is expired' do
217
219
  Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
218
220
  allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
219
- allow(Webdrivers::System).to receive(:valid_cache?)
220
- allow(edgedriver).to receive(:browser_version).and_return('77.0.207.0')
221
+ allow(Webdrivers::System).to receive(:valid_cache?).and_return(false)
222
+ allow(edgedriver).to receive(:browser_version).and_return Gem::Version.new('77.0.207.0')
221
223
 
222
224
  expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
223
225
 
@@ -135,9 +135,10 @@ You can obtain a copy of the license at https://mozilla.org/MPL/2.0/"
135
135
  expect(File.exist?("#{Webdrivers::System.install_dir}/geckodriver.version")).to eq true
136
136
  end
137
137
 
138
- it 'does not make network call if cache is valid' do
138
+ it 'does not make network calls if cache is valid and driver exists' do
139
139
  allow(Webdrivers).to receive(:cache_time).and_return(3600)
140
140
  Webdrivers::System.cache_version('geckodriver', '0.23.0')
141
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
141
142
  allow(Webdrivers::Network).to receive(:get)
142
143
 
143
144
  expect(geckodriver.latest_version).to eq Gem::Version.new('0.23.0')
@@ -115,9 +115,10 @@ describe Webdrivers::IEdriver do
115
115
  expect(File.exist?("#{Webdrivers::System.install_dir}/IEDriverServer.version")).to eq true
116
116
  end
117
117
 
118
- it 'does not make network call if cache is valid' do
118
+ it 'does not make network calls if cache is valid and driver exists' do
119
119
  allow(Webdrivers).to receive(:cache_time).and_return(3600)
120
120
  Webdrivers::System.cache_version('IEDriverServer', '3.4.0')
121
+ allow(Webdrivers::System).to receive(:exists?).and_return(true)
121
122
  allow(Webdrivers::Network).to receive(:get)
122
123
 
123
124
  expect(iedriver.latest_version).to eq Gem::Version.new('3.4.0')
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::System do
6
+ describe '#wsl_v1?' do
7
+ subject { described_class.wsl_v1? }
8
+
9
+ before do
10
+ allow(described_class).to receive(:platform).and_return(platform)
11
+ allow(File).to receive(:open).with('/proc/version').and_return(StringIO.new(wsl_proc_version_contents))
12
+ end
13
+
14
+ let(:platform) { 'linux' }
15
+ let(:wsl_proc_version_contents) { '' }
16
+
17
+ context 'when the current platform is linux and WSL version is 1' do
18
+ let(:wsl_proc_version_contents) do
19
+ 'Linux version 4.4.0-18362-Microsoft'\
20
+ '(Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) )'\
21
+ '#836-Microsoft Mon May 05 16:04:00 PST 2020'
22
+ end
23
+
24
+ it { is_expected.to eq true }
25
+ end
26
+
27
+ context 'when the current platform is linux and WSL version is 2' do
28
+ let(:wsl_proc_version_contents) do
29
+ 'Linux version 4.19.84-microsoft-standard '\
30
+ '(oe-user@oe-host) (gcc version 8.2.0 (GCC)) '\
31
+ '#1 SMP Wed Nov 13 11:44:37 UTC 2019'
32
+ end
33
+
34
+ it { is_expected.to eq false }
35
+ end
36
+
37
+ context 'when the current platform is mac' do
38
+ let(:platform) { 'mac' }
39
+
40
+ it { is_expected.to eq false }
41
+ end
42
+ end
43
+
44
+ describe '#to_win32_path' do
45
+ before { allow(described_class).to receive(:call).and_return("C:\\path\\to\\folder\n") }
46
+
47
+ it 'uses wslpath' do
48
+ described_class.to_win32_path '/c/path/to/folder'
49
+
50
+ expect(described_class).to have_received(:call).with('wslpath -w \'/c/path/to/folder\'')
51
+ end
52
+
53
+ it 'removes the trailing newline' do
54
+ expect(described_class.to_win32_path('/c/path/to/folder')).not_to end_with('\n')
55
+ end
56
+
57
+ context 'when the path is already in Windows format' do
58
+ it 'returns early' do
59
+ expect(described_class.to_win32_path('D:\\')).to eq 'D:\\'
60
+
61
+ expect(described_class).not_to have_received(:call)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#to_wsl_path' do
67
+ before { allow(described_class).to receive(:call).and_return("/c/path/to/folder\n") }
68
+
69
+ it 'uses wslpath' do
70
+ described_class.to_wsl_path 'C:\\path\\to\\folder'
71
+
72
+ expect(described_class).to have_received(:call).with('wslpath -u \'C:\\path\\to\\folder\'')
73
+ end
74
+
75
+ it 'removes the trailing newline' do
76
+ expect(described_class.to_wsl_path('/c/path/to/folder')).not_to end_with('\n')
77
+ end
78
+ end
79
+ end