Search code examples
ruby-on-railsselenium-webdrivercapybaraminitestsystem-testing

Cannot check file downloaded in Rails system test


I have a big problem with Rails system test, so I need your help. Thanks a lot! System test was implemented by using Selenium Capybara.

In application_system_test_case.rb, I have this code:

require "test_helper"
require "selenium/webdriver"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase

  DOWNLOAD_PATH = Rails.root.join("/home/seluser/Downloads").to_s

  Capybara.register_driver :chrome do |app|
    profile = Selenium::WebDriver::Chrome::Profile.new
    profile["download.default_directory"] = DOWNLOAD_PATH
    Capybara::Selenium::Driver.new(app, :browser => :chrome, :profile => profile)
  end

  Capybara.default_driver = Capybara.javascript_driver = :chrome
  driven_by :chrome, using: :chrome,  screen_size: [1400, 1400]
end

In check_download_csv_test.rb, I have this code:

test "can we export the file and are all fields in the header" do
  visit partners_path
  click_link "Export"
  sleep 1
  full_path = DOWNLOAD_PATH+"/partners-#{Date.today}.csv"
  assert File.exist?(full_path)
  headers = CSV.open(full_path, 'r') { |csv| csv.first.to_s }
  assert_equal(headers,"[\"id\", \"name\", \"partner_type_id\", \"parent_id\", \"phone\", \"website\"]","Header does not match")
end

The system test will be run on Chrome browser simulated. Hmmm... I will try my best to describe my problem. When I run system test written by Minitest. In Chrome browser, I see the csv file was downloaded and stored in path: /home/seluser/Downloads. But the test case was failure in line: assert File.exist?(full_path) Hmm... That's scrazy. I cannot understand where is wrong. This means there is no file stored in this path.

I also prefer many way in Internet but it's not work. This is my environment: Ruby: 3.1.4 Rails: 6.1.7.6 WebDriver: 4.13.1 I really appreciate your help. Thanks so much <3


Solution

  • The problem you are experiencing is that when defining your DOWNLOAD_PATH you are using Rails.root, which will take as a path the directory where you have your application installed, and to that directory you are adding 'home/...etc'. Unless your application is in the root directory, that will give you an error.

    Rails.root: This method returns a Pathname object which handles paths starting with a / as absolute (starting from the root of the filesystem). Compare:

    >> Rails.root
    => #<Pathname:/some/path/to/project>