如何使用Rails、Cucumber和Capybara测试Dropzone.js上传功能?

8

我有一个使用Cucumber和Capybara进行测试的Rails项目。我有一个使用Dropzone.js的文件上传页面。

在对话框或拖放上传时,我的上传功能非常好用。但是测试则另当别论。

我的表单中有以下字段:

<input id="photo_image" multiple="multiple" name="image" type="hidden">

然而,在步骤定义中,我尝试了几种查找和附加文件数据的方法,但都没有成功。

我尝试了 fill_in:

fill_in "photo_image",  with: photo

我尝试使用CSS选择器进行查找:

find('#photo_image').set photo

我尝试使用xpath查找:

find(:xpath, "//input[@id='photo_image']").set photo

但他们都看不到隐藏的字段。
Unable to find css "#photo_image" (Capybara::ElementNotFound)

Unable to find xpath "//input[@id='photo_image']" (Capybara::ElementNotFound)

Unable to find field "photo_image" (Capybara::ElementNotFound)

有没有一种测试方法可以处理使用Dropzone.js上传的内容,还是说无望了?
8个回答

11

Capybara 2.1默认情况下无法找到隐藏的元素。您可以在此处查看更多信息

您可以将ignore_hidden_elements设置为false:

Capybara.ignore_hidden_elements = false

或者向您的方法添加:visible选项:

attach_file('photo_image', path_to_file, visible: false)

在大多数情况下,测试中要查找的元素是可见的,因此我更喜欢第二个变体,最好保持Capybara如果其中一个元素隐藏了就抛出异常。

注意:大多数Capybara方法也支持:visible选项,这些方法在内部使用Capybara :: Query(如findallhas_css?have_selector等)。


另外,就像下面的一个答案提到的那样,对于这样的测试,请确保设置 :js => true - bbbco
我尝试将visible设置为false,但attach_file仍然找不到它。奇怪的是,在attach_file上面立即添加了一行代码来查找,它可以很好地找到输入字段。我查看了源代码,并发现attach_file也在进行查找,但我不明白为什么attach_file的查找无法找到输入字段。 - David Watson
@DavidWatson 这很奇怪。请回答以下三个问题:1. 您使用的Capybara版本是哪个?2. 您的驱动程序是什么?3. 您是否尝试过Capybara的attach_file调用的确切find方法:find(:field,'photo_image') - Andrei Botalov
我已经尝试过使用selenium、chrome和poltergeist驱动程序。capybara(2.1.0)和capybara-webkit(1.0.0 9bbf4f6)。我很快会尝试exact find方法。 - David Watson

4

我刚帮助了一个人解决这个问题,这是针对当前版本的Capybara和dropzone.js的更新答案。

默认情况下,Dropzone在初始化时将一个class为“dz-hidden-input”的隐藏文件字段添加到页面的body中。要添加文件以进行测试,您可以执行以下操作:

attach_file(file_path, class: 'dz-hidden-input', make_visible: true)

解释:由于没有已知的id/name/label文本,因此我们不传递定位器,而是传递class选项以限制找到具有指定类的文件输入。然后,我们指定make_visible:true,让Capybara临时更改CSS,使文件输入变为可见状态,添加文件,然后恢复原始CSS。


1
Dropzone.js使用下一个输入框来附加文件(从我的网站获取):
<input type="file" multiple="multiple" class="dz-hidden-input" accept="image/*,application/pdf" style="visibility: hidden; position: absolute; top: 0px; left: 0px; height: 0px; width: 0px;">

所以,你只需要运行以下代码即可通过dropzone.js附加文件:

page.find('.dz-hidden-input', visible: false).set('file_path_here'))

1
这里的重点是:dropzone仅将输入字段用作标记或备用方案。它会从dom中删除它。如果您在成功初始化dropzone后检查页面源代码,则将无法再找到该元素。

因此,这不是关于隐藏输入字段,而是关于已删除的“已经消失”的输入字段,因为它不再是dom的一部分,所以无法找到它。

我最终做的是在规范中手动添加输入字段:

page.execute_script(%|$('#your-form').append('<input id="photo_image" name="image" type="file">');|)

这将使您的表单行为类似于拖放区回退模式。

1
您不需要添加新的页面执行,您只需要找到 .dz-hidden-input 并将其 attach_file...
   attach_file("path/to/file", class: "dz-hidden-input", make_visible: true)

0

你可以使用

it "should upload a file" do
  visit upload_file_path
  attach_file "uploadfile(id of field)", /path/to/file/to/upload
  click_button "Upload File"
end

do ... end 之间的步骤应该同时适用于 rspec + capybara 或 cucumber + capybara。

为什么不使用 :js => true 呢?这也可以帮助找到隐藏元素。


0

我认为Capybara没有找到是因为你没有创建文件字段。

<input id="photo_image" multiple="multiple" name="image" type="file">

你需要的是 type="file"。type="hidden" 的输入框只能接受字符串。

我也在尝试使用 rspec/capybara 测试 dropzone.js 区域,但遇到了困难。你解决了这个问题吗?

我曾尝试过这里的解决方案,但没有成功:使用 Selenium 模拟将文件拖放到上传元素上


-2

你的输入类型是隐藏的,请将其删除,因为capybara无法在浏览器上看到它。尝试这个,这对我有效:

web_steps.rb

When /^I attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
  attach_file(field, File.expand_path(path))
end

upload_picture.feature

 ###.....some other steps too
 When I attach the file "app/assets/images/default/accept.jpg" to "image[image]"

这个答案以最简洁的方式回答了问题,但在问题的上下文中是错误的。你有没有读到问题?OP说:“我正在使用Dropzone JS上传文件页面。” - Overbryd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接