1

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

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

除了那行不通。xpath 语法不正确,我一直在努力寻找语法的良好解释。

谢谢!

4

2 回答 2

3

我相信你想要的 XPath 是

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

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

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

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

  • 它搜索子字符串(您的 XPath 示例搜索完全匹配)。
  • 它在文本值中搜索“链接”,但也在id、title 和 img alt 字段中搜索。
  • 如果您将其他属性指定为选项,例如:textor :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 日更新:在上面 添加了“normalize-space” 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.

于 2012-09-18T01:20:10.333 回答
2

那将是:

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

有关详细信息,请参阅水豚规范

于 2012-08-31T11:18:54.683 回答