cannot log-in user using rspec integration testing - selenium

I am trying to create a test for Login; The functionality has been implemented and working fine but I am trying to create a test for it. However, User model is empty in sessions controller but it has content in the test code. On the code below, I added binding.pry(debugger) to check for the User model.
It's working fine too when I am not using webdriver(js: true), if it's just purely like this:
post "/api/user/sign_in", {
user: {
email: user.email,
password: user.password
}
}
expect(response).to be_success
I've been using the same test code before which is working fine. I am not just sure if it has something to do with my front-end is AngularJS.
TEST CODE
require 'rails_helper'
describe Model, js: true do
let(:model) { Model }
let!(:user) { create(:user) }
it "Login" do
binding.pry ### #user exists in User.all #####
visit root_path
find('#btn-signin').click
find('#tab-signin').click
fill_in 'user_email', with: user.email
fill_in 'user_password', with: user.password
find('#btn-login').click
binding.pry #### user exists in User.all ####
expect(page).to have_css '.profile-pic'
end
end
SESSIONS CONTROLLER
def create
puts User.pluck(:email).join(', ') #### user does not exists (it's actually blank) ####
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
render :json => current_user.to_json
end
GEMS
group :development, :test do
gem 'factory_girl_rails'
gem 'pry'
gem 'quiet_assets'
gem 'rspec-rails', '~> 3.0.0'
end
group :test do
gem 'codeclimate-test-reporter', require: nil
gem 'shoulda-matchers'
gem 'jasmine'
gem 'capybara'
gem 'selenium-webdriver', '~> 2.38.0'
end
RAILS SPEC
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include Capybara::DSL
config.include FactoryGirl::Syntax::Methods
config.use_transactional_fixtures = true
config.include UserMacros
config.infer_spec_type_from_file_location!
end

SOLUTION:
GEMFILE
gem 'database_cleaner'
RAILS_HELPER.RB
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end

Related

Can't get any FactoryGirl factories to register

I'm trying to set up Rspec and FactoryGirl on an existing Rails 3 project which previously has had no automated testing.
The error I'm getting when running the test as below is Factory not registered: admin
I can't see why this would be failing, it happens for every test through my specs that use a factory.
/Gemfile.rb (concatenated for brevity)
group :development, :test do
gem 'rspec-rails'
gem 'factory_girl_rails
end
/config/application.rb (concatenated for brevity)
config.generators do |g|
g.test_framework :rspec, fixture: true
g.fixture_replacement :factory_girl, dir: "spec/factories"
end
/spec/spec_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/mechanize'
require 'factory_girl_rails'
HTTPI.log = false
FactoryGirl.factories.clear
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.expect_with :rspec do |c|
c.syntax = :expect
end
config.include Devise::TestHelpers, type: :controller
config.extend ControllerMacros, type: :controller
end
/spec/support/controller_macros.rb
module ControllerMacros
def login_admin
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:admin]
sign_in FactoryGirl.create(:admin)
end
end
end
/spec/factories/users.rb
FactoryGirl.define do
factory :admin do
sequence(:email) {|n| "user#{n}#local.test"}
password "password"
password_confirmation "password"
association :user_role, factory: :admin_role
trait :as_reseller do
association :user_role, factory: :reseller_role
end
trait :as_customer do
association :user_role, factory: :customer_role
end
end
factory :reseller, parent: :admin do
as_reseller
end
factory :customer, parent: :admin do
as_customer
end
end
/spec/controllers/accounts_controller_spec.rb
describe AccountCodesController do
describe "as administrator" do
login_admin
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
end
end
This line FactoryGirl.factories.clear confuse me a lot.
According to doc you needn't do any spec_helper modification (if you use it in Rails app and through Bundle).
This is my spec_helper in one of my APP and I use factories in it successfully.
It's explain on the link
The stable documentation is here :
http://github.com/thoughtbot/factory_girl/tree/1.3.x

