webdrivers 4.0.1 → 4.1.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 +4 -4
- data/.github/ISSUE_TEMPLATE.md +16 -14
- data/.gitignore +8 -7
- data/.travis.yml +40 -24
- data/CHANGELOG.md +14 -1
- data/LICENSE.txt +23 -23
- data/README.md +31 -22
- data/appveyor.yml +9 -5
- data/gemfiles/Gemfile.edge +7 -0
- data/lib/webdrivers.rb +1 -0
- data/lib/webdrivers/chrome_finder.rb +26 -14
- data/lib/webdrivers/chromedriver.rb +3 -2
- data/lib/webdrivers/common.rb +8 -6
- data/lib/webdrivers/edge_finder.rb +82 -0
- data/lib/webdrivers/edgedriver.rb +106 -0
- data/lib/webdrivers/system.rb +17 -17
- data/lib/webdrivers/tasks/chromedriver.rake +0 -2
- data/lib/webdrivers/tasks/edgedriver.rake +44 -0
- data/lib/webdrivers/tasks/geckodriver.rake +0 -2
- data/lib/webdrivers/tasks/iedriver.rake +0 -2
- data/lib/webdrivers/version.rb +1 -1
- data/spec/webdrivers/chrome_finder_spec.rb +44 -0
- data/spec/webdrivers/chromedriver_spec.rb +21 -10
- data/spec/webdrivers/edgedriver_spec.rb +276 -0
- data/spec/webdrivers/geckodriver_spec.rb +2 -2
- data/spec/webdrivers/i_edriver_spec.rb +2 -2
- data/spec/webdrivers/webdrivers_spec.rb +17 -5
- data/support/install_msedge.ps1 +17 -0
- data/webdrivers.gemspec +1 -0
- metadata +23 -2
@@ -42,9 +42,10 @@ module Webdrivers
|
|
42
42
|
# Returns currently installed Chrome/Chromium version.
|
43
43
|
#
|
44
44
|
# @return [Gem::Version]
|
45
|
-
def
|
45
|
+
def browser_version
|
46
46
|
normalize_version ChromeFinder.version
|
47
47
|
end
|
48
|
+
alias chrome_version browser_version
|
48
49
|
|
49
50
|
#
|
50
51
|
# Returns url with domain for calls to get this driver.
|
@@ -102,7 +103,7 @@ module Webdrivers
|
|
102
103
|
# @example
|
103
104
|
# 73.0.3683.75 -> 73.0.3683
|
104
105
|
def release_version
|
105
|
-
chrome = normalize_version(
|
106
|
+
chrome = normalize_version(browser_version)
|
106
107
|
normalize_version(chrome.segments[0..2].join('.'))
|
107
108
|
end
|
108
109
|
|
data/lib/webdrivers/common.rb
CHANGED
@@ -19,6 +19,7 @@ module Webdrivers
|
|
19
19
|
end
|
20
20
|
|
21
21
|
DEFAULT_CACHE_TIME = 86_400 # 24 hours
|
22
|
+
DEFAULT_INSTALL_DIR = File.expand_path(File.join(ENV['HOME'], '.webdrivers'))
|
22
23
|
|
23
24
|
class << self
|
24
25
|
attr_accessor :proxy_addr, :proxy_port, :proxy_user, :proxy_pass
|
@@ -30,7 +31,8 @@ module Webdrivers
|
|
30
31
|
# are set, it defaults to 86,400 Seconds (24 hours).
|
31
32
|
#
|
32
33
|
def cache_time
|
33
|
-
(ENV['WD_CACHE_TIME'] ||
|
34
|
+
@cache_time ||= (ENV['WD_CACHE_TIME'] || DEFAULT_CACHE_TIME)
|
35
|
+
@cache_time.to_i
|
34
36
|
end
|
35
37
|
|
36
38
|
#
|
@@ -38,7 +40,7 @@ module Webdrivers
|
|
38
40
|
#
|
39
41
|
# @return [String]
|
40
42
|
def install_dir
|
41
|
-
@install_dir
|
43
|
+
@install_dir ||= ENV['WD_INSTALL_DIR'] || DEFAULT_INSTALL_DIR
|
42
44
|
end
|
43
45
|
|
44
46
|
def logger
|
@@ -65,7 +67,7 @@ module Webdrivers
|
|
65
67
|
raise 'Webdrivers.net_http_ssl_fix is no longer available.' \
|
66
68
|
' Please see https://github.com/titusfortner/webdrivers#ssl_connect-errors.'
|
67
69
|
end
|
68
|
-
end
|
70
|
+
end
|
69
71
|
|
70
72
|
class Common
|
71
73
|
class << self
|
@@ -76,7 +78,7 @@ end
|
|
76
78
|
#
|
77
79
|
# @return [Gem::Version]
|
78
80
|
def required_version
|
79
|
-
normalize_version
|
81
|
+
normalize_version(@required_version ||= nil)
|
80
82
|
end
|
81
83
|
|
82
84
|
#
|
@@ -109,7 +111,7 @@ end
|
|
109
111
|
#
|
110
112
|
# @return [String]
|
111
113
|
def driver_path
|
112
|
-
|
114
|
+
File.absolute_path File.join(System.install_dir, file_name)
|
113
115
|
end
|
114
116
|
|
115
117
|
private
|
@@ -145,7 +147,7 @@ end
|
|
145
147
|
end
|
146
148
|
|
147
149
|
def binary_version
|
148
|
-
version = System.call(
|
150
|
+
version = System.call(driver_path, '--version')
|
149
151
|
Webdrivers.logger.debug "Current version of #{driver_path} is #{version}"
|
150
152
|
version
|
151
153
|
rescue Errno::ENOENT
|
@@ -0,0 +1,82 @@
|
|
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
|
+
|
12
|
+
raise VersionError, 'Failed to find Edge binary or its version.' if version.nil? || version.empty?
|
13
|
+
|
14
|
+
Webdrivers.logger.debug "Browser version: #{version}"
|
15
|
+
version[/\d+\.\d+\.\d+\.\d+/] # Microsoft Edge 73.0.3683.75 -> 73.0.3683.75
|
16
|
+
end
|
17
|
+
|
18
|
+
def location
|
19
|
+
user_defined_location || send("#{System.platform}_location")
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def user_defined_location
|
25
|
+
if Selenium::WebDriver::EdgeChrome.path
|
26
|
+
Webdrivers.logger.debug "Selenium::WebDriver::EdgeChrome.path: #{Selenium::WebDriver::EdgeChrome.path}"
|
27
|
+
return Selenium::WebDriver::EdgeChrome.path
|
28
|
+
end
|
29
|
+
|
30
|
+
return if ENV['WD_EDGE_CHROME_PATH'].nil?
|
31
|
+
|
32
|
+
Webdrivers.logger.debug "WD_EDGE_CHROME_PATH: #{ENV['WD_EDGE_CHROME_PATH']}"
|
33
|
+
ENV['WD_EDGE_CHROME_PATH']
|
34
|
+
end
|
35
|
+
|
36
|
+
def win_location
|
37
|
+
envs = %w[LOCALAPPDATA PROGRAMFILES PROGRAMFILES(X86)]
|
38
|
+
directories = ['\\Microsoft\\Edge Dev\\Application', '\\Microsoft\\Edge SxS\\Application']
|
39
|
+
file = 'msedge.exe'
|
40
|
+
|
41
|
+
directories.each do |dir|
|
42
|
+
envs.each do |root|
|
43
|
+
option = "#{ENV[root]}\\#{dir}\\#{file}"
|
44
|
+
return option if File.exist?(option)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def mac_location
|
51
|
+
directories = ['', File.expand_path('~')]
|
52
|
+
files = ['/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
|
53
|
+
'/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev',
|
54
|
+
'/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary']
|
55
|
+
|
56
|
+
directories.each do |dir|
|
57
|
+
files.each do |file|
|
58
|
+
option = "#{dir}/#{file}"
|
59
|
+
return option if File.exist?(option)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def linux_location
|
66
|
+
raise 'Default location not yet known'
|
67
|
+
end
|
68
|
+
|
69
|
+
def win_version(location)
|
70
|
+
System.call("powershell (Get-ItemProperty '#{location}').VersionInfo.ProductVersion")&.strip
|
71
|
+
end
|
72
|
+
|
73
|
+
def linux_version(location)
|
74
|
+
System.call(location, '--product-version')&.strip
|
75
|
+
end
|
76
|
+
|
77
|
+
def mac_version(location)
|
78
|
+
System.call(location, '--version')&.strip
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'webdrivers/common'
|
5
|
+
require 'webdrivers/chromedriver'
|
6
|
+
require 'webdrivers/edge_finder'
|
7
|
+
|
8
|
+
module Webdrivers
|
9
|
+
class Edgedriver < Chromedriver
|
10
|
+
class << self
|
11
|
+
undef :chrome_version
|
12
|
+
#
|
13
|
+
# Returns currently installed Edge version.
|
14
|
+
#
|
15
|
+
# @return [Gem::Version]
|
16
|
+
def browser_version
|
17
|
+
normalize_version EdgeFinder.version
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Returns url with domain for calls to get this driver.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
def base_url
|
25
|
+
# 'https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/'
|
26
|
+
'https://msedgedriver.azureedge.net/'
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def latest_point_release(version)
|
36
|
+
# Microsoft doesn't currently provide LATEST_RELEASE_X.Y.Z - only use X
|
37
|
+
# but require the driver version be >= the passed in version
|
38
|
+
str = Network.get(URI.join(base_url, "LATEST_RELEASE_#{version.segments[0]}"))
|
39
|
+
latest_release = normalize_version(str.encode('ASCII-8BIT', 'UTF-16'))
|
40
|
+
raise VersionError unless latest_release >= version
|
41
|
+
|
42
|
+
latest_release
|
43
|
+
rescue NetworkError, VersionError
|
44
|
+
msg = failed_to_find_message(version)
|
45
|
+
Webdrivers.logger.debug msg
|
46
|
+
raise VersionError, msg
|
47
|
+
end
|
48
|
+
|
49
|
+
def failed_to_find_message(version)
|
50
|
+
msg = "Unable to find latest point release version for #{version}."
|
51
|
+
msg = begin
|
52
|
+
# str = Network.get(URI.join(base_url, 'LATEST_RELEASE'))
|
53
|
+
# Microsoft doesn't yet/ever support LATEST_RELEASE - Use Canary as latest
|
54
|
+
str = Network.get(URI.join(base_url, 'LATEST_CANARY'))
|
55
|
+
latest_release = normalize_version(str.encode('ASCII-8BIT', 'UTF-16'))
|
56
|
+
if version > latest_release
|
57
|
+
"#{msg} You appear to be using a non-production version of Edge."
|
58
|
+
else
|
59
|
+
msg
|
60
|
+
end
|
61
|
+
rescue NetworkError
|
62
|
+
"#{msg} A network issue is preventing determination of latest msedgedriver release."
|
63
|
+
end
|
64
|
+
|
65
|
+
"#{msg} Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` "\
|
66
|
+
"to a known edgedriver version: Can not reach #{base_url}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def file_name
|
70
|
+
System.platform == 'win' ? 'msedgedriver.exe' : 'msedgedriver'
|
71
|
+
end
|
72
|
+
|
73
|
+
def download_url
|
74
|
+
return @download_url if @download_url
|
75
|
+
|
76
|
+
version = if required_version == EMPTY_VERSION
|
77
|
+
latest_version
|
78
|
+
else
|
79
|
+
normalize_version(required_version)
|
80
|
+
end
|
81
|
+
|
82
|
+
file_name = System.platform == 'win' ? 'win32' : "#{System.platform}64"
|
83
|
+
url = "#{base_url}/#{version}/edgedriver_#{file_name}.zip"
|
84
|
+
Webdrivers.logger.debug "msedgedriver URL: #{url}"
|
85
|
+
@download_url = url
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
if defined? Selenium::WebDriver::EdgeChrome
|
92
|
+
if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
93
|
+
::Selenium::WebDriver::EdgeChrome::Service.driver_path = proc { ::Webdrivers::Edgedriver.update }
|
94
|
+
else
|
95
|
+
# v3.141.0 and lower
|
96
|
+
module Selenium
|
97
|
+
module WebDriver
|
98
|
+
module EdgeChrome
|
99
|
+
def self.driver_path
|
100
|
+
@driver_path ||= Webdrivers::Edgedriver.update
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/webdrivers/system.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems/package'
|
4
4
|
require 'zip'
|
5
|
+
require 'English'
|
5
6
|
|
6
7
|
module Webdrivers
|
7
8
|
#
|
@@ -89,7 +90,7 @@ module Webdrivers
|
|
89
90
|
when /tar\.bz2$/
|
90
91
|
untarbz2_file(tempfile)
|
91
92
|
when /\.zip$/
|
92
|
-
unzip_file(tempfile)
|
93
|
+
unzip_file(tempfile, File.basename(target))
|
93
94
|
else
|
94
95
|
Webdrivers.logger.debug 'No Decompression needed'
|
95
96
|
FileUtils.cp(tempfile, File.join(Dir.pwd, file_name))
|
@@ -114,19 +115,17 @@ module Webdrivers
|
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
117
|
-
def unzip_file(filename)
|
118
|
+
def unzip_file(filename, driver_name)
|
118
119
|
Webdrivers.logger.debug "Decompressing #{filename}"
|
119
120
|
|
120
121
|
Zip::File.open(filename) do |zip_file|
|
121
|
-
zip_file.
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
zip_file.extract(f, f_path)
|
127
|
-
end
|
122
|
+
driver = zip_file.get_entry(driver_name)
|
123
|
+
f_path = File.join(Dir.pwd, driver.name)
|
124
|
+
delete(f_path)
|
125
|
+
FileUtils.mkdir_p(File.dirname(f_path)) unless File.exist?(File.dirname(f_path))
|
126
|
+
zip_file.extract(driver, f_path)
|
128
127
|
end
|
129
|
-
|
128
|
+
driver_name
|
130
129
|
end
|
131
130
|
|
132
131
|
def platform
|
@@ -145,15 +144,16 @@ module Webdrivers
|
|
145
144
|
Selenium::WebDriver::Platform.bitsize
|
146
145
|
end
|
147
146
|
|
148
|
-
def call(
|
147
|
+
def call(process, arg = nil)
|
148
|
+
cmd = arg ? [process, arg] : process # Windows provides powershell command (process) only, no args.
|
149
149
|
Webdrivers.logger.debug "making System call: #{cmd}"
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
return path.tr('/', '\\') if platform == 'win' # Windows
|
150
|
+
p = IO.popen(cmd)
|
151
|
+
out = p.read
|
152
|
+
p.close
|
153
|
+
raise "Failed to make system call: #{cmd}" unless $CHILD_STATUS.success?
|
155
154
|
|
156
|
-
|
155
|
+
Webdrivers.logger.debug "System call returned: #{out}"
|
156
|
+
out
|
157
157
|
end
|
158
158
|
end
|
159
159
|
end
|
@@ -19,8 +19,6 @@ namespace :webdrivers do
|
|
19
19
|
desc 'Remove and download updated chromedriver if necessary'
|
20
20
|
task :update, [:version] do |_, args|
|
21
21
|
args.with_defaults(version: 0)
|
22
|
-
Webdrivers.cache_time = ENV.fetch('WD_CACHE_TIME', 86_400)
|
23
|
-
Webdrivers.install_dir = ENV.fetch('WD_INSTALL_DIR', nil)
|
24
22
|
Webdrivers::Chromedriver.required_version = args.version
|
25
23
|
Webdrivers::Chromedriver.update
|
26
24
|
Webdrivers.logger.info "Updated to chromedriver #{Webdrivers::Chromedriver.current_version}"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :webdrivers do
|
4
|
+
require 'webdrivers/edgedriver'
|
5
|
+
|
6
|
+
namespace :edgedriver do
|
7
|
+
Webdrivers.logger.level = :info
|
8
|
+
|
9
|
+
desc 'Print current edgedriver version'
|
10
|
+
task :version do
|
11
|
+
gem_ver = Webdrivers::Edgedriver.current_version
|
12
|
+
if gem_ver
|
13
|
+
Webdrivers.logger.info "edgedriver #{gem_ver.version}"
|
14
|
+
else
|
15
|
+
Webdrivers.logger.warn 'No existing edgedriver found.'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Remove and download updated edgedriver if necessary'
|
20
|
+
task :update, [:version] do |_, args|
|
21
|
+
args.with_defaults(version: 0)
|
22
|
+
Webdrivers::Edgedriver.required_version = args.version
|
23
|
+
Webdrivers::Edgedriver.update
|
24
|
+
Webdrivers.logger.info "Updated to edgedriver #{Webdrivers::Edgedriver.current_version}"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Force remove edgedriver'
|
28
|
+
task :remove do
|
29
|
+
unless File.exist? Webdrivers::Edgedriver.driver_path
|
30
|
+
Webdrivers.logger.info 'No existing edgedriver to remove.'
|
31
|
+
next # Return early
|
32
|
+
end
|
33
|
+
|
34
|
+
cur_version = Webdrivers::Edgedriver.current_version
|
35
|
+
Webdrivers::Edgedriver.remove
|
36
|
+
|
37
|
+
if File.exist? Webdrivers::Edgedriver.driver_path # Failed for some reason
|
38
|
+
Webdrivers.logger.error 'Failed to remove edgedriver. Please try removing manually.'
|
39
|
+
else
|
40
|
+
Webdrivers.logger.info "Removed edgedriver #{cur_version}."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -19,8 +19,6 @@ namespace :webdrivers do
|
|
19
19
|
desc 'Remove and download updated geckodriver if necessary'
|
20
20
|
task :update, [:version] do |_, args|
|
21
21
|
args.with_defaults(version: 0)
|
22
|
-
Webdrivers.cache_time = ENV.fetch('WD_CACHE_TIME', 86_400)
|
23
|
-
Webdrivers.install_dir = ENV.fetch('WD_INSTALL_DIR', nil)
|
24
22
|
Webdrivers::Geckodriver.required_version = args.version
|
25
23
|
Webdrivers::Geckodriver.update
|
26
24
|
Webdrivers.logger.info "Updated to geckodriver #{Webdrivers::Geckodriver.current_version}"
|
@@ -19,8 +19,6 @@ namespace :webdrivers do
|
|
19
19
|
desc 'Remove and download updated IEDriverServer if necessary'
|
20
20
|
task :update, [:version] do |_, args|
|
21
21
|
args.with_defaults(version: 0)
|
22
|
-
Webdrivers.cache_time = ENV.fetch('WD_CACHE_TIME', 86_400)
|
23
|
-
Webdrivers.install_dir = ENV.fetch('WD_INSTALL_DIR', nil)
|
24
22
|
Webdrivers::IEdriver.required_version = args.version
|
25
23
|
Webdrivers::IEdriver.update
|
26
24
|
Webdrivers.logger.info "Updated to IEDriverServer #{Webdrivers::IEdriver.current_version}"
|
data/lib/webdrivers/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Webdrivers::ChromeFinder do
|
6
|
+
let(:chrome_finder) { described_class }
|
7
|
+
|
8
|
+
context 'when the user relies on the gem to figure out the location of Chrome' do
|
9
|
+
it 'determines the location correctly based on the current OS' do
|
10
|
+
expect(chrome_finder.location).not_to be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the user provides a path to the Chrome binary' do
|
15
|
+
it 'uses Selenium::WebDriver::Chrome.path when it is defined' do
|
16
|
+
Selenium::WebDriver::Chrome.path = chrome_finder.location
|
17
|
+
allow(chrome_finder).to receive(:win_location)
|
18
|
+
allow(chrome_finder).to receive(:mac_location)
|
19
|
+
allow(chrome_finder).to receive(:linux_location)
|
20
|
+
expect(chrome_finder.version).not_to be_nil
|
21
|
+
expect(chrome_finder).not_to have_received(:win_location)
|
22
|
+
expect(chrome_finder).not_to have_received(:mac_location)
|
23
|
+
expect(chrome_finder).not_to have_received(:linux_location)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "uses ENV['WD_CHROME_PATH'] when it is defined" do
|
27
|
+
allow(ENV).to receive(:[]).with('WD_CHROME_PATH').and_return(chrome_finder.location)
|
28
|
+
allow(chrome_finder).to receive(:win_location)
|
29
|
+
allow(chrome_finder).to receive(:mac_location)
|
30
|
+
allow(chrome_finder).to receive(:linux_location)
|
31
|
+
expect(chrome_finder.version).not_to be_nil
|
32
|
+
expect(chrome_finder).not_to have_received(:win_location)
|
33
|
+
expect(chrome_finder).not_to have_received(:mac_location)
|
34
|
+
expect(chrome_finder).not_to have_received(:linux_location)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'uses Selenium::WebDriver::Chrome.path over WD_CHROME_PATH' do
|
38
|
+
Selenium::WebDriver::Chrome.path = chrome_finder.location
|
39
|
+
allow(ENV).to receive(:[]).with('WD_CHROME_PATH').and_return('my_wd_chrome_path')
|
40
|
+
expect(chrome_finder.version).not_to be_nil
|
41
|
+
expect(ENV).not_to have_received(:[]).with('WD_CHROME_PATH')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|