如何让Capybara通过其标签检查复选框

时间:2014-04-24 21:58:39

标签: ruby-on-rails capybara rspec-rails

Capybara没有找到我的复选框标签,我知道我正在用它的标签正确引用它。我做错了什么,或者这是Capybara的一个错误?

根据http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions:check,“可以通过姓名,ID或标签文本找到复选框。”

以下是我运行的请求规范部分:

describe "with valid information" do   

it_should_behave_like "all item pages"

before { valid_create_item }

it "should create an item" do
    expect { click_button submit }.to change(Item, :count).by(1)
end

describe "after saving the item" do
    before { click_button submit }

    it { should have_link('Sign out') }
    it { should have_selector('h1', text: "Items") }
    it { should have_title("Items") }
    it { should have_success_message }
end      

describe "and options selected" do

    before do
        puts page.html
        check('Option 1')
        click_button "Save changes"
    end

    it { should have_title("Items") }
    it { should have_success_message }
    it { should have_link('Sign out', href: signout_path) }
    specify { expect(item.reload.options.find_by_name("Option 1")).to eq true }
end

以下是测试结果的要点,包括为页面生成的html:https://gist.github.com/anonymous/11270055

根据测试结果,Capybara在生成的html中显然没有找到标有“Option 1”的复选框。

作为旁注,我还注意到当我让rails FormHelper显示字段的默认标签文本时,我可以用Capybara 填写表格。

例如:名为“email_address”的字段的FormHelper标签文本显示为“电子邮件地址”,fill_in "Email address", with: "blahblah@blah.com"有效。如果我不使用FormHelper生成标签,而是将标签设为“电子邮件”,则fill_in "Email", with: "blahblah@blah.com"不起作用,因为Capybara无法找到标有“电子邮件”的字段。看起来这种行为与所有表单元素一致(或至少与文本字段和复选框一致 - 到目前为止我测试过的唯一表单元素。)

3 个答案:

答案 0 :(得分:1)

您是否尝试过直接根据输入进行操作?

<div class="control-group offset2"> 
<label class="control-label" for="__Option:0x000001061be660_">Option 1</label>
<div class="controls">
<input id="options_" name="options[]" type="checkbox" value="1" />
/div>
</div>

如果您想进一步调试,可以在检查之前添加binding.pry,然后运行一些capybara节点检查命令,看看它是否能够实际检测到该元素。

如果你不想使用撬,你可以做一个

puts all('.control-label', text: 'Option 1').size

如果它返回1,则检测到它,因此你可以做一个

find('.control-label', text: 'Option 1').set(true)

Capybara的检查方法是:

File 'lib/capybara/node/actions.rb', line 78
def check(locator, options={})
  find(:checkbox, locator, options).set(true)
end

如果基于这样的标签不起作用,你可以尝试根据输入做这件事。

答案 1 :(得分:1)

选项1的html如下所示:

<label class="control-label" for="__Option:0x000001061be660_">Option 1</label>
<div class="controls">
  <input id="options_" name="options[]" type="checkbox" value="1" />
</div>

问题是标签和复选框没有正确关联:

  • 标签的for属性为&#34; __选项:0x000001061be660 _&#34;
  • 该复选框的id属性为&#34; options _&#34;

因此,Capybara找到了标签&#34;选项1&#34;,但没有找到与复选框关联的标签。

需要更新页面,以便标签for属性和复选框id属性匹配。例如:

<label class="control-label" for="__Option:0x000001061be660_">Option 1</label>
<div class="controls">
  <input id="__Option:0x000001061be660_" name="options[]" type="checkbox" value="1" />
</div>

答案 2 :(得分:1)

您也可以通过传递复选框的值作为选项,使Capybara找到复选框{/ 3}}。

代码为page.check(name, option: value),其中name是复选框的名称和值 - 其值。

这也适用于id而不是name