Created
August 21, 2022 15:46
-
-
Save justin-robinson/5d3491a9adf4e81e427cfcc0c3842a53 to your computer and use it in GitHub Desktop.
Rails test download helper [thread safe]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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