Як натиснути перше посилання у списку елементів після оновлення до Capybara 2.0?


125

Як натиснути перше посилання в цьому випадку:

<div class="item">
  <a href="/agree/">Agree</a>
</div>
<div class="item">
  <a href="/agree/">Agree</a>
</div>
within ".item" do
  first(:link, "Agree").click
end

і я отримую цю помилку:

Capybara::Ambiguous:
  Ambiguous match, found 2 elements matching css ".item"

І без цього withinя отримую цю помилку:

Failure/Error: first(:link, "Agree").click
NoMethodError:
  undefined method `click' for nil:NilClass

Відповіді:


176

Ви можете просто використовувати:

first('.item').click_link('Agree')

або

first('.item > a').click

(якщо ваш вибір за замовчуванням: css)


Код у вашому запиті не працює так:

within ".item" do
  first(:link, "Agree").click
end

еквівалентно:

find('.item').first(:link, "Agree").click

Капібара знаходить декілька .item, тому вона створює виняток. Я вважаю таку поведінку Capybara 2 дуже хорошою.


4
Я б рекомендував не використовувати #first, він не чекає існування елемента: rubydoc.info/github/jnicklas/capybara/… . Якщо вміст створено під час виконання з JS, спочатку повернеться до нуля, якщо він виконує очікування до створення посилання.
занотувано

122

Спробуйте наступне:

within ".item" do
  click_link("Agree", :match => :first)
end

Джерела:


1
дивовижний. І це працює на простому page.find ('# {css}',: match =>: перший). Клацніть Привітання за дійсно корисну відповідь
Dono


4

Xpath може адресувати елемент. З цим я ще не дуже добре, але щось подібне//div[@class='active'][1]/a

Це може бути, а може і не працювати, але справа в тому, що xpath може адресувати масив збігів і витягувати певний. Ви повинні мати можливість зіставитись із цим.

Приклад робочого прикладу одного з моїх проектів:

в межах page.find ("div.panel", текст: / Пропозиції /)
  у page.find ('tr', текст: / Foo /)
    page.should have_xpath ('td [3]', текст: @today)
  кінець
кінець

2

Оскільки first () не завжди чекає, можливо, це корисно:

expect(page).to have_css("selector")                               
first("selector").click

2

більшість із цих рішень не використовуватиме блискучі функції очікування Капібари

краще зробити так, як пропонує це посилання:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

Погано:

first(".active").click
Якщо на сторінці ще немає. -Активного елемента, спочатку повернеться нуль, а натискання не вдасться.

Добре:

Якщо ви хочете, щоб переконатися, що існує саме такий
find(".active").click

Якщо ви просто хочете, щоб перший елемент
find(".active", match: :first).click
Capybara чекав, коли елемент з'явиться, перш ніж намагатися натиснути.

Зауважте, що match: :firstвона більш крихка, оскільки вона мовчки натисне на інший елемент, якщо ви введете нові елементи, які відповідають.


Я вважаю, що це найточніша відповідь.
katericata

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.