Search code examples
ruby-on-railsrspeccapybarabddruby-on-rails-4

Capybara::ElementNotFound, but it is there


I'm getting the following error:

Capybara::ElementNotFound: Unable to find field "username"
./spec/controllers/sessions_controller_spec.rb:10:in `block (3 levels) in <top (required)>'

spec:

require 'spec_helper'

describe SessionsController do
  before :each do
    @user = FactoryGirl.create(:user)
  end
  context 'creating a new session' do
    it 'can set the current_user variable to the logged user' do
      visit '/login'
      fill_in 'username', with: 'gabrielhilal' #I have tried `Username` as well
      fill_in 'password', with: 'secret'
      click_button 'Login'
      current_user.should == @user
      current_user.username.should == 'gabrielhilal'
    end
  end
  context 'destroying existing session' do
    xit 'can destroy the current_user' do
    end
  end
end

But I have the field username in my form:

<form accept-charset="UTF-8" action="/sessions" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" / <input name="authenticity_token" type="hidden" value="x7ORLDIvq1BXr8SOkd/Zla9Pl5R5tBXAtyflCpTGCtY=" /></div>
  <div class="field">
    <label for="username">Username</label>
    <input id="username" name="username" type="text" />
  </div>
  <div class="field">
    <label for="password">Password</label>
    <input id="password" name="password" type="password" />
  </div>
  <div class="actions">
    <input name="commit" type="submit" value="Login" />
  </div>
</form>

I did a similar test with cucumber and it is passing, which confirms that the field username is there: When to switch from cucumber to rspec in the BDD cycle for a login procedure

Any idea?

EDIT - I have added the save_and_open_page, which gives me a blank page. The puts "#{page.html.inspect}" also returns empity.

""

Capybara::ElementNotFound: Unable to find field "username"
./spec/controllers/sessions_controller_spec.rb:12:in `block (3 levels) in <top (required)>'

Solution

  • I know you've already answered your own question (kind of), but I feel it's still warranted to let you know that the example you've provided is a mixture of a controller and a request spec...

    To quote verbatim from RSpec - Controller Specs: Note: To encourage more isolated testing, views are not rendered by default in controller specs.

    The main difference (in the way RSpec interprets what kind of spec it is) is the line: describe SessionsController do.

    To align it with RSpec and Testing best practices:

    1. Move the spec to spec/requests
    2. Change the describe to describe "SessionsController" do
    3. Remove render_views

    your spec should run just fine...

    Check out RSpec - Request Specs for what I mean. I would also check out betterspecs.org for ways you can improve on testing.