CarrierWave not working with Fog -> ArgumentError ( is not a recognized storage provider): app/controllers/notes_controller.rb:11:in `create'

I followed the railscasts about using carrierwave with fog with aws s3 to the T but it doesnt seem to work.
The Gemfile is as follows:
source 'https://rubygems.org'
ruby '1.9.3'
gem 'rails', '3.2.13'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'pg'
gem 'pg_search'
gem 'devise'
gem "therubyracer"
gem "less-rails" #Sprockets (what Rails 3.1 uses for its asset pipeline) supports LESS
gem "twitter-bootstrap-rails", :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git'
gem "simple_form"
gem 'aws-sdk', '~> 1.8.1.2'
gem 'activerecord-reputation-system', require: 'reputation_system'
gem 'bootstrap-will_paginate'
gem 'carrierwave'
gem "rmagick"
gem "fog", "~> 1.3.1"
gem 'carrierwave-aws'
config/initializers/carrierwave.rb
require 'carrierwave'
CarrierWave.configure do |config|
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: ENV["xxx"],
aws_secret_access_key: ENV["yyy"],
region: ENV['ap-southeast-1']
}
config.cache_dir = "#{Rails.root}/tmp/uploads"
config.fog_directory = ENV["ABC"]
end
The uploader:
class ImageUploader < CarrierWave::Uploader::Base
require 'carrierwave/processing/mime_types'
before :store, :remember_cache_id
after :store, :delete_tmp_dir
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
# storage :file
storage :fog
include CarrierWave::MimeTypes
process :set_content_type
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_limit => [200, 200]
end
# store! nil's the cache_id after it finishes so we need to remember it for deletion
def remember_cache_id(new_file)
#cache_id_was = cache_id
end
def delete_tmp_dir(new_file)
# make sure we don't delete other things accidentally by checking the name pattern
if #cache_id_was.present? && #cache_id_was =~ /\A[\d]{8}\-[\d]{4}\-[\d]+\-[\d]{4}\z/
FileUtils.rm_rf(File.join(root, cache_dir, #cache_id_was))
end
end
end
the controller:
class NotesController < ApplicationController
before_filter :authenticate_user!, only: [:create, :destroy]
before_filter :correct_user, only: :destroy
def index
end
def create
#note = current_user.notes.build(params[:note])
#notes = Note.paginate(page: params[:page])
if #note.save
flash[:success] = "Note uploaded!"
redirect_to root_url
else
flash.now[:error] = "Note failed to upload."
render 'static_pages/home'
end
end
def destroy
#note.destroy
flash[:success] = "Note deleted."
redirect_to root_url
end
private
def correct_user
#note = current_user.notes.find_by_id(params[:id])
redirect_to root_url if #note.nil?
end
end
I don't really know if the problem lies in the gem or the controller. Even the controller is based on the microposts controller in Michael Hartl's book "The Ruby on Rails Tutorial" so I don't know where I have gone wrong.
That's an awfully early version of fog. The latest is 1.12.1. Try updating to the latest release using the following entry in your Gemfile
gem "fog", "~> 1.12.1"

Authlogic / Selenium breaks after rails 3.2.12 upgrade

I'm using Authlogic and having difficulty getting my Selenium tests to work with :js=>true after upgrading to Rails 3.2.12. The same tests use to worked under Rails 3.1.3. I am running my tests using Spork.
I am logging in through Selenium launches Firefox (19.0.2), fills the login form but then I get a permissions error from Authlogic, the standard "You are not allowed to access this action."
I can see that many people are having issues with this but as I mentioned, has only became a problem for me once upgrading from Rails 3.1.3 to Rails 3.2.12. I suspect that the issue may be within my spec_helper file (below) and in particularly within the
module Authlogic
block which I got from here:
Authlogic with Capybara + Cucumber + Selenium Driver not working
**spec_helper.rb**
require 'rubygems'
require 'spork'
require 'authlogic/test_case'
include Authlogic::TestCase
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.color_enabled = true
ApplicationController.skip_before_filter :activate_authlogic
config.before(:each, :type => :request) do
activate_authlogic
end
config.include FactoryGirl::Syntax::Methods
config.include Capybara::DSL
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
Capybara.current_driver = :selenium
DatabaseCleaner.strategy = :truncation
module Authlogic
module Session
module Activation
module ClassMethods
def controller
if !Thread.current[:authlogic_controller]
Thread.current[:authlogic_controller] = Authlogic::TestCase::MockController.new
end
Thread.current[:authlogic_controller]
end
end
end
end
end
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.include(MailerMacros)
config.before(:each) { reset_email }
config.mock_with :mocha
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end
end
Spork.each_run do
FactoryGirl.reload
end
My understanding is that Authlogic and Selenium Webdriver work on different threads hence the need for this patch in the spec_helper file.
In the Request Spec I get a permissions error from Authlogic. Here is the Request Spec test in question:
# UNIT REQUEST SPEC
require 'spec_helper'
describe "Units" do
describe "GET /admin/units/new" do
before(:each) do
activate_authlogic
UserSession.create FactoryGirl.create(:admin_user, :email => "foo#bar.com", :password => "password", :password_confirmation => "password")
visit root_path
fill_in "user_session[email]", :with => "foo#bar.com"
fill_in "user_session[password]", :with => "password"
click_button "Sign In"
end
it "displays a pop up dialog after unit is created", :focus, :js => true do
visit new_admin_unit_path
fill_in "Title", :with => "Unit Title"
fill_in "Code", :with => "U-TEST"
fill_in "Learning Outcome", :with => "Some Learning Outcome"
fill_in "unit[learning_outcomes_attributes][0][assessment_methods_attributes][0][content]", :with => "Some Assessment Criteria"
click_button "Save and Publish"
page.should have_css('div.ui-dialog')
end
end
end
My Capybara tests are working ok with:
activate_authlogic
UserSession.create FactoryGirl.build(:user)
in the before(:each) block, the problem only arises when using :js=>true
So, my questions are:
Is it a case that with Rails 3.2.x that the spec_helper fix (module Authlogic ... ) no longer works.
If that is in fact the case, what is the "normal" way of getting this to work?
Just revisited this today. When I upgraded Rails I also upgraded capybara to the latest version (2.1.0). It seems that downgrading capybara from this version (2.1.0) to version 2.0.1 seemed to do the trick. I can see that capybara (2.0.1) uses xpath (1.0.0) while capybara (2.1.0) uses xpath (2.0.0) along with a different version of nokogiri gem. I have no idea if there is a link there but here is my gem file if anyone cares to take a look:
source 'http://rubygems.org'
gem 'rails', '3.2.12'
gem 'rack-mini-profiler'
gem 'authlogic'
gem 'rails3-generators'
gem 'mysql2'
gem 'declarative_authorization'
gem 'kaminari'
gem "foreigner"
gem 'validates_timeliness'
gem "activerecord-import", ">= 0.2.0"
gem 'ezcrypto'
gem 'thin'
gem 'exception_notification'
gem 'mail'
gem 'libv8', '~> 3.11.8.0'
gem "therubyracer", :require => 'v8'
gem 'jasmine', :group => [:development, :test]
gem 'sprockets'
gem 'jquery-rails'
gem 'tinymce-rails'
gem 'acts_as_list'
gem 'cocaine'
gem 'rmagick'
gem 'carrierwave'
gem 'remotipart'
gem 'deep_cloneable', '~> 1.4.0'
gem 'delayed_job_active_record'
gem 'daemons'
gem 'rb-readline'
gem "jquery-migrate-rails", "~> 1.0.0"
gem 'ransack'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', "~> 3.2.3"
gem 'coffee-rails', "~> 3.2.1"
gem 'uglifier', '>= 1.0.3'
end
# Bundle gems for the local environment. Make sure to
# put test-only gems in this group so their generators
# and rake tasks are available in development mode:
group :development, :test do
gem 'cheat'
gem 'ruby-growl'
gem 'letter_opener'
gem 'rspec-rails', "~> 2.0"
gem 'database_cleaner'
gem 'rb-fsevent', '~> 0.9.1'
gem 'guard-rspec'
gem 'spork-rails'
gem 'guard-spork'
gem 'factory_girl_rails'
gem 'capybara', '2.0.1'
gem 'launchy'
gem 'mocha', :require => false
gem 'better_errors'
gem 'binding_of_caller'
gem 'meta_request'
end

Request spec with Devise + Rspec2 + Spork/Guard

I have setup Rspec2 + Spork + Guard + Devise
My files are as follows
#spec_helper.rb
Spork.prefork do
#code
Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
RSpec.configure do |config|
config.extend ControllerMacros, :type => :controller
end
end
Spork.each_run do
# This code will be run each time you run your specs.
FactoryGirl.reload
include ControllerMacros
end
#spec/support/controller_macros.rb
module ControllerMacros
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mapping[:user]
user = FactoryGirl.create(:user)
sign_in user
end
end
end
#spec/support/devise.rb
Spec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
in my request spec
#spec/features/documents_spec.rb
require 'spec_helper'
describe "Documents" do
login_user
describe "GET /documents" do
it "should display document name as sameera CV" do
#spec code
end
end
end
and when I run bundle exec guard, I get
1) Documents GET /documents should display document name as sameera CV
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `env' for nil:NilClass
# ./spec/support/controller_macros.rb:4:in `block in login_user'
So far I have done lots of fixes via google and nothing seems to be working, can someone help me :)
I'm on
rails 3.2.9
rspec 2.12.0
devise 2.2.3
any help would be greatly appreciated
Try changing #request.env["devise.mapping"] = Devise.mapping[:user] to request.env["devise.mapping"] = Devise.mapping[:user] in spec/support/controller_macros.rb
Here I'm answering my own question, and I was able to find a workaround for the question I asked.
Following are the steps I did
1) removed the controller_macros.rb and devise.rb from support directory
2) removed the ControllerMacros references from spec_helper.rb
3) Added the following code to
#spec/features/documents_spec.rb
before(:each) do
user = FactoryGirl.create(:user)
visit root_path
fill_in 'user_email', :with => user.email
fill_in 'user_password', :with => user.password
click_button 'Sign in'
end
I'm sure there should be a more elegant way (as describe in devise wiki), but this WORKS :)

