class DriverDownloader

Downloads and installs browser drivers.

Public Class Methods

new(verbose = true) click to toggle source
# File lib/chauffeur/driver_downloader.rb, line 5
def initialize(verbose = true)
  @verbose = verbose
  config_file_path = "#{Dir.pwd}/drivers/config.yml"
  @data = File.open(config_file_path) { |f| YAML.safe_load(f) }
  @installed_versions = @data['installed_versions']
end

Public Instance Methods

all_driver_versions() click to toggle source

Returns all available versions of Chromedriver

# File lib/chauffeur/driver_downloader.rb, line 43
def all_driver_versions
  raise 'This class should not be initialized! Please use subclass.'
end
all_platforms() click to toggle source

This must be implemented in all child classes!

returns an array of all available platforms for the driver.

# File lib/chauffeur/driver_downloader.rb, line 29
def all_platforms
  raise 'This class should not be initialized! Please use subclass.'
end
browser_name() click to toggle source

This must be implemented in all child classes!

Returns a string for the driver name in file structure.

# File lib/chauffeur/driver_downloader.rb, line 15
def browser_name
  raise 'This class should not be initialized! Please use subclass.'
end
download_and_unzip(driver_path, download_url) click to toggle source

Downloads and installs driver to appropriate path

driver_path: string - path to install driver (must end with '/')
download_url: string - URL of the driver desired
# File lib/chauffeur/driver_downloader.rb, line 107
def download_and_unzip(driver_path, download_url)
  FileUtils.mkdir_p(driver_path)
  destination_file_name = "#{driver_path}#{File.basename(download_url)}"
  FileUtils.rm_f destination_file_name
  File.open(destination_file_name, 'wb') do |saved_file|
    saved_file.write(HTTParty.get(download_url, verify: false).parsed_response)
  end
  raise "Could not download #{download_url}" unless File.exist?(destination_file_name)
  extract_and_delete(destination_file_name, driver_path) unless instance_of?(EdgedriverDownloader)
  FileUtils.rm_f "#{destination_file_name}.zip"
end
driver_download_url(_version, _platform) click to toggle source

This must be implemented in all child classes!

Returns the url for the desired version of driver version: string - must match exactly the version in the download URL platform: string - must be in all_platforms

# File lib/chauffeur/driver_downloader.rb, line 52
def driver_download_url(_version, _platform)
  raise 'This class should not be initialized! Please use subclass.'
end
driver_url() click to toggle source

This must be implemented in all child classes!

returns the string url where all downloads can be located.

# File lib/chauffeur/driver_downloader.rb, line 22
def driver_url
  raise 'This class should not be initialized! Please use subclass.'
end
install_driver(version, platform) click to toggle source

Downloads and installs driver

version: string   - the exact version number for the download
platform: string  - must match the appropriate platform for
                    the particular driver
# File lib/chauffeur/driver_downloader.rb, line 70
def install_driver(version, platform)
  raise unknown_platform_error(platform) unless valid_platform?(platform)
  if @installed_versions[browser_name][platform].eql?(version.to_s)
    puts "Driver version #{version} already installed for #{platform}" if @verbose
    return false
  end
  driver_path = path_for(platform, version)
  download_url = driver_download_url(version, platform)

  puts "installing '#{download_url}' into '#{driver_path}'" if @verbose

  download_and_unzip(driver_path, download_url)
  update_browser_version(platform, version)
end
install_driver_all_platforms(version) click to toggle source

Installs the specified version of specified driver for all platforms.

# File lib/chauffeur/driver_downloader.rb, line 100
def install_driver_all_platforms(version)
  all_platforms.each { |platform| install_driver(version, platform) }
end
latest_driver_version(_platform) click to toggle source

This must be implemented in all child classes!

Returns the most recent version of chromedriver for the desired platform. platform must be one of: linux32, linux64, mac32, win32

# File lib/chauffeur/driver_downloader.rb, line 38
def latest_driver_version(_platform)
  raise 'This class should not be initialized! Please use subclass.'
