如何使用Capybara和Dropzone.js测试上传文件?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

我已经切换到使用Dropzone.js插件进行拖放文件上传。如何编写Capybara测试以确保此功能继续工作?

以前我有一个带有输入文件元素的模板:

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

测试很简单:

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

但是这不再有效,因为Dropzone没有可见的文件输入。

提问于
用户回答回答于

要解决此问题,请模拟放置事件以触发将附件丢弃到Dropzone。首先将此函数添加到步骤定义中:

# 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

然后测试:

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

注意:您需要加载jQuery,Dropzone元素需要dropzone类。

用户回答回答于

如果有人有兴趣,我将@ deepwell的函数移植到javascript,将其与javascript风格的selenium一起使用:

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);
  });
};

扫码关注云+社区

领取腾讯云代金券