rails 3.1.rc6 + factorygirl+ devise + spec2 => undefined method `Factory' for #<RSpec::Core::ExampleGroup::

my gem file looks like
source 'http://rubygems.org'
gem 'rails', '3.1.0.rc6'
gem 'sqlite3'
gem 'devise'
gem 'will_paginate'
gem 'therubyracer'
group :assets do
gem 'sass-rails', " ~> 3.1.0.rc"
gem 'coffee-rails', "~> 3.1.0.rc"
gem 'uglifier'
end
gem 'jquery-rails'
group :test do
gem 'turn', :require => false
gem 'rspec-rails'
gem 'webrat'
end
group :development do
gem 'rspec-rails'
gem 'webrat'
gem 'spork'
gem 'factory_girl_rails'
gem 'capybara'
gem 'guard-rspec'
end
my factories.rb
Factory.define :user do |user|
user.username "ccc"
user.email "ccc#eg.com"
user.password "foobar"
user.password_confirmation "foobar"
end
Factory.define :user_hero do |hero|
hero.supername "superman"
hero.association :user
end
my hero_controller_spec looks like this
require 'spec_helper'
describe HerosController do
include Devise::TestHelpers
render_views
before(:each) do
#user = Factory(:user)
# #request.env["devise.mapping"] = :user
# #user = Factory.create(:user)
sign_in #user
#hero_attr = {
:supername => "superman",
}
end
it "should create a new instance with valid attributes" do
#user.heros.create!(#hero_attr)
end
end
My autotest or guard shows up the following message
Failures:
1) HerosController should create a new instance with valid attributes
Failure/Error: #user = Factory(:user)
NoMethodError:
undefined method `Factory' for #<RSpec::Core::ExampleGroup::Nested_1:0x000001028a3998>
# ./spec/controllers/heros_controller_spec.rb:8:in `block (2 levels) in <top (required)>'
Finished in 0.00726 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/heros_controller_spec.rb:33 # HerosController should create a new instance with valid attributes
in spec_helper.rb
add the following
require 'factory_girl'
load 'factories.rb'
Try this:
#user.HerosController.create!(#hero_attr)
in place of:
#user.create!(#hero_attr)
Factory Girl needs to be in the test group otherwise it never gets loaded when you run your specs. Currently it's loaded only in your development group.
Try this
#user = FactoryGirl(:user)
or
#user = FactoryGirl.create(:user)