Comment tester le téléchargement d'un fichier avec Capybara et Dropzone.js?

je suis passé à l'utilisation du Dropzone.js plugin pour les téléchargements de fichiers glisser-déposer. Comment puis-je écrire un test Capybara pour m'assurer que cette fonctionnalité continue de fonctionner?

précédemment j'avais un template avec un élément de fichier input:

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

Et le test était simple:

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

cependant cela ne fonctionne plus car Dropzone n'a pas d'entrée de fichier visible.

11
demandé sur deepwell 2015-10-01 09:10:03

2 réponses

pour résoudre ceci, simuler une chute même pour déclencher la chute d'une attache sur la zone de chute. Ajoutez d'abord cette fonction à votre définition de pas:

# 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

puis tester avec:

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

NOTE: vous devez charger jQuery, et L'élément Dropzone nécessite le dropzone classe.

17
répondu deepwell 2015-10-01 06:10:03

au cas où quelqu'un serait intéressé, j'ai porté la fonction de @deepwell en javascript, pour l'utiliser avec du sélénium aromatisé javascript:

this.dropInDropzone = function(filePath) {
  var script = "fakeFileInput = $('#fakeFileInput'); if (fakeFileInput.length === 0) fakeFileInput = window.$('<input/>').attr({id: 'fakeFileInput', type:'file'}).appendTo('body');";
  // Generate a fake input selector
  return driver.executeScript(script).then(function() {
    // Attach the file to the fake input selector
    return driver.findElement(webdriver.By.css('#fakeFileInput')).sendKeys(filePath);
  }).then(function() {
    // Add the file to a fileList array
    return driver.executeScript("var fileList = [fakeFileInput.get(0).files[0]]");
  }).then(function() {
    // Trigger the fake drop event
    script = "var e = jQuery.Event('drop', { dataTransfer : { files : [fakeFileInput.get(0).files[0]] } }); $('.dropzone')[0].dropzone.listeners[0].events.drop(e);"
    return driver.executeScript(script);
  });
};
3
répondu ppires 2016-07-06 23:23:56