我使用rspec 2.6.0和Capybara 1.1.1进行验收测试 有如下视图:
<tr >
<td>Team 3 Name</td>
<td>true</td>
<td><a href="/teams/3">Show</a></td>
<td><a href="/teams/3/edit">Edit</a></td>
<td><a href="/teams/3">Deactivate</a></td>
</tr>
<tr >
<td>Team 4 Name</td>
<td>true</td>
<td><a href="/teams/4">Show</a></td>
<td><a href="/teams/4/edit">Edit</a></td>
<td><a href="/teams/4">Deactivate</a></td>
</tr>
我想写一个验收测试,其中说:“团队3没有'停用'链接。”我希望以下内容失败:
within('tr', :text => 'Team 3 Name') do |ref|
page.should_not have_selector('a', :text => 'Deactivate')
end
但它过去了。为了进一步测试正在发生的事情,我写了荒谬的话:
lock = false
within('tr', :text => 'Team 3 Name') do |ref|
page.should have_selector('a', :text => 'Deactivate')
page.should_not have_selector('a', :text => 'Deactivate')
lock = true
end
lock.should be_true
也通过了。
我假设has_selector()调用的范围不受within()块的限制,但我不确定为什么会这样。水豚文档使用这种模式,似乎没有提到任何陷阱。 在内部使用以限制我的选择范围的正确方法是什么? 谢谢。 / Salernost
答案 0 :(得分:12)
我自己还在学习Capybara,但您尝试过have_link
而不是have_selector
吗?另外我认为你不需要|ref|
。例如:
lock = false
within('tr', :text => 'Team 3 Name') do # omit |ref|
page.should have_link('Deactivate')
page.should_not have_link('Deactivate')
lock = true
end
lock.should be_true
<小时/> 2012年10月13日更新
与Capybara进一步讨论后,我在这里看到了几个潜在的问题:
within
可能会默默地忽略text
字段。您会注意到这些示例仅显示没有其他参数的CSS或XPath查找程序。within
确实使用text
,则可能无效,因为您要求它查看<tr>
,但文字位于<td>
。< / LI>
page
区块内,within
主题很可能仍然以整个网页为目标。 within
示例主要是关于使用fill_in
或click
。例外是Beware the XPath // trap下的示例。至于创建within
块,您可以为表行提供唯一的ID并使用CSS搜索它们,或者您可以编写针对第一个匹配行的特定XPath。
后者的问题是您要使用within
上的<tr>
,但您用于定位的文字位于<td>
子元素内。因此,例如,此XPath应该找到包含文本Team 3 Name
的表格单元格,但是您只对第一个单元格而不是整行进行within
。
within(:xpath, "//tr/td[normalize-space(text())='Team 3 Name'") do
有很多方法可以使用XPath“备份”到父元素,但我不知道如何做到这一点,我读到这不是一个好习惯。我认为你最好的选择就是生成id,这样你的行就会这样开始:
<tr id="team_3">
然后用简单的
来定位它们within("tr#team_3")
答案 1 :(得分:5)
我还建议Mark Berry他提到的为每个表元素添加id的最终方法。
<tr id="team_3">
然后以
为目标within("tr#team_3")
Capybara在选择xpath时给了我一些问题,因为它似乎并不一致,尤其是CI服务。
我还想在本节中注明相同的答案:
即使您在一个内部区域,页面主题仍然可以定位整个页面。内部示例主要是关于使用fill_in或click。例外情况是Beware the XPath // trap。
在旧版本中可能就是这种情况,但在当前版本的Capybara中,在page
块内部调用within
仅检查目标页面的部分。所以,使用Mark上面的例子:
within("tr#team_3") do
expect(page).to have_content 'Team 3 Name'
# => true
expect(page).to have_content 'Team 4 Name'
# => false
end
答案 2 :(得分:4)
have_selector
似乎忽略了:text
和:content
选项。我不得不使用这样的东西:
within 'a' do
page.should have_content 'Deactivate'
end
答案 3 :(得分:3)
解决方案是不使用within
方法:
expect(page).to have_css('tr#team_3') do
without_tag('a', text: 'Deactivate')
end