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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +204 -56
- data/LICENSE.txt +2 -2
- data/README.md +253 -17
- data/lib/webdrivers/Rakefile +6 -0
- data/lib/webdrivers/chrome_finder.rb +127 -0
- data/lib/webdrivers/chromedriver.rb +131 -23
- data/lib/webdrivers/common.rb +145 -70
- data/lib/webdrivers/edge_finder.rb +99 -0
- data/lib/webdrivers/edgedriver.rb +87 -17
- data/lib/webdrivers/geckodriver.rb +46 -25
- data/lib/webdrivers/iedriver.rb +51 -18
- data/lib/webdrivers/logger.rb +111 -0
- data/lib/webdrivers/network.rb +63 -0
- data/lib/webdrivers/railtie.rb +15 -0
- data/lib/webdrivers/system.rb +197 -0
- data/lib/webdrivers/tasks/chromedriver.rake +44 -0
- data/lib/webdrivers/tasks/edgedriver.rake +44 -0
- data/lib/webdrivers/tasks/geckodriver.rake +44 -0
- data/lib/webdrivers/tasks/iedriver.rake +44 -0
- data/lib/webdrivers/version.rb +5 -0
- data/lib/webdrivers.rb +7 -9
- data/spec/spec_helper.rb +18 -2
- data/spec/webdrivers/chrome_finder_spec.rb +103 -0
- data/spec/webdrivers/chromedriver_spec.rb +276 -0
- data/spec/webdrivers/edge_finder_spec.rb +58 -0
- data/spec/webdrivers/edgedriver_spec.rb +279 -0
- data/spec/webdrivers/geckodriver_spec.rb +211 -0
- data/spec/webdrivers/i_edriver_spec.rb +197 -0
- data/spec/webdrivers/system_spec.rb +79 -0
- data/spec/webdrivers/webdrivers_spec.rb +80 -0
- data/spec/webdrivers_proxy_support_spec.rb +53 -0
- metadata +157 -43
- data/.gitignore +0 -6
- data/.travis.yml +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -6
- data/bin/IEDriverServer +0 -5
- data/bin/MicrosoftWebDriver +0 -5
- data/bin/chromedriver +0 -5
- data/bin/geckodriver +0 -5
- data/bin/phantomjs +0 -5
- data/lib/webdrivers/phantomjs.rb +0 -40
- data/spec/chromedriver_spec.rb +0 -36
- data/spec/edgedriver_spec.rb +0 -24
- data/spec/geckodriver_spec.rb +0 -36
- data/spec/iedriver_spec.rb +0 -27
- data/spec/phantomjs_spec.rb +0 -36
- data/webdrivers.gemspec +0 -24
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Webdrivers
|
4
|
+
#
|
5
|
+
# @api private
|
6
|
+
#
|
7
|
+
class ChromeFinder
|
8
|
+
class << self
|
9
|
+
def version
|
10
|
+
version = send("#{System.platform}_version", location)
|
11
|
+
raise VersionError, 'Failed to find Chrome version.' if version.nil? || version.empty?
|
12
|
+
|
13
|
+
Webdrivers.logger.debug "Browser version: #{version}"
|
14
|
+
version[/\d+\.\d+\.\d+\.\d+/] # Google Chrome 73.0.3683.75 -> 73.0.3683.75
|
15
|
+
end
|
16
|
+
|
17
|
+
def location
|
18
|
+
chrome_bin = user_defined_location || send("#{System.platform}_location")
|
19
|
+
return chrome_bin unless chrome_bin.nil?
|
20
|
+
|
21
|
+
raise BrowserNotFound, 'Failed to find Chrome binary.'
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def user_defined_location
|
27
|
+
if Selenium::WebDriver::Chrome.path
|
28
|
+
Webdrivers.logger.debug "Selenium::WebDriver::Chrome.path: #{Selenium::WebDriver::Chrome.path}"
|
29
|
+
return Selenium::WebDriver::Chrome.path
|
30
|
+
end
|
31
|
+
|
32
|
+
return if ENV['WD_CHROME_PATH'].nil?
|
33
|
+
|
34
|
+
Webdrivers.logger.debug "WD_CHROME_PATH: #{ENV['WD_CHROME_PATH']}"
|
35
|
+
ENV['WD_CHROME_PATH']
|
36
|
+
end
|
37
|
+
|
38
|
+
def win_location
|
39
|
+
envs = %w[LOCALAPPDATA PROGRAMFILES PROGRAMFILES(X86)]
|
40
|
+
directories = ['\\Google\\Chrome\\Application', '\\Chromium\\Application']
|
41
|
+
file = 'chrome.exe'
|
42
|
+
|
43
|
+
directories.each do |dir|
|
44
|
+
envs.each do |root|
|
45
|
+
option = "#{ENV[root]}\\#{dir}\\#{file}"
|
46
|
+
return option if File.exist?(option)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def wsl_location
|
54
|
+
_, drive, user = ENV['PATH'].match(%r{/([a-z])/Users/([^/:]+)/AppData/}).to_a
|
55
|
+
|
56
|
+
roots = [
|
57
|
+
"#{drive}:\\Users\\#{user}\\AppData\\Local",
|
58
|
+
"#{drive}:\\Program Files (x86)",
|
59
|
+
"#{drive}:\\Program Files"
|
60
|
+
]
|
61
|
+
|
62
|
+
directories = %w[Google\\Chrome\\Application Chromium\\Application]
|
63
|
+
file = 'chrome.exe'
|
64
|
+
|
65
|
+
directories.each do |dir|
|
66
|
+
roots.each do |root|
|
67
|
+
option = System.to_wsl_path("#{root}\\#{dir}\\#{file}")
|
68
|
+
return option if File.exist?(option)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def mac_location
|
76
|
+
directories = ['', File.expand_path('~')]
|
77
|
+
files = ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
78
|
+
'/Applications/Chromium.app/Contents/MacOS/Chromium']
|
79
|
+
|
80
|
+
directories.each do |dir|
|
81
|
+
files.each do |file|
|
82
|
+
option = "#{dir}/#{file}"
|
83
|
+
return option if File.exist?(option)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def linux_location
|
91
|
+
return wsl_location if System.wsl_v1?
|
92
|
+
|
93
|
+
directories = %w[/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin /opt/google/chrome]
|
94
|
+
files = %w[google-chrome chrome chromium chromium-browser]
|
95
|
+
|
96
|
+
directories.each do |dir|
|
97
|
+
files.each do |file|
|
98
|
+
option = "#{dir}/#{file}"
|
99
|
+
return option if File.exist?(option)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def win_version(location)
|
107
|
+
System.call("pwsh.exe -command \"(Get-ItemProperty '#{location}').VersionInfo.ProductVersion\"")&.strip
|
108
|
+
rescue StandardError
|
109
|
+
System.call("powershell.exe \"(Get-ItemProperty '#{location}').VersionInfo.ProductVersion\"")&.strip
|
110
|
+
end
|
111
|
+
|
112
|
+
def wsl_version(location)
|
113
|
+
win_version(System.to_win32_path(location))
|
114
|
+
end
|
115
|
+
|
116
|
+
def linux_version(location)
|
117
|
+
return wsl_version(location) if System.wsl_v1?
|
118
|
+
|
119
|
+
System.call(location, '--product-version')&.strip
|
120
|
+
end
|
121
|
+
|
122
|
+
def mac_version(location)
|
123
|
+
System.call(location, '--version')&.strip
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -1,41 +1,149 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'webdrivers/common'
|
5
|
+
require 'webdrivers/chrome_finder'
|
2
6
|
|
3
7
|
module Webdrivers
|
4
8
|
class Chromedriver < Common
|
5
|
-
|
6
9
|
class << self
|
7
|
-
|
8
|
-
|
10
|
+
#
|
11
|
+
# Returns current chromedriver version.
|
12
|
+
#
|
13
|
+
# @return [Gem::Version]
|
14
|
+
def current_version
|
15
|
+
Webdrivers.logger.debug 'Checking current version'
|
16
|
+
return nil unless exists?
|
17
|
+
|
18
|
+
version = binary_version
|
19
|
+
return nil if version.nil?
|
20
|
+
|
21
|
+
# Matches 2.46, 2.46.628411 and 73.0.3683.75
|
22
|
+
normalize_version version[/\d+\.\d+(\.\d+)?(\.\d+)?/]
|
9
23
|
end
|
10
24
|
|
11
|
-
|
12
|
-
|
13
|
-
|
25
|
+
#
|
26
|
+
# Returns latest available chromedriver version.
|
27
|
+
#
|
28
|
+
# @return [Gem::Version]
|
29
|
+
def latest_version
|
30
|
+
@latest_version ||= begin
|
31
|
+
# Versions before 70 do not have a LATEST_RELEASE file
|
32
|
+
return normalize_version('2.41') if browser_build_version < normalize_version('70')
|
33
|
+
|
34
|
+
# Cache check
|
35
|
+
# Cached version should exist and be compatible with the current browser version.
|
36
|
+
# Otherwise, fetch the latest compatible driver.
|
37
|
+
latest_applicable = with_cache(file_name,
|
38
|
+
current_build_version,
|
39
|
+
browser_build_version) { latest_point_release(browser_build_version) }
|
40
|
+
|
41
|
+
Webdrivers.logger.debug "Latest version available: #{latest_applicable}"
|
42
|
+
normalize_version(latest_applicable)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Returns currently installed Chrome/Chromium version.
|
48
|
+
#
|
49
|
+
# @return [Gem::Version]
|
50
|
+
def browser_version
|
51
|
+
normalize_version ChromeFinder.version
|
52
|
+
end
|
53
|
+
alias chrome_version browser_version
|
54
|
+
|
55
|
+
#
|
56
|
+
# Returns url with domain for calls to get this driver.
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
def base_url
|
60
|
+
'https://chromedriver.storage.googleapis.com'
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def latest_point_release(version)
|
66
|
+
normalize_version(Network.get(URI.join(base_url, "LATEST_RELEASE_#{version}")))
|
67
|
+
rescue NetworkError
|
68
|
+
msg = "Unable to find latest point release version for #{version}."
|
69
|
+
msg = begin
|
70
|
+
latest_release = normalize_version(Network.get(URI.join(base_url, 'LATEST_RELEASE')))
|
71
|
+
if version > latest_release
|
72
|
+
"#{msg} You appear to be using a non-production version of Chrome."
|
73
|
+
else
|
74
|
+
msg
|
75
|
+
end
|
76
|
+
rescue NetworkError
|
77
|
+
"#{msg} A network issue is preventing determination of latest chromedriver release."
|
78
|
+
end
|
79
|
+
|
80
|
+
msg = "#{msg} Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` "\
|
81
|
+
'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
|
82
|
+
Webdrivers.logger.debug msg
|
83
|
+
raise VersionError, msg
|
14
84
|
end
|
15
85
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
86
|
+
def file_name
|
87
|
+
System.platform == 'win' || System.wsl_v1? ? 'chromedriver.exe' : 'chromedriver'
|
88
|
+
end
|
89
|
+
|
90
|
+
def apple_m1_compatible?(driver_version)
|
91
|
+
if System.apple_m1_architecture? && driver_version >= normalize_version('87.0.4280.88')
|
92
|
+
Webdrivers.logger.debug 'chromedriver version is Apple M1 compatible.'
|
93
|
+
return true
|
21
94
|
end
|
22
|
-
|
95
|
+
|
96
|
+
Webdrivers.logger.debug 'chromedriver version is NOT Apple M1 compatible. Required >= 87.0.4280.88'
|
97
|
+
false
|
23
98
|
end
|
24
99
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
100
|
+
def direct_url(driver_version)
|
101
|
+
"#{base_url}/#{driver_version}/chromedriver_#{driver_filename(driver_version)}.zip"
|
102
|
+
end
|
103
|
+
|
104
|
+
def driver_filename(driver_version)
|
105
|
+
if System.platform == 'win' || System.wsl_v1?
|
106
|
+
'win32'
|
107
|
+
elsif System.platform == 'linux'
|
108
|
+
'linux64'
|
109
|
+
elsif System.platform == 'mac'
|
110
|
+
apple_arch = apple_m1_compatible?(driver_version) ? '_m1' : ''
|
111
|
+
"mac64#{apple_arch}"
|
112
|
+
else
|
113
|
+
raise 'Failed to determine driver filename to download for your OS.'
|
31
114
|
end
|
32
115
|
end
|
33
116
|
|
34
|
-
|
35
|
-
|
117
|
+
# Returns major.minor.build version from the currently installed chromedriver version
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# 73.0.3683.68 (major.minor.build.patch) -> 73.0.3683 (major.minor.build)
|
121
|
+
def current_build_version
|
122
|
+
build_ver = if current_version.nil? # Driver not found
|
123
|
+
nil
|
124
|
+
else
|
125
|
+
current_version.segments[0..2].join('.')
|
126
|
+
end
|
127
|
+
normalize_version(build_ver)
|
36
128
|
end
|
37
129
|
|
38
|
-
|
130
|
+
# Returns major.minor.build version from the currently installed Chrome version
|
131
|
+
#
|
132
|
+
# @example
|
133
|
+
# 73.0.3683.75 (major.minor.build.patch) -> 73.0.3683 (major.minor.build)
|
134
|
+
def browser_build_version
|
135
|
+
normalize_version(browser_version.segments[0..2].join('.'))
|
136
|
+
end
|
137
|
+
alias chrome_build_version browser_build_version
|
39
138
|
|
139
|
+
# Returns true if an executable driver binary exists
|
140
|
+
# and its build version matches the browser build version
|
141
|
+
def sufficient_binary?
|
142
|
+
super && current_version && (current_version < normalize_version('70.0.3538') ||
|
143
|
+
current_build_version == browser_build_version)
|
144
|
+
end
|
145
|
+
end
|
40
146
|
end
|
41
|
-
end
|
147
|
+
end
|
148
|
+
|
149
|
+
::Selenium::WebDriver::Chrome::Service.driver_path = proc { ::Webdrivers::Chromedriver.update }
|
data/lib/webdrivers/common.rb
CHANGED
@@ -1,100 +1,175 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubygems/package'
|
2
|
-
require '
|
4
|
+
require 'webdrivers/logger'
|
5
|
+
require 'webdrivers/network'
|
6
|
+
require 'webdrivers/system'
|
7
|
+
require 'selenium-webdriver'
|
8
|
+
require 'webdrivers/version'
|
3
9
|
|
4
10
|
module Webdrivers
|
5
|
-
class
|
11
|
+
class ConnectionError < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
class VersionError < StandardError
|
15
|
+
end
|
16
|
+
|
17
|
+
class NetworkError < StandardError
|
18
|
+
end
|
19
|
+
|
20
|
+
class BrowserNotFound < StandardError
|
21
|
+
end
|
22
|
+
|
23
|
+
DEFAULT_CACHE_TIME = 86_400 # 24 hours
|
24
|
+
DEFAULT_INSTALL_DIR = File.expand_path('~/.webdrivers')
|
25
|
+
|
26
|
+
class << self
|
27
|
+
attr_accessor :proxy_addr, :proxy_port, :proxy_user, :proxy_pass
|
28
|
+
attr_writer :install_dir, :cache_time
|
29
|
+
|
30
|
+
#
|
31
|
+
# Returns the amount of time (Seconds) the gem waits between two update checks.
|
32
|
+
# @note Value from the environment variable "WD_CACHE_TIME" takes precedence over Webdrivers.cache_time. If neither
|
33
|
+
# are set, it defaults to 86,400 Seconds (24 hours).
|
34
|
+
#
|
35
|
+
def cache_time
|
36
|
+
@cache_time ||= (ENV['WD_CACHE_TIME'] || DEFAULT_CACHE_TIME)
|
37
|
+
@cache_time.to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Returns the install (download) directory path for the drivers.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
def install_dir
|
45
|
+
@install_dir ||= ENV['WD_INSTALL_DIR'] || DEFAULT_INSTALL_DIR
|
46
|
+
end
|
47
|
+
|
48
|
+
def logger
|
49
|
+
@logger ||= Webdrivers::Logger.new
|
50
|
+
end
|
6
51
|
|
52
|
+
#
|
53
|
+
# Provides a convenient way to configure the gem.
|
54
|
+
#
|
55
|
+
# @example Configure proxy and cache_time
|
56
|
+
# Webdrivers.configure do |config|
|
57
|
+
# config.proxy_addr = 'myproxy_address.com'
|
58
|
+
# config.proxy_port = '8080'
|
59
|
+
# config.proxy_user = 'username'
|
60
|
+
# config.proxy_pass = 'password'
|
61
|
+
# config.cache_time = 604_800 # 7 days
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
def configure
|
65
|
+
yield self
|
66
|
+
end
|
67
|
+
|
68
|
+
def net_http_ssl_fix
|
69
|
+
raise 'Webdrivers.net_http_ssl_fix is no longer available.' \
|
70
|
+
' Please see https://github.com/titusfortner/webdrivers#ssl_connect-errors.'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Common
|
7
75
|
class << self
|
8
|
-
|
9
|
-
|
10
|
-
|
76
|
+
attr_writer :required_version
|
77
|
+
|
78
|
+
#
|
79
|
+
# Returns the user defined required version.
|
80
|
+
#
|
81
|
+
# @return [Gem::Version]
|
82
|
+
def required_version
|
83
|
+
normalize_version(@required_version ||= nil)
|
11
84
|
end
|
12
85
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
File.open(filename, "wb") do |saved_file|
|
23
|
-
URI.parse(url).open("rb") do |read_file|
|
24
|
-
saved_file.write(read_file.read)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
raise "Could not download #{url}" unless File.exists? filename
|
28
|
-
dcf = decompress_file(filename)
|
29
|
-
extract_file(dcf) if respond_to? :extract_file
|
86
|
+
#
|
87
|
+
# Triggers an update check.
|
88
|
+
#
|
89
|
+
# @return [String] Path to the driver binary.
|
90
|
+
def update
|
91
|
+
if correct_binary?
|
92
|
+
msg = required_version != EMPTY_VERSION ? 'The required webdriver version' : 'A working webdriver version'
|
93
|
+
Webdrivers.logger.debug "#{msg} is already on the system"
|
94
|
+
return driver_path
|
30
95
|
end
|
31
|
-
|
32
|
-
|
96
|
+
|
97
|
+
remove
|
98
|
+
System.download(download_url, driver_path)
|
33
99
|
end
|
34
100
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
101
|
+
#
|
102
|
+
# Deletes the existing driver binary.
|
103
|
+
#
|
104
|
+
def remove
|
105
|
+
@download_url = nil
|
106
|
+
@latest_version = nil
|
107
|
+
System.delete "#{System.install_dir}/#{file_name.gsub('.exe', '')}.version"
|
108
|
+
System.delete driver_path
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Returns path to the driver binary.
|
113
|
+
#
|
114
|
+
# @return [String]
|
115
|
+
def driver_path
|
116
|
+
File.absolute_path File.join(System.install_dir, file_name)
|
42
117
|
end
|
43
118
|
|
44
|
-
|
45
|
-
tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(filename))
|
46
|
-
tar_extract.rewind
|
119
|
+
private
|
47
120
|
|
48
|
-
|
49
|
-
|
50
|
-
ucf.close
|
51
|
-
File.basename ucf
|
121
|
+
def download_version
|
122
|
+
required_version == EMPTY_VERSION ? latest_version : required_version
|
52
123
|
end
|
53
124
|
|
54
|
-
def
|
55
|
-
|
56
|
-
zip_file.each do |f|
|
57
|
-
@top_path ||= f.name
|
58
|
-
f_path = File.join(Dir.pwd, f.name)
|
59
|
-
FileUtils.mkdir_p(File.dirname(f_path))
|
60
|
-
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
@top_path
|
125
|
+
def download_url
|
126
|
+
@download_url ||= direct_url(download_version).tap { |url| Webdrivers.logger.debug "#{file_name} URL: #{url}" }
|
64
127
|
end
|
65
128
|
|
66
|
-
def
|
67
|
-
|
129
|
+
def exists?
|
130
|
+
System.exists? driver_path
|
68
131
|
end
|
69
132
|
|
70
|
-
def
|
71
|
-
|
133
|
+
def correct_binary?
|
134
|
+
current_version == download_version
|
135
|
+
rescue ConnectionError, VersionError
|
136
|
+
driver_path if sufficient_binary?
|
72
137
|
end
|
73
138
|
|
74
|
-
def
|
75
|
-
|
139
|
+
def sufficient_binary?
|
140
|
+
exists?
|
76
141
|
end
|
77
142
|
|
78
|
-
def
|
79
|
-
|
143
|
+
def normalize_version(version)
|
144
|
+
Gem::Version.new(version.to_s)
|
80
145
|
end
|
81
146
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
147
|
+
def binary_version
|
148
|
+
version = System.call(driver_path, '--version')
|
149
|
+
Webdrivers.logger.debug "Current version of #{driver_path} is #{version}"
|
150
|
+
version
|
151
|
+
rescue Errno::ENOENT
|
152
|
+
Webdrivers.logger.debug "No Such File or Directory: #{driver_path}"
|
153
|
+
nil
|
90
154
|
end
|
91
155
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
156
|
+
# Returns cached driver version if cache is still valid and the driver binary exists.
|
157
|
+
# Otherwise caches the given version (typically the latest available)
|
158
|
+
# In case of Chrome, it also verifies that the driver build and browser build versions are compatible.
|
159
|
+
# Example usage: lib/webdrivers/chromedriver.rb:34
|
160
|
+
def with_cache(file_name, driver_build = nil, browser_build = nil)
|
161
|
+
if System.valid_cache?(file_name) && exists? && (driver_build == browser_build)
|
162
|
+
cached_version = System.cached_version(file_name)
|
163
|
+
Webdrivers.logger.debug "using cached version as latest: #{cached_version}"
|
164
|
+
normalize_version cached_version
|
165
|
+
else
|
166
|
+
version = yield
|
167
|
+
System.cache_version(file_name, version)
|
168
|
+
normalize_version version
|
169
|
+
end
|
96
170
|
end
|
97
|
-
end
|
98
171
|
|
172
|
+
EMPTY_VERSION = Gem::Version.new('')
|
173
|
+
end
|
99
174
|
end
|
100
|
-
end
|
175
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Webdrivers
|
4
|
+
#
|
5
|
+
# @api private
|
6
|
+
#
|
7
|
+
class EdgeFinder
|
8
|
+
class << self
|
9
|
+
def version
|
10
|
+
version = send("#{System.platform}_version", location)
|
11
|
+
raise VersionError, 'Failed to find Edge version.' if version.nil? || version.empty?
|
12
|
+
|
13
|
+
Webdrivers.logger.debug "Browser version: #{version}"
|
14
|
+
version[/\d+\.\d+\.\d+\.\d+/] # Microsoft Edge 73.0.3683.75 -> 73.0.3683.75
|
15
|
+
end
|
16
|
+
|
17
|
+
def location
|
18
|
+
edge_bin = user_defined_location || send("#{System.platform}_location")
|
19
|
+
return edge_bin unless edge_bin.nil?
|
20
|
+
|
21
|
+
raise BrowserNotFound, 'Failed to find Edge binary.'
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def user_defined_location
|
27
|
+
if Selenium::WebDriver::Edge.path
|
28
|
+
Webdrivers.logger.debug "Selenium::WebDriver::Edge.path: #{Selenium::WebDriver::Edge.path}"
|
29
|
+
return Selenium::WebDriver::Edge.path
|
30
|
+
end
|
31
|
+
|
32
|
+
return if ENV['WD_EDGE_PATH'].nil?
|
33
|
+
|
34
|
+
Webdrivers.logger.debug "WD_EDGE_PATH: #{ENV['WD_EDGE_PATH']}"
|
35
|
+
ENV['WD_EDGE_PATH']
|
36
|
+
end
|
37
|
+
|
38
|
+
def win_location
|
39
|
+
envs = %w[LOCALAPPDATA PROGRAMFILES PROGRAMFILES(X86)]
|
40
|
+
directories = ['\\Microsoft\\Edge\\Application',
|
41
|
+
'\\Microsoft\\Edge Beta\\Application',
|
42
|
+
'\\Microsoft\\Edge Dev\\Application',
|
43
|
+
'\\Microsoft\\Edge SxS\\Application']
|
44
|
+
file = 'msedge.exe'
|
45
|
+
|
46
|
+
directories.each do |dir|
|
47
|
+
envs.each do |root|
|
48
|
+
option = "#{ENV[root]}\\#{dir}\\#{file}"
|
49
|
+
return option if File.exist?(option)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def mac_location
|
56
|
+
directories = ['', File.expand_path('~')]
|
57
|
+
files = ['/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
|
58
|
+
'/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta',
|
59
|
+
'/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev',
|
60
|
+
'/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary']
|
61
|
+
|
62
|
+
directories.each do |dir|
|
63
|
+
files.each do |file|
|
64
|
+
option = "#{dir}/#{file}"
|
65
|
+
return option if File.exist?(option)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def linux_location
|
72
|
+
# directories = %w[/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin /opt/google/chrome]
|
73
|
+
# files = %w[microsoft-edge] # Based on Microsoft Edge 89.0.760.0 dev
|
74
|
+
#
|
75
|
+
# directories.each do |dir|
|
76
|
+
# files.each do |file|
|
77
|
+
# option = "#{dir}/#{file}"
|
78
|
+
# return option if File.exist?(option)
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# nil
|
83
|
+
raise 'Default location not yet known'
|
84
|
+
end
|
85
|
+
|
86
|
+
def win_version(location)
|
87
|
+
System.call("powershell (Get-ItemProperty '#{location}').VersionInfo.ProductVersion")&.strip
|
88
|
+
end
|
89
|
+
|
90
|
+
def linux_version(location)
|
91
|
+
System.call(location, '--product-version')&.strip
|
92
|
+
end
|
93
|
+
|
94
|
+
def mac_version(location)
|
95
|
+
System.call(location, '--version')&.strip
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|