Arenzel
Arenzel

Reputation: 1156

"Expected css... to return something" : rspec fail while test by hand works (can't reproduce the fail myself)

I'm working on a training app which is an Ogame-Like game (https://github.com/arnlen/ogame-like).

I'm using rspec (with Capybara) in order to test my app. I'm stacked for several hours because rspec is complaining for an error which *I can't reproduce * by myself with my browser.

Here is my rspec code :

describe 'Planet pages' do

let(:user){FactoryGirl.create(:user)}
before {sign_in user}

subject {page}

describe "new planet page" do
    before {visit new_planet_path}  

    describe "with valid information" do
        before do
            visit new_planet_path
            fill_in "Name", with: "MyPlanet"
            click_button "Validate"
        end

        # This test doesn't pass
        it {should have_selector('h1', text: "Planet")}
    end
end

end

The failure :

  1) Planet pages new planet page with valid information
 Failure/Error: it {should have_selector('h1', text: "Planet")}
   expected css "h1" with text "Planet" to return something
 # ./spec/requests/planet_pages_spec.rb:34:in `block (4 levels) in <top (required)>'

Here is the involved code.

My function "sign_in" used by rspec (location : spec/support/utilities.rb)

def sign_in(user)
    visit signin_path

    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Sign in"
end

My UsersController

class UsersController < ApplicationController

before_filter :signed_in_user, only: [:index, :show, :edit, :update, :destroy]

def new
    @user = User.new
end

def create
    @user = User.new(params[:user])
    if @user.save
    sign_in @user
    redirect_to new_planet_path
else
    render 'new'
end
 [...]

My PlanetsController

class PlanetsController < ApplicationController

before_filter :signed_in_user

def index
    @planets = current_user.planets
end

def new
    @planet = Planet.new
end

def create
    @planet = Planet.new(name: params[:planet][:name],
        coordinates: generate_coordinates,
        metal_ressource: 1000,
        user_id: current_user.id)
    if @planet.save
        flash[:success] = "Welcome on your first planet!"
        redirect_to action: 'index'
    else
        flash[:error] = "Error naming your planet"
        render 'new'
    end
end
end

And My Planet Index view

<% @planets.each do |planet| %>
    <h1>Planet : <%= planet.name %></h1>
    <p><%= "Coordinates : #{planet.coordinates}" %></p>
<% end %>

I tried to user the Capybara method "save_and_open_page", but rspec raised an error "undefined method"

I also tried step by step debugging by iterations on my spec file, and it revealed that the error occurs right after the "click_button 'Validate'". For an unknown reason, rspec seems not to be able to reach the planets_path ("index" action from PlanetsController).

I'm out, if anybody has an idea, I take it !


EDIT : SOLVED - Found the problem!

Using the "save_and_open_page" method from Capybara, I figured out what was going on: the planet created by rspec didn't have any coordinates, which was not allowed by the model.


How to debug with the wonderful "save_and_open_page" method

  1. Add this to your gemfile : "gem 'launchy'"
  2. Install it : bundle install
  3. Put the command "save_and_open_page" wherever you want

Hope it could help. :)

Upvotes: 0

Views: 740

Answers (1)

Jussi Hirvi
Jussi Hirvi

Reputation: 725

Capybara also has a save_page method, which is easier to use as it does not seem to need the "launchy" gem. The pages are saved in tmp/capybara. In the rspec tests, be sure to use save_page inside before, it, or some other block. It will not work as a separate command. Example:

    before { visit signup_path; save_page }

Upvotes: 1

Related Questions