Comment obtenir le nœud parent à Capybara?

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

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

?

J’ai vraiment trouvé la réponse de jamuraa utile, mais aller dans xpath complet m’a donné un cauchemar de chaîne dans mon cas, alors j’ai utilisé la possibilité de concaténer des localisations dans Capybara, ce qui m’a permis de combiner 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.0 : find(:xpath,".//..") entraînera probablement une erreur de Ambiguous match . Dans ce cas, utilisez d’ first(:xpath,".//..") place.

Il n’y a pas moyen de faire cela avec capybara et CSS. J’ai déjà utilisé XPath dans le passé pour atteindre cet objective, 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 

J’ai trouvé ce qui suit:

 find(:xpath, '..') 

Capybara a été mis à jour pour supporter cela.

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

Si vous êtes tombé sur ce problème, essayez de trouver un nœud parent (comme dans l’ 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"]') 

Cette réponse concerne la manière de manipuler un élément frère, ce que je pense que la question originale évoque

Votre hypothèse de question fonctionne avec un ajustement mineur. Si le champ généré dynamicment ressemble à ceci et n’a pas d’identifiant:

 

Votre requête serait alors:

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

Si l’entrée générée dynamicment est associée à un élément id (soyez prudent avec ces éléments, mais en angular, ils ne changeront pas en fonction de l’ajout et de la suppression d’éléments):

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

J’espère que cela pourra aider.

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

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

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

J’avais besoin de trouver un ancêtre avec une classe css, même s’il était 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é ceci:

 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 cela avec parcimonie, cela pourrait vous coûter beaucoup de temps en tests, alors assurez-vous que l’ancêtre est à quelques pas de là.