Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
981 views
in Technique[技术] by (71.8m points)

ruby on rails - How to test CSV file download in Capybara and RSpec?

The following is in the controller:

respond_to do |format|
  format.csv  { send_data as_csv, type:'text/csv' }
end

In spec:

click_link 'Download CSV'
page.driver.browser.switch_to.alert.accept

expect( page ).to have_content csv_data

But this doesn't work:

Failure/Error: page.driver.browser.switch_to.alert.accept
Selenium::WebDriver::Error::NoAlertPresentError: No alert is present

I see the Save File dialog box display, but apparently it is not an "alert" dialog.

How to click OK and get Capybara to see the data?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Adapted from CollectiveIdea and another source.

Works on OSX. Firefox 34.0.5

Spec:

  describe 'Download CSV' do
    let( :submission_email ){ 'foo@example.com' }
    let( :email_csv ){ "id,email,created_at
1,#{ submission_email }," }

    specify do
      visit '/emails'
      expect( page ).to have_content 'Email Submissions'

      click_on 'Download CSV'

      expect( DownloadHelpers::download_content ).to include email_csv
    end
  end

Spec helper:

require 'shared/download_helper'

Capybara.register_driver :selenium do |app|
  profile = Selenium::WebDriver::Firefox::Profile.new
  profile['browser.download.dir'] = DownloadHelpers::PATH.to_s
  profile['browser.download.folderList'] = 2

  # Suppress "open with" dialog
  profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
  Capybara::Selenium::Driver.new(app, :browser => :firefox, :profile => profile)
end

config.before( :each ) do
    DownloadHelpers::clear_downloads
end

shared/download_helper.rb:

module DownloadHelpers
  TIMEOUT = 1
  PATH    = Rails.root.join("tmp/downloads")

  extend self

  def downloads
    Dir[PATH.join("*")]
  end

  def download
    downloads.first
  end

  def download_content
    wait_for_download
    File.read(download)
  end

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

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

  def downloading?
    downloads.grep(/.part$/).any?
  end

  def clear_downloads
    FileUtils.rm_f(downloads)
  end
end

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...