Fixing Capybara Tests for a User Registration Page
While our application is working, it looks like our form changes for the user registration page broke one of our tests, in this lesson we'll walk through how to fix this.
Guide Tasks
  • Read Tutorial

While our application is working, it looks like our form changes for the user registration page broke one of our RSpec tests, in this lesson we'll walk through how to fix this. This is a common issue when working on implementing a design. It's important to constantly run the tests, even if it feels like you're not implementing actual functionality. Thankfully right now it looks like we only have one test failing. Running rspec will give the following failure:

Failures:

  1) user navigation creation can register with full set of user attributes
     Failure/Error: fill_in 'user[email]', with: "test@test.com"

     Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching field "user[email]"
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/node/finders.rb:40:in `block in find'
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/node/base.rb:84:in `synchronize'
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/node/finders.rb:32:in `find'
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/node/actions.rb:58:in `fill_in'
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/session.rb:686:in `block (2 levels) in <class:Session>'
     # /Users/admin/.rvm/gems/ruby-2.1.2/gems/capybara-2.6.2/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
     # ./spec/features/user_spec.rb:8:in `block (3 levels) in <top (required)>'

Finished in 3.58 seconds (files took 3.62 seconds to load)
35 examples, 1 failure, 2 pending

Failed examples:

rspec ./spec/features/user_spec.rb:5 # user navigation creation can register with full set of user attributes

The key issue here is that we have two email form elements on the same page, one for the sign in and one for signing up. So what do we do? Well Capybara isn't restricted to only selecting form fields with the fill_in method. We can add unique HTML ids to any ambiguous/duplicate form fields and the tests will go back to passing. Let's add an id to the registration email and password form elements:

<!-- app/views/devise/registrations/new.html.erb -->

        <div class="form-group clearfix">
          <%= f.label :email %>
          <%= f.email_field :email, placeholder: 'e.g. jon@snow.com', id: 'registration_email' %>
        </div>

        <div class="form-group clearfix">
          <%= f.label :password %>
          <%= f.password_field :password, autocomplete: "off", id: 'registration_password' %>
        </div>

If you startup the rails server and navigate to localhost:3000/users/sign_up and inspect the email element you'll see it now has a unique ID, and this is what we'll be passing to Capybara for the spec.

large

Now let's update the spec with the new id selectors:

# spec/features/user_spec.rb

require 'rails_helper'

describe 'user navigation' do
  describe 'creation' do
    it 'can register with full set of user attributes' do
      visit new_user_registration_path

      find('#registration_email').set('test@test.com')
      find('#registration_password').set('password')
      fill_in 'user[password_confirmation]', with: "password"
      fill_in 'user[first_name]', with: "Jon"
      fill_in 'user[last_name]', with: "Snow"
      fill_in 'user[username]', with: "watcheronthewall"

      click_on "Sign up"

      expect(page).to have_content("Welcome")
    end
  end
end

Now if you run rspec you'll see that the specs are now passing and now we're good to keep moving forward with the implementation.

Resources