1
votes

I'm using Capybara 2.4.3 with Rspec-Rails 3.1.0, Ruby 2.1.5 and Rails 4.1.8. This test continues to fail:

let(:attack_squad) { create :squad, user: attacker, name: 'Attack Squad' }

scenario 'attacker has available attack squad' do
  visit '/account/battles/new'
  save_and_open_page
  expect(page).to have_select 'Squad', options: [attack_squad.name]
end

Using save_and_open_page, I'm able to see this HTML is being generated:

<select id="battle_squad_id" name="battle[squad_id]">
  <option value="194">Attack Squad</option>
  <option value="192">Default Squad</option>
</select>

And here is the failure message:

 Battle Management attacker has available attack squad
 Failure/Error: expect(page).to have_select 'Squad', options: [attack_squad.name]
   expected to find select box "Squad" with options ["Attack Squad"] but there were no matches. Also found "Attack Squad Default Squad", which matched the selector but not all filters.
 # ./spec/features/battle_spec.rb:31:in `block (2 levels) in <top (required)>'
 # -e:1:in `<main>'

I'm following the same format as demonstrated in the capybara spec on GitHub. If I change the expectation to:

expect(page).to have_select 'Squad'

It is able to find the select box and pass successfully. If I make the options: value anything other than an array, it gives me an error about there being on sort method. What am I missing?

1

1 Answers

4
votes

When testing the presence of a select list, there are two filters related to the options:

  • :options - This checks that the select list options exactly match the specified array.
  • :with_options - This checks that the select list options contains at least those in the specified array.

The test is failing because the expectation is expecting the HTML to be without the "Default Squad" option:

<select id="battle_squad_id" name="battle[squad_id]">
  <option value="194">Attack Squad</option>
</select>

You need to either specify all the expected options:

let(:attack_squad) { create :squad, user: attacker, name: 'Attack Squad' }
let(:default_squad) { create :squad, user: attacker, name: 'Default Squad' }

scenario 'attacker has available attack squad' do
  visit '/account/battles/new'
  save_and_open_page
  expect(page).to have_select 'Squad', options: [attack_squad.name, default_squad.name]
end

Or if you only care about the one option, use the :with_options filter instead:

let(:attack_squad) { create :squad, user: attacker, name: 'Attack Squad' }

scenario 'attacker has available attack squad' do
  visit '/account/battles/new'
  save_and_open_page
  expect(page).to have_select 'Squad', with_options: [attack_squad.name]
end