webdrivers 2.3.2 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +204 -56
  3. data/LICENSE.txt +2 -2
  4. data/README.md +253 -17
  5. data/lib/webdrivers/Rakefile +6 -0
  6. data/lib/webdrivers/chrome_finder.rb +127 -0
  7. data/lib/webdrivers/chromedriver.rb +131 -23
  8. data/lib/webdrivers/common.rb +145 -70
  9. data/lib/webdrivers/edge_finder.rb +99 -0
  10. data/lib/webdrivers/edgedriver.rb +87 -17
  11. data/lib/webdrivers/geckodriver.rb +46 -25
  12. data/lib/webdrivers/iedriver.rb +51 -18
  13. data/lib/webdrivers/logger.rb +111 -0
  14. data/lib/webdrivers/network.rb +63 -0
  15. data/lib/webdrivers/railtie.rb +15 -0
  16. data/lib/webdrivers/system.rb +197 -0
  17. data/lib/webdrivers/tasks/chromedriver.rake +44 -0
  18. data/lib/webdrivers/tasks/edgedriver.rake +44 -0
  19. data/lib/webdrivers/tasks/geckodriver.rake +44 -0
  20. data/lib/webdrivers/tasks/iedriver.rake +44 -0
  21. data/lib/webdrivers/version.rb +5 -0
  22. data/lib/webdrivers.rb +7 -9
  23. data/spec/spec_helper.rb +18 -2
  24. data/spec/webdrivers/chrome_finder_spec.rb +103 -0
  25. data/spec/webdrivers/chromedriver_spec.rb +276 -0
  26. data/spec/webdrivers/edge_finder_spec.rb +58 -0
  27. data/spec/webdrivers/edgedriver_spec.rb +279 -0
  28. data/spec/webdrivers/geckodriver_spec.rb +211 -0
  29. data/spec/webdrivers/i_edriver_spec.rb +197 -0
  30. data/spec/webdrivers/system_spec.rb +79 -0
  31. data/spec/webdrivers/webdrivers_spec.rb +80 -0
  32. data/spec/webdrivers_proxy_support_spec.rb +53 -0
  33. metadata +157 -43
  34. data/.gitignore +0 -6
  35. data/.travis.yml +0 -3
  36. data/Gemfile +0 -4
  37. data/Rakefile +0 -6
  38. data/bin/IEDriverServer +0 -5
  39. data/bin/MicrosoftWebDriver +0 -5
  40. data/bin/chromedriver +0 -5
  41. data/bin/geckodriver +0 -5
  42. data/bin/phantomjs +0 -5
  43. data/lib/webdrivers/phantomjs.rb +0 -40
  44. data/spec/chromedriver_spec.rb +0 -36
  45. data/spec/edgedriver_spec.rb +0 -24
  46. data/spec/geckodriver_spec.rb +0 -36
  47. data/spec/iedriver_spec.rb +0 -27
  48. data/spec/phantomjs_spec.rb +0 -36
  49. data/webdrivers.gemspec +0 -24
@@ -0,0 +1,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
- require 'nokogiri'
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
- def file_name
8
- platform == "win" ? "chromedriver.exe" : "chromedriver"
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
- def current_version
12
- return nil unless File.exists?(binary_path)
13
- %x(#{binary_path} --version).match(/ChromeDriver (\d\.\d+)/)[1]
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 newest_version
17
- padded = downloads.keys.each_with_object({}) do |version, hash|
18
- matched = version.match(/^(\d+)\.(\d+)$/)
19
- minor = sprintf '%02d', matched[2]
20
- hash["#{matched[1]}.#{minor}"] = version
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
- padded.keys.sort.last
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 downloads
26
- doc = Nokogiri::XML.parse(OpenURI.open_uri(base_url))
27
- items = doc.css("Contents Key").collect(&:text)
28
- items.select! { |item| item.include?(platform) }
29
- items.each_with_object({}) do |item, hash|
30
- hash[item[/^[^\/]+/]] = "#{base_url}/#{item}"
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
- def base_url
35
- 'http://chromedriver.storage.googleapis.com'
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
- end
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 }
@@ -1,100 +1,175 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems/package'
2
- require 'zip'
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 Common
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
- def install *args
9
- download
10
- exec binary_path, *args
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
- def download
14
- return if File.exists?(binary_path) && !internet_connection?
15
- raise StandardError, "Unable to Reach #{base_url}" unless internet_connection?
16
- return if newest_version == current_version
17
-
18
- url = download_url
19
- filename = File.basename url
20
- Dir.chdir platform_install_dir do
21
- FileUtils.rm_f filename
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
- raise "Could not unzip #{filename} to get #{binary_path}" unless File.exists? binary_path
32
- FileUtils.chmod "ugo+rx", binary_path
96
+
97
+ remove
98
+ System.download(download_url, driver_path)
33
99
  end
34
100
 
35
- def decompress_file(filename)
36
- case filename
37
- when /tar\.gz$/
38
- untargz_file(filename)
39
- when /\.zip$/
40
- unzip_file(filename)
41
- end
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
- def untargz_file(filename)
45
- tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(filename))
46
- tar_extract.rewind
119
+ private
47
120
 
48
- ucf = File.open(file_name, "w+")
49
- tar_extract.each { |entry| ucf << entry.read }
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 unzip_file(filename)
55
- Zip::ZipFile.open("#{Dir.pwd}/#{filename}") do |zip_file|
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 download_url(version = nil)
67
- downloads[version || newest_version]
129
+ def exists?
130
+ System.exists? driver_path
68
131
  end
69
132
 
70
- def binary_path
71
- File.join platform_install_dir, file_name
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 platform_install_dir
75
- File.join(install_dir, platform).tap { |dir| FileUtils.mkdir_p dir }
139
+ def sufficient_binary?
140
+ exists?
76
141
  end
77
142
 
78
- def install_dir
79
- File.expand_path(File.join(ENV['HOME'], ".webdrivers")).tap { |dir| FileUtils.mkdir_p dir}
143
+ def normalize_version(version)
144
+ Gem::Version.new(version.to_s)
80
145
  end
81
146
 
82
- def platform
83
- cfg = RbConfig::CONFIG
84
- case cfg['host_os']
85
- when /linux/ then
86
- cfg['host_cpu'] =~ /x86_64|amd64/ ? "linux64" : "linux32"
87
- when /darwin/ then "mac"
88
- else "win"
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
- def internet_connection?
93
- true #if open(base_url)
94
- rescue
95
- false
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