在黄瓜测试中检查链接的正确方法是什么?

时间:2012-08-31 11:04:16

标签: xpath cucumber

我一直无法找到这个问题的答案。我想在Cucumber中编写一个简单的步骤来检查页面上是否存在链接,并且它具有正确的文本和href。像这样:

Then /^I see the page with link "(.*?)" to "(.*?)"$/ do |link,url|
  page.should have_xpath("//a[text()='#{link}',@href='#{url}']")
end

除非不起作用。 xpath语法不正确,我一直在努力寻找语法的好解释。

谢谢!

2 个答案:

答案 0 :(得分:3)

我相信你想要的XPath是

page.should have_xpath("//a[text()='#{link}' and @href='#{url}']")

我不熟悉Cucumber,但如果它依赖于Capybara,@ shioyama建议的has_link?替代方案更容易阅读:

page.should have_link(link, :href => url)

然而,它看似简单。使用has_link?时,请记住:

  • 它搜索子字符串(您的XPath示例搜索完全匹配)。
  • 搜索"链接"在文本值中,但在id,title和img alt字段中。
  • 如果您将其他属性指定为选项,例如:text:class,他们会被默默地忽略。您可能认为自己正在缩小测试范围,但事实并非如此。

考虑以下HTML:

<a href="/contacts/3" data-confirm="Are you sure?" data-method="delete"
   title="Delete Contact 3">Delete</a>

我很惊讶地发现因为has_link?搜索title的子字符串,以下条件的符合该链接:

has_link?("Contact 3", href: "/contacts/3")
has_link?("Delete", href: "/contacts/3")

我目前正在尝试使用自定义has_exact_link匹配器,通过显式格式化XPath来消除歧义。它仅搜索文本值的完全匹配,而不是子字符串,除:href之外的任何选项都会引发错误:

<强>规格/支持/ matchers.rb

# Check for an <a> tag with the exact text and optional :href and  :count.
# Same param syntax as has_link, but it only matches the link's TEXT, not id,
# label, etc., and it doesn't match substrings.
def has_exact_link?(locator, options={})

  # Subtract :href, :count from array of options.keys
  # Raise error if any options remain
  raise ArgumentError.new \
    "options, if supplied, must be a hash" if !options.is_a?(Hash)
  raise ArgumentError.new \
    "has_exact_link only supports 'href' and 'count' as options" unless
    (options.keys - [:href] - [:count]).empty?
  href = options[:href]
  xpath = href ? "//a[normalize-space(text())='#{locator}' and @href='#{href}']" :
                 "//a[normalize-space(text())='#{locator}']/@href"
  # pass original options has so test results will show options if present
  # has_xpath apparently ignores :href in options but will use :count.
  has_xpath?(xpath, options)

end

2012年9月19日更新:已添加&#34; normalize-space&#34;到上面的has_exact_link所以它会像HTML一样忽略前导和尾随空格。例如,如果您的链接文字与<a>标记不在一行,则需要这样做,例如

<a href="/contacts/3">
  Contact 3
</a>

它仍然与子串不匹配。要匹配上述内容,您必须指定has_exact_link("Contact 3"),而不仅仅是has_exact_link("Contact")


2012年9月20日更新上面的另一个has_exact_link更新。现在它对options参数进行类型检查,并处理:count选项以及:href

答案 1 :(得分:2)

那将是:

page.should have_link(link, :href => url)

有关详细信息,请参阅capybara spec