水豚,水豚网络工具包和自定义文件上传表单



我使用以下html堆栈创建了自定义上传表单:

<form>
  <label></label>
  <input type="file">
</form>

文件字段通过具有display: none属性的css隐藏。因此,当用户点击标签(这是自定义样式的)时,就会调用文件附加对话框。

在我的功能测试中,我无法附加文件,因为输入字段是隐藏的。我尝试了几种可能的解决方案,但都不起作用:

find(:xpath, '//input', visible: false).set(some_file_path)

within('form') do                                                                                                                                                                       
  attach_file(:input, some_file_path, visible: false)                                                                                                                                          
end

还有许多其他人。一直以来,我都以失败点击未知位置的元素错误告终。一旦我删除了与输入字段重叠的标签,使其可见,并运行我的规范,一切都通过。因此,这里的问题是:

  1. 输入文件字段具有display: none属性(因此找不到)
  2. 有一个标签与隐藏文件字段重叠(可能)

有什么方法可以让Capybara和Capybara网络工具包驱动程序以某种理智的方式处理这种微妙的情况吗?

使用capybara webkit,您可以告诉驱动程序在页面上下文中运行任何您想要的javascript,这样您就可以编写一些自定义的东西来破解可见性问题:

script = "$('thelabel').toggle(); " # hide the label
script << "$('myfield').toggle();"  # show your field
page.driver.browser.execute_script(script)

这是伪代码,但在调用attach_file之前,您应该能够执行类似的操作,使字段可见

也就是说,每次(至少我)在测试中做这样有点恶心的事情时,花点时间问一下是测试还是接口需要修复是个好主意。如果你对这个接口很满意,你应该能够使用像上面这样的小js片段来让元素在测试中可见。

更新:

对这种行为的支持已经变得更加广泛,现在在水豚中已经标准化了,所以你可以:

page.execute_script(script)

这个较短的版本应该适用于capybara 2.x和最近版本的capybara webkit或poltergeist,这是我现在使用的一个依赖性较低的替代方案。

还有一种伙伴方法evaluate_script:

result = page.evaluate_script('4 + 4');

希望这能有所帮助!

Matt Sanders建议使用JS来切换元素的可见性。这会起作用,但这里有另一个更干净的解决方案,IMO.

我建议仅在必要时才包括隐藏字段。为了做到这一点,我当你真的想让水豚包括在内时,在那些罕见的情况下使用了这个助手隐藏字段。例如:

# features/support/capybara_helpers.rb
module CapybaraHelpers
  # By default, capybara will ignore all hidden fields. This is a smart default
  # except in rare cases. For example, our AS3 file uploader requires you to
  # click a hidden file field - and that makes perfect sense. In those rare
  # cases, you can use this helper to override the default and force capybara
  # to include hidden fields.
  #
  # Examples
  #
  #   include_hidden_fields do
  #     attach_file("hidden-input", "path/to/fixture/file")
  #   end
  #
  def include_hidden_fields
    Capybara.ignore_hidden_elements = false
    yield
    Capybara.ignore_hidden_elements = true
  end
end
World(CapybaraHelpers)

现在有了一个选项"make_visible"https://www.rubydoc.info/github/jnicklas/capybara/Capybara/Node/Actions%3Aattach_file

对于其他人来说,可能会发现这很有用:

有时"切换"是不够的,然后检查"不透明度"(不应该为零):

script = "$('#file-field').css({opacity: 100, display: 'block'});"
page.driver.browser.execute_script(script)

试试这个

file_field = page.find('input[type="file"]', visible: false) file_field.set('path/to/my/image.jpg')