Search code examples
cssrubyautomationcapybaramaterialize

Select a Dropdown using Capybara ElementNotFound


I'm trying to select an item from a dropdown with Capybara. I have done this just fine using a different CSS framework; now I'm using Materialize.

I have talked with the developer and he mentioned that Materialize uses two select boxes and so it might be getting confused there. Not sure if that's helpful but I thought I'd mention it.

I'm dealing with CSS that looks something like

  <div class="select-wrapper country required">
    <span class="caret">▼</span>    
    <input type="text" class="select-dropdown" readonly="true" data-activates="select-options-0e5c0ffe-1e78-5df0-c08d-7bced194abd1" value="">    

    <ul id="select-options-0e5c0ffe-1e78-5df0-c08d-7bced194abd1" class="dropdown-content select-dropdown" style="width: 435px; position: absolute; top: 0px; left: 0px; opacity: 1; display: none;"><li class="">  <span></span></li>
        <li class=""><span>Afghanistan</span></li>
        <li class=""><span>Åland Islands</span></li>
        <li class=""><span>Albania</span></li>
        <li class=""><span>Algeria</span></li>
        <li class=""><span>United States</span></li></ul>       

    <select class="country required initialized"   name="store[address_attributes][country]" id="store_address_attributes_country"><option value=""></option>
        <option value="AF">Afghanistan</option>
        <option value="AX">Åland Islands</option>
        <option value="AL">Albania</option>
        <option value="DZ">Algeria</option>
        <option value="US">United States</option>

What I've tried is

select "United States", :from => 'store_address_attributes_country'

I've also tried

find("store_address_attributes_country").select("United States")

(I also tried this same thing using the XPath, selector and name instead of the ID)

These give me the error

 Capybara::ElementNotFound:
   Unable to find select box "store_address_attributes_country`

Solution

  • When using materialize the <select> element is hidden on the page and replaced with an <input> element as the trigger and <ul> and <li> elements as the dropdown. Because of this you can't use #select. Instead you have to replicate what a user would have to do, which is click on the input used to trigger the dropdown and then click on the correct li. In this case that would be

    find("input.select-dropdown").click
    find("li", text: "United States").click
    

    Obviously the first find would have to be scoped to something on the page (or increase the specificity of the selector) if there is more than one select on the page