Как получить родителя node в Капибаре?

Я работаю со многими плагинами jQuery, которые часто создают элементы DOM без идентификатора или других идентификационных свойств, и единственный способ получить их в Capybara (например, для щелчка) - это получить своего соседа (другого ребенка из его предка). Но я ничего не нашел, Капибара поддерживает такие вещи, например:

find('#some_button').parent.fill_in "Name:", :with => name

?

Ответ 1

Я действительно нашел ответ jamuraa полезным, но переход на полный xpath дал мне кошмар строки в моем случае, поэтому я с радостью воспользовался способностью конкатенации найти в Capybara, что позволило мне смешать выбор css и xpath. Ваш пример будет выглядеть следующим образом:

find('#some_button').find(:xpath,".//..").fill_in "Name:", :with => name

Обновление Capybara 2.0: find(:xpath,".//..") скорее всего приведет к ошибке Ambiguous match. В этом случае используйте first(:xpath,".//..").

Ответ 2

Нет способа сделать это с помощью capybara и CSS. Я использовал XPath в прошлом для достижения этой цели, хотя у нее есть способ получить родительский элемент и поддерживается Capybara:

find(:xpath, '//*[@id="some_button"]/..').fill_in "Name:", :with => name

Ответ 3

Это не работало для меня с ошибкой:

Ambiguous match, found 2 elements matching xpath ".//.."

Я нашел следующее, что работает:

find(:xpath, '..')

Capybara был обновлен, чтобы поддержать это.

https://github.com/jnicklas/capybara/pull/505

Ответ 4

Если вы наткнулись на это, пытаясь выяснить, как найти родителя (как у предка) node (как указано в комментарии @vrish88 к ответу @Pascal Lindelauf):

find('#some_button').find(:xpath, 'ancestor::div[@id="some_div_id"]')

Ответ 5

Этот ответ относится к тому, как манипулировать элементом брата, который, как мне кажется, относится к исходному вопросу, относится к

Ваша гипотеза вопроса работает с незначительной настройкой. Если динамически сгенерированное поле выглядит так и не имеет идентификатора:

<div>
  <input></input>
  <button>Test</button>
</div>

Тогда ваш запрос:

find('button', text: 'Test').find(:xpath, "..").find('input').set('whatever')

Если динамически сгенерированный ввод подключается с помощью элемента id (будьте осторожны с ними, как и в angular, они обычно меняются в зависимости от добавления и удаления элементов), это будет примерно так:

find('button', text: 'Test').find(:xpath, "..").fill_in('#input_1', with: 'whatever')

Надеюсь, что это поможет.

Ответ 6

Я использую другой подход, сначала найдя родительский элемент, используя текст внутри этого родительского элемента:

find("<parent element>", text: "text within your #some_button").fill_in "Name:", with: name

Возможно, это полезно в подобной ситуации.

Ответ 7

Мне нужно было найти предка с классом css, хотя он был неопределенным, если у целевого предка был один или несколько классов CSS, поэтому я не видел способа сделать детерминированный запрос xpath. Вместо этого я работал над этим:

def find_ancestor_with_class(field, cssClass)
  ancestor = field
  loop do
    ancestor = ancestor.find(:xpath, '..')
    break if ancestor.nil?

    break if ancestor.has_css? cssClass
  end

  ancestor
end

Предупреждение: используйте это экономно, это может стоить вам много времени в тестах, поэтому убедитесь, что предок находится всего в нескольких прыжках.