web-dev-qa-db-fra.com

Comment sélectionner une option dans le menu déroulant avec Capybara

J'essaie de sélectionner un élément dans un menu déroulant à l'aide de Capybara (2.1.0).

Je veux sélectionner par numéro (c’est-à-dire choisir la deuxième, troisième option, etc.).

J'ai googlé comme un fou en essayant toutes sortes de choses mais pas de chance.

J'ai pu le sélectionner en utilisant la valeur:

 find("option[value='4c430d62-f1ba-474f-8e8a-4452c55ea0a8']").click

Mais je ne veux pas utiliser cette méthode car la valeur est quelque chose qui va changer et rendre mon test fragile.

Le code HTML pour la liste déroulante est:

<td class="value">
    <select name="organizationSelect" id="organizationSelect" class="required">
     <option value="NULL">Choose...</option>
     <option value="4c430d62-f1ba-474f-8e8a-4452c55ea0a8">&nbsp;Institution1</option>
     <option value="e1a4efa7-352d-410a-957e-35c8a3b92944">&nbsp;Institution / test</option>
    </select>
</td>

J'ai aussi essayé ceci:

  option = find(:xpath, "//*[@id='organizationSelect']/option[2]").text  
  select(option, :from => organizationSelect)

Mais il en résulte cette erreur:

Ambiguous match, found 2 elements matching option "Institution" (Capybara::Ambiguous)

Alors, comment puis-je sélectionner les première, deuxième, troisième, etc. options dans le menu déroulant (avec Capybara)?

116
Farooq

Si vous jetez un oeil à la source de la méthode select , vous pouvez voir que ce qu'elle fait lorsque vous passez une clé from est essentiellement:

find(:select, from, options).find(:option, value, options).select_option

En d'autres termes, il trouve le <select> qui vous intéresse, puis trouve le <option> dans celui-ci, puis appelle select_option sur le noeud <option>.

Vous avez déjà pratiquement fait les deux premières choses, je voudrais simplement les réorganiser. Ensuite, vous pouvez ajouter la méthode select_option à la fin:

find('#organizationSelect').find(:xpath, 'option[2]').select_option
124
carols10cents

Pour une raison quelconque, cela n'a pas fonctionné pour moi. Je devais donc utiliser autre chose.

select "option_name_here", :from => "organizationSelect"

a travaillé pour moi.

162
RVM

une autre option consiste à ajouter une méthode comme celle-ci

  def select_option(css_selector, value)
    find(:css, css_selector).find(:option, value).select_option
  end
5
montrealmike

Malheureusement, la réponse la plus populaire n'a pas fonctionné entièrement pour moi. Je devais ajouter .select_option à la fin de la déclaration

select("option_name_here", from: "organizationSelect").select_option

sans le select_option, aucune sélection n'a été effectuée

3
Sam D

Pour ajouter encore une réponse à la pile (car apparemment, il y a tellement de façons de le faire en fonction de votre configuration) - je l'ai fait en sélectionnant l'élément littéral option et en cliquant dessus

find(".some-selector-for-dropdown option[value='1234']").select_option

Ce n'est pas très joli, mais ça marche: /

2
user2490003

aucune des réponses n'a fonctionné pour moi en 2017 avec capybara 2.7. J'ai "ArgumentError: nombre d'arguments incorrect (donné 2, attendu 0)"

Mais cela a:

find('#organizationSelect').all(:css, 'option').find { |o| o.value == 'option_name_here' }.select_option
2
bjelli

Ce n'est pas une réponse directe, mais vous pouvez (si votre serveur le permet):

1) Créer un modèle pour votre organisation; extra: Il sera plus facile de renseigner votre code HTML.

2) Créez une usine (FactoryGirl) pour votre modèle;

3) Créer une liste (create_list) avec la fabrique;

4) "choisir" (exemple) une organisation dans la liste avec:

# Random select
option = Organization.all.sample 

# Select the FIRST(0) by id
option = Organization.all[0] 

# Select the SECOND(1) after some restriction
option = Organization.where(some_attr: some_value)[2]
option = Organization.where("some_attr OP some_value")[2] #OP is "=", "<", ">", so on... 
1
David V. Teixeira

Voici le moyen le plus concis que j'ai trouvé (avec capybara 3.3.0 et le pilote chrome):

all('#id-of-select option')[1].select_option

sélectionnera la 2ème option. Incrémenter l'index si nécessaire.

0
pduey