Reputation: 3821
I'm fairly new to writing integration tests, so excuse me if this question appears rudimentary (although I spent hours looking for an answer online).
I'm working with Rails 4, RSpec and Capybara.
Here is my code:
RSpec.feature "Sign up" do
it "has a working link to sign in page" do
visit '/users/new'
click_on("Sign in")
expect(page).to have_content "Sign in to continue" <= the problem is here
end
end
Error:
1) Sign up has a working link to sign in page
Failure/Error: expect(page).to have_content "Sign in to continue"
expected to find text "Sign in to continue" in ""
Link works fine in the browser. I tried save-and-open-page and it indeed shows a blank page. All my RSpec unit tests are working with the current configuration. Can it be the controller not rendering my page and if so, how can I fix it? I don't have any controller tests at this point.
Thanks a lot for any ideas!
My spec-helper:
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
My rails-helper:
require 'capybara/rspec'
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include FactoryGirl::Syntax::Methods
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
end
The full view:
<header class='header'>
<div class='dog-logo'></div>
<aside>
<a class='blue-button' href='<%= new_session_url %>'>Sign in</a>
</aside>
</header>
<h1 class='create-new-account-header-text'>Create your account!</h1>
<form class='create-account-form group' id='create-account-form'>
<label>Name</label>
<input type='text' for='Name' name='user[first_name]'
placeholder="First" class='sign-up-first-name'>
<input type='text' for='Name' name='user[last_name]'
placeholder="Last" class='sign-up-last-name'>
</label>
<label>Choose your username</label>
<input type='text' name='user[username]'
for='Choose your username'>
<label>Create a password</label>
<input type='password' name='user[password]' class='sign-up-password'
for='Create a password'>
<label>Confirm your password</label>
<input type='password' name='confirmPassword' class='sign-up-confirm-password'
for='Confirm your password'>
<label>Birthday</label>
<select name='birthday-month' for='Birthday'>
<option>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
<input name='birthday-day' type='text' placeholder="Day" for='Birthday'>
<input name='birthday-year' type='text' placeholder="Year" for='Birthday'>
<label>Gender</label>
<select name="user[gender]" for='Gender'>
<option value="" disabled selected style='display:none;'>I am</option>
<option value='M'>Male</option>
<option value='F'>Female</option>
<option value='O'>Other</option>
</select>
<input type='checkbox' for='I agree to be awesome!'
class='sign-up-checkbox'>
<label class='sign-up-awesome-label'>I agree to be awesome!</label>
<button class='blue-button'>Create account</button>
</form>
UsersController:
class UsersController < ApplicationController
before_action :redirect_current_user
def new
render :new
end
end
SessionsController:
class SessionsController < ApplicationController
before_action :require_user!, only: [:destroy]
before_action :redirect_current_user, only: [:new]
def new
render :new
end
def destroy
current_user.reset_session_token!
session[:session_token] = nil
redirect_to new_session_url
end
end
ApplicationController:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user, :logged_in?
def current_user
@current_user ||= User.find_by(session_token: session[:session_token])
end
def logged_in?
!!current_user
end
def log_in!(user)
user.reset_session_token!
session[:session_token] = user.session_token
end
def log_out!
current_user.reset_session_token!
session[:session_token] = nil
end
def require_user!
redirect_to new_session_url unless logged_in?
end
def redirect_current_user
redirect_to root_url if current_user
end
end
Upvotes: 1
Views: 2181
Reputation: 3821
RESOLVED:
As correctly pointed out by @dwenzel in the comments, the content that was supposed to be present after the click, was being entirely rendered by Javascript.
When using Capybara, the default setting is that Javascript on the page does not get run. The issue was resolved by installing capybara-webkit (see capybara-webkit github for more info) and including the line
Capybara.javascript_driver = :webkit
in my spec_helper.rb. Note that you need to explicitly tell RSpec that tests involve JS by writing js: true when defining example group, like so:
RSpec.feature "Sign up", js: true do
...
// your test examples here
...
end
Upvotes: 1