Capybara在rspec测试中不匹配单选按钮

时间:2018-05-29 19:15:13

标签: ruby rspec capybara

我正在尝试使用rspec为Bootstrap表单编写测试。我有以下代码:

<div id="published" class="col-sm-auto">
  <div class="custom-control custom-radio custom-control-inline">
    <%= form.radio_button :published, true, checked: page.published?, class: 'custom-control-input' %>
    <%= form.label :published, 'Published', value: true, class: 'custom-control-label' %>
  </div>
  <div class="custom-control custom-radio custom-control-inline">
    <%= form.radio_button :published, false, checked: !page.published?, class: 'custom-control-input' %>
    <%= form.label :published, 'Hidden', value: false, class: 'custom-control-label' %>
  </div>
</div>

生成以下HTML:

<div id="published" class="col-sm-auto">
  <div class="custom-control custom-radio custom-control-inline">
    <input class="custom-control-input" type="radio" value="true" name="page[published]" id="page_published_true" />
    <label class="custom-control-label" for="page_published_true">Published</label>
  </div>
  <div class="custom-control custom-radio custom-control-inline">
    <input class="custom-control-input" type="radio" value="false" checked="checked" name="page[published]" id="page_published_false" />
    <label class="custom-control-label" for="page_published_false">Hidden</label>
  </div>
</div>

当我运行此测试时,它失败并显示消息

it 'should default to unpublished' do
  expect(page).to have_checked_field('Hidden')
end

发送消息expected to find visible field "page[published]" that is checked and not disabled but there were no matches. Also found "", "", which matched the selector but not all filters.

查看检查器中的HTML,该字段是可见的而不是禁用的,并且有一个与文本匹配的标签。我不知道这两个空字符串是什么。

请有人告诉我为什么have_checked_field不匹配?我真的不热衷于编写一个更脆弱的测试,使用has_csshas_xpath来查找具有特定ID的输入标记 - 整点是用户应该看到标记为“隐藏”的字段“无论幕后发生了什么,都应该进行检查!

1 个答案:

答案 0 :(得分:1)

我99.9%保证无线电输入实际上不可见,并且已经被使用CSS(可能还有一些JS)的图像所取代。你可以做到

expect(page).to have_checked_field('Hidden', visible: false)

或者您可以做一些稍微复杂的事情,以验证标签实际上是否可见,如

expect(page).to have_css('input:checked + label', exact_text: 'Hidden')

如果你正在处理很多这些单选按钮的另一个解决方案是编写类似

的自定义选择器类型
Capybara.add_selector(:bootstrap_radio) do 
  xpath do |locator|
    XPath.descendant(:input)[XPath.attr(:type) == 'radio'].following_sibling(:label)[XPath.string.n.is(locator)]
  end

  filter(:checked) do |node, value|
    node.sibling('input[type="radio"]', visible: :hidden).checked? == value
  end
end

然后允许你做

expect(page).to have_selector(:bootstrap_radio, 'Hidden', checked: true)

如果需要,你可以编写像have_checked_bootstrap_radio这样的辅助方法。注意:此代码不在袖口中,因此XPath / CSS表达式可能不是100%正确,但一般的想法是合理的:)