Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you test uploading a file with Capybara and Dropzone.js?

I've switched to using the Dropzone.js plugin for drag-and-drop file uploads. How can I write a Capybara test to ensure this functionality keeps on working?

Previously I had a template with an input file element:

<input type="file" name="attachments">

And the test was simple:

When(/^I upload "([^"]*)"$/) do |filename|
  attach_file("attachments", File.expand_path(filename))
  # add assertion here
end

However this no longer works because Dropzone doesn't have a visible file input.

like image 943
deepwell Avatar asked Oct 01 '15 06:10

deepwell


People also ask

How does dropzone js work?

Dropzone. js is 'a light weight JavaScript library that turns an HTML element into a "dropzone"'. Users can drag and drop a file onto an area of the page, uploading to a server. If you would like to read more how all of this works skim through the Dropzone.

What is dropzone file upload?

js is one of the most popular drag and drop JavaScript libraries. It is free, fully open source, and makes it easy for you to handle dropped files on your website. It's meant to look good by default, and is highly customizable. Documentation Download.


1 Answers

To solve this, simulate a drop event to trigger dropping an attachment onto Dropzone. First add this function to your step definition:

    # Upload a file to Dropzone.js
    def drop_in_dropzone(file_path)
      # Generate a fake input selector
      page.execute_script <<-JS
        fakeFileInput = window.$('<input/>').attr(
          {id: 'fakeFileInput', type:'file'}
        ).appendTo('body');
      JS
      # Attach the file to the fake input selector
      attach_file("fakeFileInput", file_path)
      # Add the file to a fileList array
      page.execute_script("var fileList = [fakeFileInput.get(0).files[0]]")
      # Trigger the fake drop event
      page.execute_script <<-JS
        var e = jQuery.Event('drop', { dataTransfer : { files : [fakeFileInput.get(0).files[0]] } });
        $('.dropzone')[0].dropzone.listeners[0].events.drop(e);
      JS
    end

Then test with:

    When(/^I upload "([^"]*)"$/) do |filename|
      drop_in_dropzone File.expand_path(filename)
      # add assertion here
    end

NOTE: You need to have jQuery loaded, and the Dropzone element requires the dropzone class.

like image 193
deepwell Avatar answered Sep 24 '22 16:09

deepwell