Skip to content

Commit

Permalink
Allow for legacy versions to be pulled up
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoertink committed Oct 20, 2023
1 parent 4ee6a47 commit b019315
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 22 deletions.
4 changes: 2 additions & 2 deletions spec/webdrivers/cache_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe Webdrivers::Cache do
end
end

private def with_tempfile
private def with_tempfile(&)
tempfile = File.tempfile(suffix: ".txt") do |file|
file.print("hello!")
end
Expand All @@ -47,7 +47,7 @@ ensure
tempfile.try(&.delete)
end

private def with_missing_file
private def with_missing_file(&)
tempname = File.tempname(suffix: ".txt")
yield tempname
ensure
Expand Down
3 changes: 1 addition & 2 deletions spec/webdrivers/chrome/driver_remote_version_finder_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ module Webdrivers::Chrome
File.delete(finder.cache_path) if File.exists?(finder.cache_path)
end

# TODO: Figure out if this is necessary
pending "will limit return version to matching major version if version" do
it "will limit return version to matching major version when version is provided" do
version = SemanticVersion.new(
major: 71,
minor: 22,
Expand Down
2 changes: 1 addition & 1 deletion src/webdrivers/cache.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Webdrivers::Cache
def self.fetch(cache_path : String, expires_in : Time::Span, &block)
def self.fetch(cache_path : String, expires_in : Time::Span, &)
value = read(cache_path, expires_in)
return value if value

Expand Down
37 changes: 29 additions & 8 deletions src/webdrivers/chrome/driver_remote_version_finder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ class Webdrivers::Chrome::DriverRemoteVersionFinder
getter cache_path : String
getter version : SemanticVersion?

# Since Chrome v115+ the download locations have changed.
# We can use https://github.com/GoogleChromeLabs/chrome-for-testing#json-api-endpoints
# to find specific API endpoints
MANIFEST_API_ENDPOINT = "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json"

def initialize(driver_directory, @version = nil)
@cache_path = File.join(driver_directory, "chromedriver.version")
end
Expand All @@ -17,9 +12,35 @@ class Webdrivers::Chrome::DriverRemoteVersionFinder

private def find_raw_version
Cache.fetch(cache_path, Webdrivers.settings.cache_duration) do
response = HTTP::Client.get(MANIFEST_API_ENDPOINT)
google = JSON.parse(response.body)
google.dig("channels", "Stable", "version").as_s
if v = version
if v.major < 113
fetch_legacy_version(v)
else
fetch_latest_version(v)
end
else
fetch_latest_stable
end
end
end

private def fetch_legacy_version(version : SemanticVersion)
response = HTTP::Client.get("https://chromedriver.storage.googleapis.com/LATEST_RELEASE_#{version.major}")
response.body
end

private def fetch_latest_version(version : SemanticVersion)
response = HTTP::Client.get("#{chrome_for_testing_base_url}/LATEST_RELEASE_#{version.major}")
response.body
end

private def fetch_latest_stable
response = HTTP::Client.get("#{chrome_for_testing_base_url}/last-known-good-versions-with-downloads.json")
google = JSON.parse(response.body)
google.dig("channels", "Stable", "version").as_s
end

private def chrome_for_testing_base_url : String
"https://googlechromelabs.github.io/chrome-for-testing"
end
end
36 changes: 30 additions & 6 deletions src/webdrivers/chrome/install_driver_executor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@ class Webdrivers::Chrome::InstallDriverExecutor
getter current_version : SemanticVersion?
getter driver_directory : String
getter driver_name : String
getter cache_path : String

def initialize(@install_version, @driver_directory, @driver_name, @current_version)
@cache_path = File.join(Common.driver_directory, "chromedriver.download_url")
end

def execute
return if current_version == install_version

Dir.mkdir_p(driver_directory) unless File.exists?(driver_directory)

if install_version.major < 115
normalized_driver_name = driver_name
else
normalized_driver_name = File.join("chromedriver-#{download_url_platform}", driver_name)
end

FileUtils.cd(driver_directory) do
zip = download_file(from: download_url, to: download_url_filename)
Common::ZipExtractor.new(zip, File.join("chromedriver-#{download_url_platform}", driver_name), driver_directory).extract
Common::ZipExtractor.new(zip, normalized_driver_name, driver_directory).extract
zip.delete
File.chmod(driver_name, Common::EXECUTABLE_PERMISSIONS)
end
Expand All @@ -29,17 +37,33 @@ class Webdrivers::Chrome::InstallDriverExecutor
end

private def download_url : String
response = HTTP::Client.get(Webdrivers::Chrome::DriverRemoteVersionFinder::MANIFEST_API_ENDPOINT)
google = JSON.parse(response.body.to_s)
downloads = google.dig("channels", "Stable", "downloads", "chromedriver").as_a
platform = downloads.find! { |version| version["platform"].as_s == download_url_platform }
platform["url"].as_s
if install_version.major < 115
"https://chromedriver.storage.googleapis.com/#{converted_version}/#{download_url_filename}"
else
fetch_download_url_for_version
end
end

private def fetch_download_url_for_version : String
Cache.fetch(cache_path, Webdrivers.settings.cache_duration) do
response = HTTP::Client.get("#{chrome_for_testing_base_url}/known-good-versions-with-downloads.json")
google = JSON.parse(response.body.to_s)
downloads = google["versions"].as_a
version_found = downloads.find! { |version| version["version"].as_s == converted_version }
platforms = version_found.dig("downloads", "chromedriver").as_a
platform_found = platforms.find! { |platform| platform["platform"].as_s == download_url_platform }
platform_found["url"].as_s
end
end

private def converted_version : String
SemverConverter.convert(install_version)
end

private def chrome_for_testing_base_url : String
"https://googlechromelabs.github.io/chrome-for-testing"
end

# TODO: Support Win64, and Mac Intel
private def download_url_platform : String
case Common.os
Expand Down
2 changes: 1 addition & 1 deletion src/webdrivers/chromedriver.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Webdrivers::Chromedriver

def self.install : String
Chrome::InstallDriverExecutor.new(
install_version: latest_driver_version.not_nil!,
install_version: latest_driver_version.as(SemanticVersion),
current_version: driver_version,
driver_directory: Common.driver_directory,
driver_name: driver_name
Expand Down
2 changes: 1 addition & 1 deletion src/webdrivers/common/tar_gz_extractor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Webdrivers::Common::TarGzExtractor
def extract
Compress::Gzip::Reader.open(file) do |gzip|
Crystar::Reader.open(gzip) do |tar|
entry = tar.next_entry.not_nil!
entry = tar.next_entry.as(Crystar::Header)
destination_path = File.join(install_path, entry.name)
File.delete(destination_path) if File.exists?(destination_path)
File.write(destination_path, entry.io)
Expand Down
2 changes: 1 addition & 1 deletion src/webdrivers/geckodriver.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Webdrivers::Geckodriver

def self.install : String
Gecko::InstallDriverExecutor.new(
install_version: latest_driver_version.not_nil!,
install_version: latest_driver_version.as(SemanticVersion),
current_version: driver_version,
driver_directory: Common.driver_directory,
driver_name: driver_name
Expand Down

0 comments on commit b019315

Please sign in to comment.