在Capybara表的复杂断言

时间:2013-01-25 17:54:14

标签: cucumber capybara

我的应用中有一张桌子。

enter image description here

使用Capybara和Cucumber,我如何断言价值4.5和1.1只发生在Mike的行中?
在Capybara有这样的主张吗?

谢谢!

2 个答案:

答案 0 :(得分:5)

您可以使用within来搜索特定值的范围:

例如,要声明值4.5发生在Mike的第二列中,请尝试以下操作:

within("table tr:nth-child(2)") do
  find("td:nth-child(2)").text.should == 4.5
end

如果您愿意,可以将它们包装在辅助方法中以方便使用:

def within_row(num, &block)
  within("table tr:nth-child(#{num})", &block)
end

def column_text(num)
  find("td:nth-child(#{num})").text
end

现在你可以通过以下方式对Mike的行做出相同的断言:

within_row(2) do
  column_text(2).should == 4.1
end

希望你会发现其中一种技术对你想要做的事情有用。

答案 1 :(得分:3)

是的,这是可能的,也很简单:

def td_text(n)
  find(:xpath, "./td[#{n}]").text
end

h = {2 => 4.5, 3 => 1.1}

all('table tr').each do |row|
  within row do
    if td_text(1) == 'Mike'
      h.each { |i, value| td_text(i).should == value.to_s }
    else
      h.each { |i, value| td_text(i).should_not == value.to_s }
    end
  end
end

您可以使用full script进行测试

更新:我想的更多。上面的代码会非常慢,因为find中的texttd_text的每次调用都会向浏览器发出新的查询。

我看到的减轻它的唯一方法是使用JS和Nokogiri:

source = page.evaluate_script("document.getElementsByTagName('table')[0].innerHTML")

doc = Nokogiri::HTML(source)

def td_text(row, n)
  row.xpath("./td[#{n}]").text
end

h = {2 => 4.5, 3 => 1.1}

doc.css('tr').each do |row|
  if td_text(row, 1) == 'Mike'
    h.each { |i, value| td_text(row, i).should == value.to_s }
  else
    h.each { |i, value| td_text(row, i).should_not == value.to_s }
  end
end

代码的第一个变体在我的机器上运行大约200毫秒,而第二个代码在8毫秒内运行。好的优化!