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

时间:2013-05-23 19:27:53

标签: css ruby-on-rails xpath cucumber capybara

我有一个使用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 个答案:

答案 0 :(得分:10)

Capybara 2.1 doesn't find hidden elements by default

您可以将ignore_hidden_elements设置为false:

Capybara.ignore_hidden_elements = false

或为您的方法添加:visible选项:

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

我更喜欢第二个变体,因为在大多数情况下,在测试中找到的元素是可见的,如果其中一个被隐藏,最好让Capybara抛出异常。

注意:大多数内部使用:visible的Capybara方法也支持Capybara::Query选项(例如findallhas_css?,{{ 1}}等等。)

答案 1 :(得分:1)

这里的要点是:dropzone仅使用输入字段作为标记或回退。它从dom中删除它。如果在成功执行dropzone初始化后检查页面源,您将无法再找到该元素。

所以它不是关于一个隐藏的输入字段,而是关于一个已删除的'已经消失'并且由于它不再是dom的一部分而无法找到。

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

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

这将使您的表单与dropzone后备模式一样。

答案 2 :(得分:1)

由于我不得不帮助某人解决这个问题,这是当前版本的Capybara和dropzone.js的更新答案。

默认情况下,Dropzone会在初始化时向页面正文添加一个隐藏文件字段,其中包含一个&#39; dz-hidden-input&#39;。要将文件添加到测试目的,您可以执行

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

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

答案 3 :(得分: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'))

答案 4 :(得分: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或者黄瓜+水豚

为什么不使用:js =&gt;是的,这将有助于找到隐藏的元素..

答案 5 :(得分:0)

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

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

type =“file”就是你想要的。 type =“hidden”的输入应该只接受一个字符串。

我也试图在rspec / capybara中测试dropzone.js区域并撞墙。你有没有想到这个?

我在这里尝试解决方案,没有运气:Using Selenium to imitate dragging a file onto an upload element

答案 6 :(得分:0)

您不需要添加新的页面执行,您需要做的就是找到.dz-hidden-input和attach_file ...

   attach_file("path/to/file", class: "dz-hidden-input", make_visible: true)

答案 7 :(得分:-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]"