web-dev-qa-db-fra.com

Comment obtenir le nœud parent à Capybara?

Je travaille avec de nombreux plugins jQuery, qui créent souvent des éléments DOM sans id ou autres propriétés d'identification, et la seule façon de les obtenir dans Capybara (pour cliquer par exemple) - est d'obtenir d'abord leur voisin (un autre enfant de son ancêtre) . Mais je n'ai trouvé nulle part, Capybara prend-il en charge de telles choses, par exemple:

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

?

80
sandrew

J'ai vraiment trouvé la réponse de jamuraa utile, mais opter pour xpath complet m'a donné un cauchemar de chaîne dans mon cas, alors j'ai heureusement utilisé la possibilité de concaténer les trouvailles à Capybara, me permettant de mélanger la sélection css et xpath. Votre exemple ressemblerait alors à ceci:

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

mise à jour de Capybara 2.: find(:xpath,".//..") entraînera très probablement une erreur Ambiguous match. Dans ce cas, utilisez plutôt first(:xpath,".//..").

106
Pascal Lindelauf

Il n'y a aucun moyen de le faire avec capybara et CSS. J'ai déjà utilisé XPath dans le passé pour atteindre cet objectif, qui a un moyen d'obtenir l'élément parent et est pris en charge par Capybara:

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

J'ai trouvé ce qui suit qui fonctionne:

find(:xpath, '..')

Capybara a été mis à jour pour prendre en charge cela.

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

29
B Seven

Si vous êtes tombé sur cela en essayant de trouver un nœud parent (comme dans ancêtre) (comme indiqué dans le commentaire de @ vrish88 sur la réponse de @Pascal Lindelauf):

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

Cette réponse se rapporte à la façon de manipuler un élément frère, ce à quoi je pense que la question d'origine fait allusion

L'hypothèse de votre question fonctionne avec un Tweak mineur. Si le champ généré dynamiquement ressemble à ceci et n'a pas d'ID:

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

Votre requête serait alors:

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

Si l'entrée générée dynamiquement est attachée avec un élément id (soyez prudent avec ceux-ci, car en angulaire, ils ne changeront pas en fonction de l'ajout et de la suppression d'éléments), ce serait quelque chose comme ceci:

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

J'espère que cela pourra aider.

4
T. Slater

J'utilise une approche différente en trouvant d'abord l'élément parent en utilisant le texte dans cet élément parent:

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

Peut-être que cela est utile dans une situation similaire.

4
Harm de Wit

J'avais besoin de trouver un ancêtre avec une classe css, bien qu'il soit indéterminé si l'ancêtre cible avait une ou plusieurs classes css présentes, donc je n'ai pas vu de moyen de faire une requête déterministe xpath. J'ai plutôt travaillé cela:

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

Attention: utilisez-le avec parcimonie, cela pourrait vous coûter beaucoup de temps dans les tests, alors assurez-vous que l'ancêtre n'est qu'à quelques sauts.

2
kross