I'd like to put a dropdown list's options into an array generically in capybara. After the process I'm expecting to have an arrray of strings, containing all dropdown options. I've tried the code below but the length of my array stays 1 regardless of what the option count is.
periods = Array.new()
periods = all('#MainContent_dd')
print periods.length
The problem is that all('#MainContent_dd')
returns all elements that have the id MainContent_dd
. Assuming this is your dropdown and ids are unique, it is expected that the periods.length
is 1 (ie periods
is the select list).
What you want to do is get the option
elements instead of the select
element.
Assuming your html is:
<select id="MainContent_dd">
<option>Option A</option>
<option>Option B</option>
<option>Option C</option>
</select>
Then you can do:
periods = find('#MainContent_dd').all('option').collect(&:text)
p periods.length
#=> 3
p periods
#=> ["Option A", "Option B", "Option C"]
What this does is:
find('#MainContent_dd')
- Finds the select list that you want to get the options fromall('option')
- Gets all option elements within the select listcollect(&:text)
- Collects the text of each option and returns it as an array@JustinCo's answer has a problem if used driver isn't fast: Capybara will make a query to driver for every invocation of text
. So if select contains 200 elements, Capybara will make 201 query to browser instead of 1 which may be slow.
I suggest you to do it using one query with 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")
or (shorter variant with jQuery):
periods = page.evaluate_script("$('#MainContent_dd').map(function() { return $(this).text() }).get()")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With