Skip to content

Instantly share code, notes, and snippets.

@justin-robinson
Created August 21, 2022 15:46
Show Gist options
  • Select an option

  • Save justin-robinson/5d3491a9adf4e81e427cfcc0c3842a53 to your computer and use it in GitHub Desktop.

Select an option

Save justin-robinson/5d3491a9adf4e81e427cfcc0c3842a53 to your computer and use it in GitHub Desktop.
Rails test download helper [thread safe]
require 'test_helper'
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
WINDOW_SIZE = [1400, 1400].freeze
driven_by :selenium, using: :chrome, screen_size: WINDOW_SIZE do |options|
options.add_preference(:download, prompt_for_download: false, default_directory: DownloadHelper::PATH.to_s)
options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
end
end
require 'application_system_test_case'
class DownloadsTest < ApplicationSystemTestCase
test 'should download' do
visit download_url
download = DownloadHelper.download { click_on 'Download' }
file = File.open download
# assert properties of file
end
end
# Modified version of a common download helper that adds thread safety
# Now you can initiate a mutli-threaded system test and your file download operations will still work as expected
# Before you were not guaranteed to get the download your test requested but could get one from another test
module DownloadHelper
TIMEOUT = 1
PATH = Rails.root.join('tmp/downloads')
SEMAPHORE = Mutex.new
def self.downloads
Dir[PATH.join('*')].select(&File.method(:file?))
.sort_by &File.method(:mtime)
end
def self.download(&block)
SEMAPHORE.synchronize {
wait_for_download &block
downloads.last
}
end
def self.wait_for_download(&block)
block.call
@current_download_count = downloads.size
Timeout.timeout(TIMEOUT) do
sleep 0.1 until downloaded?
end
end
def self.downloaded?
!downloading? && @current_download_count < downloads.size
end
def self.downloading?
downloads.grep(/\.crdownload$/).any?
end
def self.clear_downloads
FileUtils.rm_f(downloads)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment