【问题标题】:Capybara, capybara-webkit and custom file upload formCapybara、capybara-webkit及自定义文件上传表单
【发布时间】:2013-06-26 00:42:34
【问题描述】:

我使用以下 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

还有很多其他的。一直以来,我都会遇到 Failed to click element at unknown position 错误。一旦我删除了与输入字段重叠的标签,使其可见并运行我的规范,一切都通过了。所以这里的问题是:

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

有没有什么办法可以让 Capybara 和 Capybara-webkit 驱动程序以某种理智的方式处理这种微妙的情况?

【问题讨论】:

  • 您能否展示您使用的样式标签的 CSS/JS,以便我可以重现此问题?
  • 这真的没有什么花哨的东西,只是普通的东西——jsfiddle.net/QUc4M/2(顺便说一句,它是自定义文件上传字段的一个干净完整的解决方案:-)
  • AFAIK 您无法将文件附加到 Selenium 中的不可见输入 - 请参阅 this section。我认为您应该在附加文件之前使文件输入可见。
  • 好在我没有使用 Selenium。
  • 我不确定这里发生了什么,但我注意到了两件事:(1)你没有关闭你的输入标签。不知道这对水豚是否重要。 (2) 在您的 jsFiddle 中,当我单击标签时(在 Firefox 22.0 中),文件对话框会打开两次。在第一个对话框上单击取消后,第二个对话框打开。

标签: ruby-on-rails capybara capybara-webkit poltergeist


【解决方案1】:

【讨论】:

  • 这是较新 Capybara 版本的最佳选择。
【解决方案2】:

试试这个

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

【讨论】:

    【解决方案3】:

    Matt Sanders 建议使用 JS 来切换元素的可见性。这行得通,但这是另一个更清洁的解决方案,IMO。

    我建议仅在必要时才包含隐藏字段。为了做到这一点,我 当您真正希望 Capybara 包含这些罕见的情况时,使用此助手 隐藏字段。例如:

    # 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)
    

    【讨论】:

    • not in field被隐藏的问题;存在问题是因为表单字段被标签覆盖。所以不行;在这种情况下,您的解决方案将不起作用。
    【解决方案4】:

    使用 capybara-webkit,您可以告诉驱动程序在页面上下文中运行您想要的任何 javascript,因此您可以编写一些自定义内容来解决可见性问题:

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

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

    也就是说,每次(至少我)在我的测试中做一些像这样粗暴的事情时,最好花点时间询问一下是测试还是界面需要修复。如果您对界面感到满意,您应该能够使用像上面这样的小型 js sn-p 来让元素对您的测试可见。

    更新:

    对这种行为的支持变得更加广泛,并且现在在 capybara 中已标准化,因此您可以:

    page.execute_script(script)
    

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

    还有一种合伙人方法,evaluate_script

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

    希望这会有所帮助!

    【讨论】:

    • 终于有答案了!非常感谢——你刚刚保存了我的测试!是的,当然解决方案有点不干净,但它正在工作,而且这个解决方案让我的生产代码保持干净;这比干净的测试代码更重要。
    • 同意,最好在测试方面做出牺牲。乐意效劳! :-)
    【解决方案5】:

    对其他人来说,可能会觉得这很有用:

    有时候'toggle'是不够的,那就检查'opacity'(不应该为零):

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 1970-01-01
      • 2013-02-28
      • 2017-05-18
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多