end
path_for(platform, version) click to toggle source

Returns the destination folder for the browser driver for the desired platform.

platform: string  - must match the appropriate platform for
                    the particular driver
# File lib/chauffeur/driver_downloader.rb, line 60
def path_for(platform, version)
  raise unknown_platform_error(platform) unless valid_platform?(platform)
  last_part = instance_of?(EdgedriverDownloader) ? version : platform
  "#{Dir.pwd}/drivers/#{browser_name}/#{last_part}/"
end
upgrade_driver(platform) click to toggle source

Installs the latest version of chromedriver for the specified platform.

platform: string  - must match the appropriate platform for
                    the particular driver
# File lib/chauffeur/driver_downloader.rb, line 88
def upgrade_driver(platform)
  raise unknown_platform_error(platform) unless valid_platform?(platform)
  latest_version = latest_driver_version(platform)
  install_driver(latest_version, platform)
end
upgrade_driver_all_platforms() click to toggle source

Installs the latest version of chromedriver for all platforms.

# File lib/chauffeur/driver_downloader.rb, line 95
def upgrade_driver_all_platforms
  all_platforms.each { |platform| upgrade_driver(platform) }
end

Private Instance Methods

extract_and_delete(destination_file_name, driver_path) click to toggle source

Extracts a file and deletes the compressed file

destination_file_name: string - full file path to the compressed file. driver_path: string - the full path to the destination folder.

# File lib/chauffeur/driver_downloader.rb, line 162
def extract_and_delete(destination_file_name, driver_path)
  if destination_file_name.end_with?('.tar.gz')
    File.open(destination_file_name, 'rb') do |f|
      gz = Zlib::GzipReader.new(f)
      File.open("#{driver_path}geckodriver", 'wb', 0o0755) { |new_file| new_file.puts(gz.read) }
    end
  else
    Archive::Zip.extract(destination_file_name, driver_path, overwrite: :all)
  end
  files_to_delete = Dir.glob("#{driver_path}*.{zip,gz}")
  FileUtils.rm_rf(files_to_delete) if files_to_delete.size.eql?(1)
end
save_data() click to toggle source

Saves @data to config.yml file

# File lib/chauffeur/driver_downloader.rb, line 134
def save_data
  File.open("#{Dir.pwd}/drivers/config.yml", 'w') { |f| f.write(@data.to_yaml) }
end
unknown_platform_error(platform) click to toggle source

Returns instance of an UnknownPlatform Error to be thrown

Requires all_platforms to be defined in the instantiated class.

# File lib/chauffeur/driver_downloader.rb, line 148
def unknown_platform_error(platform)
  msg = "Unknown platform #{platform}, valid options: #{all_platforms}."
  raise UnknownPlatformError.new(platform, msg)
end
unknown_version_error(version) click to toggle source
# File lib/chauffeur/driver_downloader.rb, line 153
def unknown_version_error(version)
  msg = "Unknown version '#{version}', valid options: #{@all_driver_versions}."
  raise UnknownVersionError.new(version, msg)
end
update_browser_version(platform, version) click to toggle source

Updates the hash of the installed versions and then saves the Yaml file

# File lib/chauffeur/driver_downloader.rb, line 128
def update_browser_version(platform, version)
  @installed_versions[browser_name][platform] = version.to_s
  save_data
end
valid_platform?(platform) click to toggle source

Checks to see if the passed in platform is valid for the particular browser

Requires all_platforms to be defined in the instantiated class.

# File lib/chauffeur/driver_downloader.rb, line 141
def valid_platform?(platform)
  all_platforms.include?(platform)
end
version_of(num_str) click to toggle source

Gem::Version lets versions get compared in a way that makes sense for semantic versions. For example it makes 2.38 greater than 2.5

# File lib/chauffeur/driver_downloader.rb, line 123
def version_of(num_str)
  Gem::Version.new(num_str)
end