lucas
lucas

Reputation: 1151

How to test a multi-select select box with Capybara in a rails app?

A coworker and I have been struggling to figure out how to test a rails form with a select element, which we sometimes want to be a standard select dropdown and sometimes want to be a multi-select box.

What can we add to our RSpec feature spec to test this? Here's the code we're trying to test:

    <% if @use_multi_select %>
      <%= select_tag :program, options_for_select(@programs), { multiple: true } %>
    <% else %>
      <%= select_tag :program, options_for_select(@programs) %>
    <% end %>

And here's what I'm thinking for the test:

    context 'when @use_multi-select == true' do
      it 'displays a multi-select select box' do
        expect(page).to have_select('program').with_options(multiple: true)
      end
    end

    context 'when @use_multi-select == false' do
      it 'displays a standard select box' do
        expect(page).to have_select('program').with_options(multiple: false)
      end
    end

But that whole with_options thing doesn't work that way. Has anyone done this before and found a workable solution or work-around?

Upvotes: 3

Views: 1650

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49950

with_options is an option that can be passed to have_select (not a method that is called on have_select) to check that specific option elements are children of the select (others may also exist)

To test whether a select is multiple you can do

expect(page.find(:select, 'program')[:multiple]).to be_truthy

And obviously be_falsey for the opposite

If you're running Capybara 2.6.x you could do

Capybara.modify_selector(:select) do
  filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
end

which would then let you do

expect(page).to have_select('program', multiple: true)

The :multiple filter will probably be included in Capybara 2.7 when it's released

Upvotes: 5

Related Questions