Comment sélectionner une option dans la liste déroulante en utilisant Capybara

125

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

Je veux sélectionner par numéro (ce qui signifie sélectionner l'option deuxième, troisième, 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 qui rendra mon test fragile.

Le code HTML de 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 cela entraîne cette erreur:

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

Alors, comment puis-je sélectionner la première, deuxième, troisième, etc. option dans la liste déroulante (en utilisant Capybara)?

Farooq
la source

Réponses:

129

Si vous regardez la source de la selectméthode , vous pouvez voir que ce qu'elle fait lorsque vous passez une fromclé est essentiellement:

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

En d'autres termes, il trouve ce qui <select>vous intéresse, puis trouve ce <option>qui s'y trouve, puis appelle select_optionle <option>nœud.

Vous avez déjà pratiquement fait les deux premières choses, je les réorganiserais simplement. Ensuite, vous pouvez clouer la select_optionméthode à la fin:

find('#organizationSelect').find(:xpath, 'option[2]').select_option
chants de Noël10cents
la source
1
Merci beaucoup Carol! J'apprécie vraiment l'aide! : D
Farooq
2
Voudrais ajouter cette référence pour ceux qui recherchent ceci à l'avenir: gist.github.com/zhengjia/428105
BKSpurgeon
3
Très bonne réponse! Je voudrais ajouter que dans Rails 5 vous pouvez le faire de la manière suivante ainsi: select('option_name', from: 'select_box'). Où les valeurs peuvent être: id, nom, élément d'étiquette associé. Vous pouvez en savoir plus sur Capybara et les options DSL ici .
Nesha Zoric
178

Pour une raison quelconque, cela n'a pas fonctionné pour moi. J'ai donc dû utiliser autre chose.

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

travaillé pour moi.

RVM
la source
1
Bizarre, cela ne fonctionne pas pour moi car la méthode semble prendre au moins 3 options. Bien que le code que vous avez suggéré corresponde à l'exemple de code du guide capybara.
Linus
1
ce n'est pas form, ça l'est from. Voici la documentation sur select
fontno
3
Il est peut-être intéressant de noter que la valeur from est le nom, l'identifiant ou le texte de l'étiquette. c'est-à-dire que "#organizationSelect" est incorrect, mais "organizationSelect" devrait fonctionner.
MZB
Cela n'a pas fonctionné pour moi, mais la solution de carols10cents a fonctionné. Ce n'est pas une critique de votre réponse. Je trouve juste vraiment étrange que même sur la dernière version de capybara, certains appels fonctionnent et certains appels ne fonctionnent même pas lorsque l'intution vous amènerait à croire que plusieurs solutions semblent valables. Cela me rend fou. Est-ce lié à Firefox (ou à tout autre navigateur utilisé par Capybara)?
chaostheory
Je pense que cela ne fonctionnera que lorsque le nom et la valeur de l'option sont identiques.
pixelearth
8

une autre option est d'ajouter une méthode comme celle-ci

  def select_option(css_selector, value)
    find(:css, css_selector).find(:option, value).select_option
  end
montréal
la source
Options utilesfind("select[name='organization_search[role]']").find(:option, text: :Staff).select_option
Pixelearth
find(:css, "#search_field").find(:option, "Opp Last Name").select_option, qui est le texte de l'option affiché, a fonctionné pour moi, contrairement à la valeur de l'option.
codenoob le
4

Malheureusement, la réponse la plus populaire n'a pas fonctionné entièrement pour moi. J'ai dû 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'était effectuée

Sam D
la source
Comment se fait-il que vous puissiez appeler .select_option, puisque la selectméthode renvoie une valeur booléenne?
Ruby
4

Pour ajouter encore une autre 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' optionélément littéral et en cliquant dessus

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

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

user2490003
la source
2

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

Mais cela a fait:

find('#organizationSelect').all(:css, 'option').find { |o| o.value == 'option_name_here' }.select_option
Bjelli
la source
0

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

1) Créez un modèle pour votre organisation; extra: il sera plus facile de remplir votre HTML.

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

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

4) `` choisir '' (échantillonner) 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... 
David V. Teixeira
la source
4
si je dois créer un modèle, il ne sert à rien d'utiliser capybara
user1735921
Ce n'est pas du tout une réponse. C'est une question sur Capybara.
Robin Daugherty le
0

Voici le moyen le plus concis que j'ai trouvé (en utilisant capybara 3.3.0 et le pilote chromium):

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

sélectionnera la 2ème option. Incrémentez l'index selon vos besoins.

pduey
la source
0

Dans Capybara, vous ne pouvez utiliser que rechercher avec xpath

find(:xpath, "//*[@id='organizationSelect']/option[2]").click

et méthode cliquez

Alexandr
la source