2013-02-21 13 views
5

Vorrei mettere le opzioni di un elenco a discesa in un array genericamente in capybara. Dopo il processo mi aspetto di avere una serie di stringhe, contenente tutte le opzioni a discesa. Ho provato il codice qui sotto, ma la lunghezza del mio array rimane 1 indipendentemente da quale sia il conteggio delle opzioni.Capybara scrive i testi delle opzioni del menu a discesa in un array

periods = Array.new() 
periods = all('#MainContent_dd') 
print periods.length 

risposta

21

Il problema è che all('#MainContent_dd') restituisce tutti gli elementi che hanno l'id MainContent_dd. Supponendo che questo sia il tuo menu a discesa e gli ID siano unici, è previsto che lo periods.length sia 1 (ovvero periods è l'elenco di selezione).

Quello che vuoi fare è ottenere gli elementi option anziché l'elemento select.

Assumendo che il HTML è:

<select id="MainContent_dd"> 
    <option>Option A</option> 
    <option>Option B</option> 
    <option>Option C</option> 
</select> 

allora si può fare:

periods = find('#MainContent_dd').all('option').collect(&:text) 
    p periods.length 
    #=> 3 
    p periods 
    #=> ["Option A", "Option B", "Option C"] 

Quello che fa è:

  1. find('#MainContent_dd') - Trova l'elenco di selezione che si desidera ottenere le opzioni da
  2. all('option') - G ETS tutti gli elementi opzionali all'interno della lista di selezione
  3. collect(&:text) - Raccoglie il testo di ogni opzione e la restituisce come un array
+0

funziona come un fascino :) Grazie Justin, avrà più di queste domande noob :) –

+0

Potrebbe avere problemi con le prestazioni –

2

@ risposta di JustinCo ha un problema se il driver utilizzato non è veloce: Capybara farà una query all'autista per ogni chiamata di text. Quindi se select contiene 200 elementi, Capybara eseguirà 201 query al browser anziché 1, che potrebbe essere lento.

vi consiglio di farlo utilizzando una query con JavaScript:

periods = page.execute_script("options = document.querySelectorAll('#MainContent_dd > option'); texts=[]; for (i=0; i<options.length; i++) texts.push(options[i].textContent); return texts") 

o (variante più corta con jQuery):

periods = page.evaluate_script("$('#MainContent_dd').map(function() { return $(this).text() }).get()") 
Problemi correlati