Rails
RSpec
Capybara

RSpecでファイルがダウンロードされるまで待つ

課題:ファイルのダウンロードが終わってたり終わってなかったり

Capybara(Chrome headless)のテストが不安定でした。

調査

ディレクトリの中が空じゃないかどうか見張ればいい。
なんでこんな単純なことに気づかなかったのか!!

実装

参考URLに載っているのとほぼ同じですが、PATHの指定を並列テストを考慮した作りにしています。

module WaitForDownload
  PATH = Rails.root.join("tmp/download#{ENV['TEST_ENV_NUMBER']}")

  def wait_for_download
    Timeout.timeout(Capybara.default_max_wait_time) do
      sleep(0.1) until downloaded?
    end
  end

  def downloads(pattern="*")
    Dir.glob(PATH.join(pattern))
  end

  def downloaded?
    !downloading? && downloads.any?
  end

  def downloading?
    downloads.grep(/\.crdownload\z/).any?
  end

  def clear_downloads
    FileUtils.rm_rf(downloads)
  end
end

RSpec.configure do |config|
  config.include WaitForDownload, type: :feature

  config.after :each, type: :feature do
    clear_downloads
  end
end

利用法

click_button 'Excelダウンロード'
wait_for_download
expect(downloads('*.xlsx').size).to eq 1

参考URL