lib/geordi/chromedriver_updater.rb in geordi-9.6.0 vs lib/geordi/chromedriver_updater.rb in geordi-9.6.1
- old
+ new
@@ -1,19 +1,22 @@
require 'open3'
require 'net/http'
require 'tempfile'
+require 'json'
+require 'fileutils'
module Geordi
class ChromedriverUpdater
+ VERSIONS_PER_MILESTONES_URL = "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone-with-downloads.json"
def run(options)
chrome_version = determine_chrome_version
current_chromedriver_version = determine_chromedriver_version
latest_chromedriver_version = latest_version(chrome_version)
if current_chromedriver_version == latest_chromedriver_version
- Interaction.success "No update required: Chromedriver is already on the latest version v#{latest_chromedriver_version}!" unless options[:quiet_if_matching]
+ Interaction.note "No update required. Chromedriver is already on the latest version #{latest_chromedriver_version}." unless options[:quiet_if_matching]
else
update_chromedriver(latest_chromedriver_version)
end
end
@@ -47,12 +50,12 @@
end
end
# Check https://groups.google.com/a/chromium.org/g/chromium-discuss/c/4BB4jmsRyv8/m/TY3FXS4HBgAJ
# for information how chrome version numbers work
- def major_version(full_version)
- full_version.match(/^(\d+\.\d+\.\d+)\.\d+$/)[1]
+ def milestone_version(full_version)
+ full_version.match(/^\d+/)[0]
end
def update_chromedriver(latest_chromedriver_version)
chromedriver_zip = download_chromedriver(latest_chromedriver_version)
@@ -60,41 +63,70 @@
# We need to determine the version again, as it could be nil in case no chromedriver was installed before
Interaction.success "Chromedriver updated to v#{determine_chromedriver_version}."
end
- def download_chromedriver(latest_version)
- uri = URI("https://chromedriver.storage.googleapis.com/#{latest_version}/chromedriver_linux64.zip")
- response = Net::HTTP.get_response(uri)
-
- if response.is_a?(Net::HTTPSuccess)
- file = Tempfile.new(['chromedriver', '.zip'])
+ def download_chromedriver(version)
+ fetch_response(chromedriver_url(version), "Could not download chromedriver v#{version}.") do |response|
+ file = Tempfile.new(%w[chromedriver .zip])
file.write(response.body)
file
- else
- Interaction.fail("Could not download chromedriver v#{latest_version}.")
end
end
- def latest_version(chrome_version)
- return @latest_version if @latest_version
-
- uri = URI("https://chromedriver.storage.googleapis.com/LATEST_RELEASE_#{major_version(chrome_version)}")
+ def fetch_response(url, error_message)
+ uri = URI(url)
response = Net::HTTP.get_response(uri)
if response.is_a?(Net::HTTPSuccess)
- @latest_version = response.body.to_s
+ yield(response)
else
- Interaction.fail("Could not download the chromedriver v#{chrome_version}.")
+ Interaction.fail(error_message)
end
end
+ def chromedriver_url(chrome_version)
+ chromedriver_per_platform = chromedriver_download_data.dig("milestones", milestone_version(chrome_version), "downloads", "chromedriver")
+ chromedriver = chromedriver_per_platform&.find do |chromedriver|
+ chromedriver["platform"] == "linux64"
+ end
+
+ if chromedriver && chromedriver["url"]
+ chromedriver["url"]
+ else
+ Interaction.fail("Could not find chromedriver download url for Chrome version v#{chrome_version}.")
+ end
+ end
+
+ def chromedriver_download_data
+ return @chromedriver_download_data if @chromedriver_download_data
+
+ fetch_response(VERSIONS_PER_MILESTONES_URL, "Could not find chromedriver download data") do |response|
+ begin
+ chromedriver_download_data = JSON.parse(response.body)
+ rescue JSON::ParserError
+ Interaction.fail("Could not parse chromedriver download data.")
+ end
+ @chromedriver_download_data = chromedriver_download_data
+ end
+ end
+
+ def latest_version(chrome_version)
+ latest_version = chromedriver_download_data.dig("milestones", milestone_version(chrome_version), "version")
+ latest_version || Interaction.fail("Could not find matching chromedriver for Chrome v#{chrome_version}.")
+ end
+
def unzip(zip, output_dir)
_stdout_str, _error_str, status = Open3.capture3('unzip', '-d', output_dir, '-o', zip.path)
unless status.success?
Interaction.fail("Could not unzip #{zip.path}.")
end
+
+ # the archive contains a folder in which the relevant files are located. These files must be moved to ~/bin.
+ FileUtils.mv("#{output_dir}/chromedriver-linux64/chromedriver", output_dir)
+ FileUtils.mv("#{output_dir}/chromedriver-linux64//LICENSE.chromedriver", output_dir)
+ FileUtils.rm_rf("#{output_dir}/chromedriver-linux64")
end
end
end