Come selezionare l'opzione nel menu a discesa usando Capybara


125

Sto provando a selezionare un elemento da un menu a discesa usando Capybara (2.1.0).

Voglio selezionare per numero (ovvero selezionare la seconda, la terza, ecc.).

Ho cercato su Google come un matto di provare ogni sorta di cose, ma senza fortuna.

Sono stato in grado di selezionarlo utilizzando il valore:

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

Ma non voglio usare quel metodo b / c il valore è qualcosa che cambierà e che renderà il mio test fragile.

L'HTML per il menu a discesa è:

<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>

Ho anche provato questo:

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

Ma provoca questo errore:

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

Quindi, come posso selezionare la prima, la seconda, la terza, ecc. Dal menu a discesa (usando Capybara)?

Risposte:


129

Se dai un'occhiata alla fonte del selectmetodo , puoi vedere che ciò che fa quando passi una fromchiave è essenzialmente:

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

In altre parole, trova quello <select>che ti interessa, quindi trova quello <option>all'interno, quindi chiama select_optionil <option>nodo.

Hai già praticamente fatto le prime due cose, le riorganizzerei. Quindi puoi applicare il select_optionmetodo alla fine:

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

1
Grazie mille Carol! Apprezzo molto l'aiuto! : D
Farooq,

2
Vorrei aggiungere questo riferimento per coloro che ricercano questo in futuro: gist.github.com/zhengjia/428105
BKSpurgeon

3
Bella risposta! Vorrei aggiungere che in Rails 5 si può fare nel seguente modo pure: select('option_name', from: 'select_box'). Dove possono essere i valori: id, nome, elemento etichetta correlato. Puoi leggere di più sulle opzioni di Capybara e DSL qui .
Nesha Zoric,

178

Per qualche motivo non ha funzionato per me. Quindi ho dovuto usare qualcos'altro.

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

ha funzionato per me.


1
Strano, questo non funziona per me in quanto il metodo sembra prendere almeno 3 opzioni. Sebbene il codice che hai suggerito corrisponda al codice di esempio della guida capybara.
Linus,

1
non formlo è from. Ecco la documentazione su select
fontno

3
Forse vale la pena notare il valore from è il nome, l'id o il testo dell'etichetta. vale a dire "#organizationSelect" non è corretto, ma "organisationSelect" dovrebbe funzionare.
MZB,

Questo non ha funzionato per me, ma la soluzione di carols10cents ha funzionato. Questo non è un critico per la tua risposta. Trovo davvero strano che anche sull'ultima versione di capybara, alcune chiamate funzionino e alcune chiamate non lo facciano anche quando l'intuizione ti porta a credere che più soluzioni sembrano valide. Mi sta facendo impazzire. Questo è legato a Firefox (o qualunque sia il browser capybara che finisce per usare)?
chaostheory,

Penso che funzionerà solo quando il nome e il valore dell'opzione sono gli stessi.
pixelearth

8

un'altra opzione è quella di aggiungere un metodo come questo

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

Opzioni utilifind("select[name='organization_search[role]']").find(:option, text: :Staff).select_option
pixelearth

find(:css, "#search_field").find(:option, "Opp Last Name").select_option, che è il testo dell'opzione visualizzato, ha funzionato per me, mentre il valore dell'opzione no.
codenoob,

4

Sfortunatamente, la risposta più popolare non ha funzionato del tutto per me. Ho dovuto aggiungere .select_optionalla fine della dichiarazione

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

senza il select_option, non è stata eseguita alcuna selezione


Come mai potresti chiamare .select_option, dal momento che il selectmetodo restituisce un valore booleano?
Ruby,

4

Per aggiungere ancora un'altra risposta alla pila (perché apparentemente ci sono molti modi per farlo a seconda della configurazione) - l'ho fatto selezionando l' optionelemento letterale e facendo clic su di esso

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

Non è molto carino, ma funziona: /


2

nessuna delle risposte ha funzionato per me nel 2017 con capybara 2.7. Ho ricevuto "ArgumentError: numero errato di argomenti (dato 2, previsto 0)"

Ma questo ha fatto:

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

0

Non è una risposta diretta, ma puoi (se il tuo server lo consente):

1) Crea un modello per la tua Organizzazione; extra: sarà più facile popolare il tuo HTML.

2) Crea una fabbrica (FactoryGirl) per il tuo modello;

3) Creare un elenco (create_list) con la fabbrica;

4) 'pick' (campione) un'organizzazione dalla lista con:

# 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... 

4
se devo creare un modello, non ha senso usare capybara
user1735921

Non è affatto una risposta. Questa è una domanda su Capibara.
Robin Daugherty,

0

Ecco il modo più conciso che ho trovato (usando capybara 3.3.0 e driver del cromo):

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

selezionerà la seconda opzione. Incrementa l'indice secondo necessità.


0

In Capybara puoi usare find solo con xpath

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

e metodo clicca

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.