I am running tests that starts by logging in a user using the login form. It successfully opens Firefox, navigates to the login form and fills in the fields, but when it clicks the 'Login' button, it hangs indefinitely. When I quit Firefox the test that was running fails, but I am not getting any additional error message.
Any idea what I am doing wrong? This is driving me crazy and preventing me from testing a big portion of my app, any help would be much appreciated! Thanks!
Here is some additional info:
Rails 4.2.0
Ruby 2.2.4
Capybara 2.6.2
Selenium-Webdriver 2.53.0
Firefox 46.0.1
Using Capybara with RSpec
Capybara.javascript_driver = :selenium
/spec_helper.rb
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
require 'simplecov'
SimpleCov.start 'rails'
require 'capybara/rspec'
require 'aasm/rspec'
RSpec.configure do |config|
config.include Capybara::DSL
def test_sign_in(user)
# helper method to sign in the passed-in user
visit new_user_session_path
within ('#user-login-non-modal') do
within(".user-login") do
fill_in 'Email', with: user.email
fill_in 'Password', with: 'foobar11'
click_button 'Sign in'
end
end
end
def test_partner_sign_in(partner)
# helper method to sign in the passed-in partner
visit new_partner_session_path
within('#partner-login-non-modal') do
within(".partner-login") do
fill_in 'Email', with: partner.email
fill_in 'Password', with: 'foobar11'
click_button 'Sign in'
end
end
end
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
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
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
# if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
# config.default_formatter = 'doc'
# end
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
/rails_helper.rb
# 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'
require 'devise'
require 'controller_macros'
require 'byebug'
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include Devise::TestHelpers, :type => :controller
config.include Rails.application.routes.url_helpers
config.extend ControllerMacros, :type => :controller
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
end
/test.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure static asset server for tests with Cache-Control for performance.
config.serve_static_files = true
config.static_cache_control = 'public, max-age=3600'
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# For Devise
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
.rspec
--color
--require spec_helper
--drb
Edit:
user_pages_spec.rb
describe "show page" do
before do
# #user = FactoryGirl.create(:user)
#user = User.invite!(:email => "test_user#example.com", :skip_invitation => true)
#user.accept_invitation!
#user.password = "foobar11"
#user.first_name = "John"
#user.last_name = "Smith"
#user.save
#car1 = FactoryGirl.create(:car, user: #user)
#car2 = FactoryGirl.create(:car, user: #user)
#tomorrow = Time.now + 24*60*60
#earlier_today = Time.now - 30
#app_in_future1 = FactoryGirl.create(:appointment, car: #car1, garage: #car1.garage, pickuptime: #tomorrow)
#app_in_future2 = FactoryGirl.create(:appointment, car: #car1, garage: #car1.garage, pickuptime: #tomorrow + 24*60*60)
#app_in_past = FactoryGirl.build(:appointment, car: #car1, garage: #car1.garage, pickuptime: #earlier_today)
#app_in_past.save(validate: false)
different_pickup_time = #tomorrow + 60*60
#different_user = FactoryGirl.create(:user)
#car_different_user = FactoryGirl.create(:car, make: "diff_make", user: #different_user)
#app_different_user = FactoryGirl.create(:appointment, car: #car_different_user, garage: #car_different_user.garage, pickuptime: different_pickup_time)
test_sign_in(#user)
end
describe "adding an appointment to a car", js:true do
context "when the appointment is in the future" do
it "should increment the number of the car's appointments" do
expect do
within(".create-appt-row-#{#car1.id}") do
click_button 'Add Appointment'
fill_in 'appointment_pickuptime', with: "12/07/2100 4:57 PM"
click_button 'Book It'
end
end.to change(#car1.appointments, :count).by(1)
end
end
end
Edit 3:
After updating to selenium-webdriver 2.53.4 and re-running the test that requires the user-login, Firefox is hanging indefinitely, and when I quit Firefox manually I get this error message with the failing test:
Failure/Error: visit new_user_session_path
Errno::ECONNREFUSED:
Connection refused - connect(2) for "127.0.0.1" port 7055
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/default.rb:107:in `response_for'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/default.rb:58:in `request'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:134:in `get'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/common/navigation.rb:33:in `to'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/selenium/driver.rb:45:in `visit'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/session.rb:232:in `visit'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
# ./spec/spec_helper.rb:23:in `test_sign_in'
# ./spec/requests/user_pages_spec.rb:31:in `block (3 levels) in <top (required)>'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/test_framework/rspec.rb:12:in `run_tests'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:13:in `block in run'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:21:in `block in initialize'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:18:in `fork'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:18:in `initialize'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:9:in `new'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:9:in `run'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/server.rb:49:in `run'
Edit 4:
test.log after running the test that hangs
[1m[36mActiveRecord::SchemaMigration Load (0.6ms)[0m [1mSELECT "schema_migrations".* FROM "schema_migrations"[0m
[1m[35m (0.2ms)[0m BEGIN
[1m[36m (0.2ms)[0m [1mCOMMIT[0m
[1m[35m (0.1ms)[0m BEGIN
[1m[36m (1.7ms)[0m [1mALTER TABLE "active_admin_comments" DISABLE TRIGGER ALL;ALTER TABLE "authorizations" DISABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" DISABLE TRIGGER ALL;ALTER TABLE "garagepartners" DISABLE TRIGGER ALL;ALTER TABLE "cars" DISABLE TRIGGER ALL;ALTER TABLE "locations" DISABLE TRIGGER ALL;ALTER TABLE "partners" DISABLE TRIGGER ALL;ALTER TABLE "appointments" DISABLE TRIGGER ALL;ALTER TABLE "images" DISABLE TRIGGER ALL;ALTER TABLE "garages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "companies" DISABLE TRIGGER ALL;ALTER TABLE "damages" DISABLE TRIGGER ALL;ALTER TABLE "admin_users" DISABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" DISABLE TRIGGER ALL[0m
[1m[35m (2.3ms)[0m SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND
schemaname = ANY (current_schemas(false))
[1m[36m (2.0ms)[0m [1mselect table_name from information_schema.views where table_schema = 'parkme3_test'[0m
[1m[35m (55.4ms)[0m TRUNCATE TABLE "public"."active_admin_comments", "public"."authorizations", "public"."authorized_drivers", "public"."garagepartners", "public"."cars", "public"."locations", "public"."partners", "public"."appointments", "public"."images", "public"."garages", "public"."users", "public"."companies", "public"."damages", "public"."admin_users", "public"."delayed_jobs" RESTART IDENTITY CASCADE;
[1m[36m (0.9ms)[0m [1mALTER TABLE "active_admin_comments" ENABLE TRIGGER ALL;ALTER TABLE "authorizations" ENABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" ENABLE TRIGGER ALL;ALTER TABLE "garagepartners" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "cars" ENABLE TRIGGER ALL;ALTER TABLE "locations" ENABLE TRIGGER ALL;ALTER TABLE "partners" ENABLE TRIGGER ALL;ALTER TABLE "appointments" ENABLE TRIGGER ALL;ALTER TABLE "images" ENABLE TRIGGER ALL;ALTER TABLE "garages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL;ALTER TABLE "companies" ENABLE TRIGGER ALL;ALTER TABLE "damages" ENABLE TRIGGER ALL;ALTER TABLE "admin_users" ENABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" ENABLE TRIGGER ALL[0m
[1m[35mUser Load (1.4ms)[0m SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["email", "test_user#example.com"]]
[1m[36mUser Load (0.6ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."invitation_token" = $1 ORDER BY "users"."id" ASC LIMIT 1[0m [["invitation_token", "12f7e3e1ca7f4be3bf7ebc51410444e1b49d703cade994df75ca75a2e49fed3e"]]
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.7ms)[0m [1mINSERT INTO "users" ("receive_email_notification", "receive_text_notification", "email", "encrypted_password", "invitation_token", "invitation_created_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["receive_email_notification", "t"], ["receive_text_notification", "t"], ["email", "test_user#example.com"], ["encrypted_password", "$2a$04$dzJj7097jsrmaWOfVGqrq.F4wcKx4yktACtDVjI7IXbt6u83C7.QO"], ["invitation_token", "12f7e3e1ca7f4be3bf7ebc51410444e1b49d703cade994df75ca75a2e49fed3e"], ["invitation_created_at", "2016-07-15 15:02:23.921974"], ["created_at", "2016-07-15 15:02:23.923749"], ["updated_at", "2016-07-15 15:02:23.923749"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.3ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.5ms)[0m UPDATE "users" SET "invitation_accepted_at" = $1, "invitation_token" = $2, "updated_at" = $3 WHERE "users"."id" = $4 [["invitation_accepted_at", "2016-07-15 15:02:23.929347"], ["invitation_token", nil], ["updated_at", "2016-07-15 15:02:23.930593"], ["id", 1]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.5ms)[0m [1mUPDATE "users" SET "encrypted_password" = $1, "first_name" = $2, "last_name" = $3, "updated_at" = $4 WHERE "users"."id" = $5[0m [["encrypted_password", "$2a$04$c8LSFWcTJXE7np2W838iLui3lHt7yYXSjQvhQoxt91EqkW1xvBr1q"], ["first_name", "John"], ["last_name", "Smith"], ["updated_at", "2016-07-15 15:02:23.938120"], ["id", 1]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.5ms)[0m INSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "company_1"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:23.977122"], ["updated_at", "2016-07-15 15:02:23.977122"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.6ms)[0m [1mINSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"[0m [["name", "garage_1"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 1], ["created_at", "2016-07-15 15:02:23.982258"], ["updated_at", "2016-07-15 15:02:23.982258"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.7ms)[0m INSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["make", "make_1"], ["car_model", "car_model_1"], ["year", 2014], ["car_number", 1], ["garage_id", 1], ["user_id", 1], ["created_at", "2016-07-15 15:02:23.988597"], ["updated_at", "2016-07-15 15:02:23.988597"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"[0m [["name", "company_2"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:23.996186"], ["updated_at", "2016-07-15 15:02:23.996186"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id" [["name", "garage_2"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 2], ["created_at", "2016-07-15 15:02:23.999804"], ["updated_at", "2016-07-15 15:02:23.999804"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.4ms)[0m [1mINSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["make", "make_2"], ["car_model", "car_model_2"], ["year", 2014], ["car_number", 2], ["garage_id", 2], ["user_id", 1], ["created_at", "2016-07-15 15:02:24.003820"], ["updated_at", "2016-07-15 15:02:24.003820"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.6ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-16 15:02:24.006227"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.026603"], ["updated_at", "2016-07-15 15:02:24.026603"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.4ms)[0m [1mINSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"[0m [["aasm_state", "scheduled"], ["pickuptime", "2016-07-17 15:02:24.006227"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.033088"], ["updated_at", "2016-07-15 15:02:24.033088"]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-15 15:01:54.006233"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.039517"], ["updated_at", "2016-07-15 15:02:24.039517"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mUser Exists (0.5ms)[0m [1mSELECT 1 AS one FROM "users" WHERE "users"."email" = 'person_1#example.com' LIMIT 1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "users" ("receive_email_notification", "receive_text_notification", "email", "encrypted_password", "invitation_accepted_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["receive_email_notification", "t"], ["receive_text_notification", "t"], ["email", "person_1#example.com"], ["encrypted_password", "$2a$04$glYjOuWxkRp06jc/l1X0ceeI5OD.eqWMzsnt/MRhizfX7RuD7ti9m"], ["invitation_accepted_at", "2016-07-15 14:02:24.045381"], ["created_at", "2016-07-15 15:02:24.053170"], ["updated_at", "2016-07-15 15:02:24.053170"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"[0m [["name", "company_3"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:24.060156"], ["updated_at", "2016-07-15 15:02:24.060156"]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.1ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id" [["name", "garage_3"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 3], ["created_at", "2016-07-15 15:02:24.063107"], ["updated_at", "2016-07-15 15:02:24.063107"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["make", "diff_make"], ["car_model", "car_model_3"], ["year", 2014], ["car_number", 3], ["garage_id", 3], ["user_id", 2], ["created_at", "2016-07-15 15:02:24.066940"], ["updated_at", "2016-07-15 15:02:24.066940"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-16 16:02:24.006227"], ["car_id", 3], ["garage_id", 3], ["created_at", "2016-07-15 15:02:24.071953"], ["updated_at", "2016-07-15 15:02:24.071953"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
Started GET "/login" for 127.0.0.1 at 2016-07-15 11:02:26 -0400
Processing by Users::SessionsController#new as HTML
Rendered users/sessions/_new.html.erb (75.4ms)
Rendered users/sessions/new.html.erb within layouts/application (82.6ms)
Rendered layouts/_shim.html.erb (0.2ms)
Rendered application/_favicon.html.erb (1.2ms)
Rendered users/sessions/_new.html.erb (8.2ms)
Rendered partners/sessions/_new.html.erb (16.3ms)
Rendered layouts/_header.html.erb (27.6ms)
Rendered layouts/_footer.html.erb (1.2ms)
Rendered layouts/_google_analytics.html.erb (1.0ms)
Completed 200 OK in 206ms (Views: 190.7ms | ActiveRecord: 0.0ms)
Started POST "/login" for 127.0.0.1 at 2016-07-15 11:02:28 -0400
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "user"=>{"email"=>"test_user#example.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
This is where it hung. The rest of the log appeared after the test timed out.
[1m[35m (0.5ms)[0m ALTER TABLE "active_admin_comments" DISABLE TRIGGER ALL;ALTER TABLE "authorizations" DISABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" DISABLE TRIGGER ALL;ALTER TABLE "garagepartners" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "cars" DISABLE TRIGGER ALL;ALTER TABLE "locations" DISABLE TRIGGER ALL;ALTER TABLE "partners" DISABLE TRIGGER ALL;ALTER TABLE "appointments" DISABLE TRIGGER ALL;ALTER TABLE "images" DISABLE TRIGGER ALL;ALTER TABLE "garages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL;ALTER TABLE "companies" DISABLE TRIGGER ALL;ALTER TABLE "damages" DISABLE TRIGGER ALL;ALTER TABLE "admin_users" DISABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" DISABLE TRIGGER ALL
[1m[36m (45.9ms)[0m [1mTRUNCATE TABLE "public"."active_admin_comments", "public"."authorizations", "public"."authorized_drivers", "public"."garagepartners", "public"."cars", "public"."locations", "public"."partners", "public"."appointments", "public"."images", "public"."garages", "public"."users", "public"."companies", "public"."damages", "public"."admin_users", "public"."delayed_jobs" RESTART IDENTITY CASCADE;[0m
[1m[35m (0.8ms)[0m ALTER TABLE "active_admin_comments" ENABLE TRIGGER ALL;ALTER TABLE "authorizations" ENABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" ENABLE TRIGGER ALL;ALTER TABLE "garagepartners" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "cars" ENABLE TRIGGER ALL;ALTER TABLE "locations" ENABLE TRIGGER ALL;ALTER TABLE "partners" ENABLE TRIGGER ALL;ALTER TABLE "appointments" ENABLE TRIGGER ALL;ALTER TABLE "images" ENABLE TRIGGER ALL;ALTER TABLE "garages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL;ALTER TABLE "companies" ENABLE TRIGGER ALL;ALTER TABLE "damages" ENABLE TRIGGER ALL;ALTER TABLE "admin_users" ENABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" ENABLE TRIGGER ALL
This was in the Spork console after the test timed out:
1.1) Failure/Error: click_button 'Sign in'
Net::ReadTimeout:
Net::ReadTimeout
users/sessions_controller.rb (using Devise)
class Users::SessionsController < Devise::SessionsController
include ApplicationHelper
def create
super
end
def new
render 'new'
end
def after_sign_in_path_for(resource)
user_path(resource)
end
end
Got stuck at this point when stepping through the controller using byebug:
in /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/devise-3.5.6/app/controllers/devise/sessions_controller.rb
12: respond_with(resource, serialize_options(resource))
13: end
14:
15: # POST /resource/sign_in
16: def create
=> 17: self.resource = warden.authenticate!(auth_options)
After stepping into that, I got stuck here:
in /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/warden-1.2.6/lib/warden/proxy.rb
122: # Example
123: # env['warden'].authenticate!(:password, :scope => :publisher) # throws if it cannot authenticate
124: #
125: # :api: public
126: def authenticate!(*args)
=> 127: user, opts = _perform_authentication(*args)
128: throw(:warden, opts) unless user
129: user
130: end
After pulling out a lot of hair, this is what ended up working:
Change:
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
end
To:
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
And add config.use_transactional_fixtures = false to rails_helper.rb, which had been there at the beginning and had been removed at some point in the many iterations of configurations that I had tried.
Either way, hopefully this saves someone else a headache!
I have a model called as Template which has self referential has-many through association with a join model called as RelatedTemplate.
The Template model is written like this:
has_many :related_templates, :foreign_key => :parent_id
has_many :children, :through => :related_templates, :source => :child
has_many :inverse_related_templates, class_name: "RelatedTemplate", :foreign_key => :child_id
has_many :parents, :through => :inverse_related_templates, :source => :parent
validates :name, presence: true, uniqueness: { case_sensitive: false },
length: { maximum: 100, too_long: "should be maximum %{count} characters" }
The join-model RelatedTemplate is:
belongs_to :parent, class_name: 'Template'
belongs_to :child, class_name: 'Template'
In the console when i tried to create a child template with the same name as the parent name then the validation doesn't work:
rails c --sandbox
Loading development environment in sandbox (Rails 4.2.5)
Any modifications you make will be rolled back on exit
irb(main):001:0> a = Template.new
=> #<Template id: nil, client_id: nil, something_id: nil, name: nil, description: nil, another_something_id: nil, video_id: nil, container_id: nil>
irb(main):002:0> a.something_id=1
=> 1
irb(main):003:0> a.name="Hamza"
=> "Hamza"
irb(main):004:0> a.another_something_id=16
=> 16
irb(main):005:0> a.container_id=2
=> 2
irb(main):006:0> a.children.build(name: "Hamza", another_something_id: 16, container_id: 2)
=> #<Template id: nil, client_id: nil, something_id: nil, name: "Hamza", description: nil, another_something_id: 16, video_id: nil, container_id: 2>
irb(main):007:0> a.save
(0.9ms) SAVEPOINT active_record_1
Template Exists (1.3ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.7ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
Template Exists (0.5ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.2ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
SQL (0.3ms) INSERT INTO "templates" ("something_id", "name", "another_something_id", "container_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["something_id", 1], ["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
SQL (0.2ms) INSERT INTO "templates" ("name", "another_something_id", "container_id") VALUES ($1, $2, $3) RETURNING "id" [["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
SQL (0.6ms) INSERT INTO "related_templates" ("parent_id", "child_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["parent_id", 156], ["child_id", 157], ["created_at", "2016-05-05 07:03:51.496346"], ["updated_at", "2016-05-05 07:03:51.496346"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
=> true
Now the query:
irb(main):016:0> a.name
=> "Hamza"
irb(main):017:0> a.children.first.name
Template Load (1.9ms) SELECT "templates".* FROM "templates" INNER JOIN "related_templates" ON "templates"."id" = "related_templates"."child_id" WHERE "related_templates"."parent_id" = $1 ORDER BY "templates"."id" ASC LIMIT 1 [["parent_id", 158]]
=> "Hamza"
Dont know what is wrong here ?
Both object only exist in memory, when you validate them. The uniqueness validation passes in both cases, because the validation checks if there is a similar record in the database already.
Have a look at the logs:
# you call save
irb(main):007:0> a.save
(0.9ms) SAVEPOINT active_record_1
# Rails validates the first object
Template Exists (1.3ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.7ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
# Rails validates the second object
Template Exists (0.5ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.2ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
# At this point Rails thinks that both records will be fine, because the validation passed
# Rails saved the first object
SQL (0.3ms) INSERT INTO "templates" ("something_id", "name", "another_something_id", "container_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["something_id", 1], ["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
# Rails saved the second object
SQL (0.2ms) INSERT INTO "templates" ("name", "another_something_id", "container_id") VALUES ($1, $2, $3) RETURNING "id" [["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
This is good example why Rails uniqueness validations are not 100% secure. Another example might be race conditions, when multiple requests hit the application at the same time.
The only way to avoid this kind of problems, is to add a unique index to the database table.
I'm tried to create a User in the console doing:
2.2.1 :012 > u.save!
(0.2ms) BEGIN
User Exists (0.7ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('noc#co.co') LIMIT 1
SQL (2.1ms) INSERT INTO "users" ("id", "first_name", "last_name", "email", "title", "time_zone", "company_id", "password_digest", "created_at", "updated_at", "activation_digest") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["id", 200], ["first_name", "Random"], ["last_name", "Dude"], ["email", "noc#co.co"], ["title", "CEO"], ["time_zone", "Stockholm"], ["company_id", 1], ["password_digest", "$2a$10$bHHA/JP5IMrucGUXRWMpsO8sInaouSqn48M.fDHpjGdvedu3Napra"], ["created_at", "2015-10-11 23:09:38.213109"], ["updated_at", "2015-10-11 23:09:38.213109"], ["activation_digest", "$2a$10$WF3bUOtbC1gk4ZnX58cJZO5k7P7YV6wvhmwz7EErTdvIseNuy0oyq"]]
2.2.1 :013 > u.activation_token
=> "vKrs0jtvZRiyU-YVE-aPXw"
now when I try to create a user the before_create doesn't work, I tried changing it to before_validation and that didn't work either.
The user is a nested attribute from companies, and is created in Companies#new.
class User < ActiveRecord::Base
belongs_to :company
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
now when I do #user.activation_token it returns nil. Here's the console log from when I try it on the app:
Started POST "/companies" for ::1 at 2015-10-12 01:31:47 +0200
Processing by CompaniesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZTEtGR2Dd1FDDYm9j4/SiqSTP646R8gctFx4aJHM9QDP+RQky8SG6gkomLbf+E+LgMi+aah1YOhCkUsg3uSYoQ==", "company"=>{"time_zone"=>"Stockholm", "users_attributes"=>{"0"=>{"first_name"=>"swaga", "last_name"=>"swaga", "email"=>"swaga#wkoa.com", "password"=>"[FILTERED]"}}, "name"=>"swaga"}, "commit"=>"Create Company"}
(0.2ms) BEGIN
User Exists (1.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('swaga#wkoa.com') LIMIT 1
SQL (7.1ms) INSERT INTO "companies" ("name", "time_zone", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "swaga"], ["time_zone", "Stockholm"], ["created_at", "2015-10-11 23:31:47.380530"], ["updated_at", "2015-10-11 23:31:47.380530"]]
SQL (0.5ms) INSERT INTO "users" ("first_name", "last_name", "email", "password_digest", "activation_digest", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["first_name", "swaga"], ["last_name", "swaga"], ["email", "swaga#wkoa.com"], ["password_digest", "$2a$10$3GsPACTg5HPodiqdedsCvu52N64BEE3/fA77p.oBHAhM51zCSzUV."], ["activation_digest", "$2a$10$75y9jP.eZxmWI1KjHZrg3.DuB5GSwiS2UsaQdtV25ClBHDi.z4Pte"], ["company_id", 8], ["created_at", "2015-10-11 23:31:47.390462"], ["updated_at", "2015-10-11 23:31:47.390462"]]
(6.7ms) COMMIT
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."company_id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["company_id", 8]]
Rendered user_mailer/account_activation.html.erb within layouts/mailer (7.8ms)
UserMailer#account_activation: processed outbound mail in 29.2ms
Completed 500 Internal Server Error in 380ms (ActiveRecord: 16.9ms)
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
now I see that the activation_digest is returned, so I think the issue is literarily just the before_create not working? Which is weird because then it shouldn't be able to create an activation digest as the two are connected:
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
Your error says:
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
Seems like, in your view, you are calling edit_account_activation_path without the id param and that's creating the problem for you. Try to send the user.id as a parameter in the edit_account_activation_path call.
Something like this:
edit_account_activation_path(user.email, user.id)
That should fix your issue.