2

I am trying to test a download using Capybara and Cucumber.

The test steps look like:

When(/^I export to CSV$/) do
  export_button = find("div.results-table input[type=\"submit\"]")

  export_button.click
end

Then(/^I should be prompted to download the CSV$/) do
  Capybara.current_driver = :webkit #switch driver so we can see the response_headers
  page.response_headers['Content-Disposition'].should include("filename=\"transactions\"")
end

I had to add the capybara webkit driver in the middle of the test so that I can use the response_headers, but the response_headers seem to return an empty object. I am using the default driver before that because I need to click the button, but I wonder if switching drivers like this is why I am not getting anything in the response_header?

yoyodunno
  • 617
  • 1
  • 8
  • 19
  • 1
    You can't just swap drivers mid test. Each driver communicates with its own browser and maintains it's own state, etc. You need to use one driver for the whole test. – Thomas Walpole Jan 27 '16 at 21:25
  • Ahh I see. I thought you could temporarily, it vaguely said that here https://github.com/jnicklas/capybara#selecting-the-driver Do you know where I can set webkit as the driver for the whole test? I can't seem to find where I set it. – yoyodunno Jan 27 '16 at 21:54
  • 1
    You can change driver per test (scenario, example whatever you want to call it) but you can't change it mid test. If you're using the standard cucumber capybara setup you should just be able to tag the specific test/scenario/example with @webkit (or whatever driver name you want) - see: https://github.com/jnicklas/capybara/blob/master/lib/capybara/cucumber.rb#L19 – Thomas Walpole Jan 27 '16 at 22:02
  • Ok I added the @webkit on the scenario and had the issue that I get the error unable to find CSS "div.results-table input[type=\"submit\"]" (Capybara::ElementNotFound) For some reason webkit won't let my find method work! – yoyodunno Jan 27 '16 at 22:44
  • 1
    Is it visible on the page? Webkit actually processes CSS and runs JS unlike the default rack-test driver, so if the input is hidden vis CSS it won't find it - also I assume you have a step that visits the page, etc – Thomas Walpole Jan 27 '16 at 23:10
  • Yeah the button is visible, it's the Export to CSV button on this page http://query.mrr.devtechlab.com/ I do have a step that visits the page, the button gets clicked just fine when I use the default driver. But, the browser doesn't pop up when I use the webkit driver, which is the correct behavior for webkit? – yoyodunno Jan 27 '16 at 23:33
  • 1
    Ok -- since you're saying that a browser pops up - I'm going to assume that by default driver you mean selenium. The capybara-webkit driver is headless so it won't pop up a browser. Taking a quick look at that page I can see it's built with reactJS - if you built capybara-webkit with Qt 4.x it doesn't have Function.prototype.bind() so reactJS doesn't work with it. You'll need to build capybara-webkit with something like Qt 5.5.1 - see the capybara-webkit project for details – Thomas Walpole Jan 27 '16 at 23:38
  • Yes installing Qt5 worked, thank you!! I also had to uninstall capybara, capybara-webkit to get Qt5 working like described here http://stackoverflow.com/questions/17075380/can-i-use-homebrews-qt5-with-capybara-webkit – yoyodunno Jan 28 '16 at 00:21

1 Answers1

1

I have done it in my recent project as shown below

Given Download folder for export is empty
And   Joe clicks "Download Csv" button
Then  The contents of the downloaded csv should be:
|TEAM_ID | TEAM_EXTERNAL_ID | TYPE | REG_OPTION      | TEAM_REG_BRACKET | RACE_NAME  | WAVE      | BIB | BRACKET | STATUS    | TEAM_NAME | TEAM_TYPE | ATHLETE_COUNT | MIN_MEMBERS  | MAX_MEMBERS | TEAM_MEMBERS |
|    8   |                  | TEAM | 10k Aggregate   | N/A              | 10k        | Universal | 208 | Overall | DNF       | Team 08   | Aggregate |0              |              |             |              |

And the capybara for this cucumber will be like

Given(/^Download folder for export is empty$/) do
  FileUtils.rm_rf('/home/vagrant/Downloads/')
end

And(/^(\S*) clicks "([^"]*)" button$/) do |user, arg|
  button = find_button(arg)
  button.click
end

And /^The contents of the downloaded csv should be:$/ do |table|
  for i in 0..5
      if(Dir.glob('/home/vagrant/Downloads/*.csv'))
        break;
      end
      sleep(1); // if not found wait one second before continue looping
  end

  if(Dir.glob('/home/vagrant/Downloads/*.csv'))
    Dir['/home/vagrant/Downloads/*'].each do |file_name|
      arr = CSV.read(file_name, :col_sep => "\t", :row_sep => "\r\n", encoding: "UTF-16:UTF-8")
      table.raw[0...table.raw.length].each_with_index do |row, row_index|
        row.each_with_index do |value, index|
          if arr[row_index][index] == nil
            arr[row_index][index] = ""
          end
          if index == 1
          else
            puts "#{index}" + 'Value in table = ' + "#{value} + 'Value in file' + #{arr[row_index][index]}"
            value.should eq arr[row_index][index]
          end
        end
      end
    end
  else
    puts "/home/vagrant/Downloads/*.csv file not found!"
  end
end

Hope this resolves you problem for downloading CSV and verifying its contents too :)

Sarabjit Singh
  • 786
  • 4
  • 4
  • Thanks. The only issue I have with clicking the download button is how do I click the browser's download prompt that pops up to do the download? – yoyodunno Feb 08 '16 at 19:02