Я считаю, что XPath вы хотите
page.should have_xpath("//a[text()='#{link}' and @href='#{url}']")
Я не знаком с огурцами, но если она опирается на Капибара, то has_link?
альтернативой было предложено @shioyama легче читать:
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
, который устраняет двусмысленность formatti ng 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
Обновление 19 сентября 2012 года: добавлено «normalize-space» к has_exact_link
, поэтому он будет игнорировать пробелы ведущего и конечного пробелов, как это делает HTML. Это необходимо, если, например, текст вашей ссылки находится на другой строке, кроме тега <a>
, например.
<a href="/contacts/3">
Contact 3
</a>
Он по-прежнему не соответствует подстрокам. Чтобы соответствовать указанному выше, вы должны указать has_exact_link("Contact 3")
, а не только has_exact_link("Contact")
.
Update 20 сентября 2012 Еще has_exact_link
обновление, выше. Теперь он выполняет проверку типов по параметру options
и обрабатывает опцию :count
, а также :href
.
спасибо за это. Я знал, что, должно быть, был лучший способ, но has_link ускользнул от меня. Книга огурца упоминает has_content, но не has_link. очень признателен. – starfry
Методы Capybara не являются документированными. Непосредственная проверка спецификаций - это самый надежный способ получить ответы на эти вопросы. –
Вы можете получить идеи из спецификаций, но они не являются исчерпывающими. Например, на данный момент ни спецификации, ни документы не говорят вам, что 'has_link?' Фактически ищет в текстовом поле, а также атрибуты id, title и img alt. Я нашел это после долгого отладочного сеанса, который привел меня в [этот исходный код XPath] (https://github.com/jnicklas/xpath/blob/master/lib/xpath/html.rb#L14). –