RSpec + Poltergeist fails when setting authenticity_token - ruby-on-rails

I am trying to test a feature in my Rails app using RSpec + Polgergeist.
My feature spec is very basic right now:
RSpec.feature 'Listing owners can create new listings' do
let(:owner) { create(:user, :owner) }
before do
login_as owner
# I've also tried this with as recommended by Devise when using Capybara-Webkit:
# login_as(user, scope: :user, run_callbacks: false)
visit new_listing_path
end
scenario 'successfully', js: true do
fill_in 'Field 1', with: 'Example'
click_link 'Create'
# expectations here...
end
end
I have the following in my rails_helper.rb
require 'capybara/poltergeist'
RSpec.configure do |config|
# ...
config.include Warden::Test::Helpers, type: :feature
config.after(type: :feature) { Warden.test_reset! }
# ...
end
and in a support/poltergeist.rb file
RSpec.configure do |config|
Capybara.javascript_driver = :poltergeist
# Increase timeout in case asset compilation
# takes longer than anticipated.
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {timeout: 60})
end
end
The precise location that is failing is this, where I set the CSRF token using Vue.js:
import Vue from 'vue/dist/vue.esm'
import VueResource from 'vue-resource'
Vue.use(VueResource)
document.addEventListener('DOMContentLoaded', () => {
if(document.getElementById('listing-multistep') !== null) {
Vue.http.headers.common['X-CSRF-Token'] = document.querySelector('input[name="authenticity_token"]').getAttribute('value');
var listingForm = document.getElementById('listing_form');
var listing = JSON.parse(listingForm.dataset.listing);
// do magic....
}
});
The authenticity token is set from the Rails form partial, _form.html.erb:
<%= form_for(
listing,
html: { multipart: true, id: 'listing_form',
data: {
listing: listing.to_json(except: [:user_id, :created_at, :updated_at])
}
}) do |f| %>
<fieldset class="listing-step" v-show="activeStep === 0">
<%= render 'listings/form/basics', f: f, listing: listing %>
</fieldset>
<fieldset class="listing-step" v-show="activeStep === 1">
<%= render 'listings/form/location', f: f, listing: listing %>
</fieldset>
<fieldset class="listing-step" v-show="activeStep === 2">
<%= render 'listings/form/amenities', f: f, listing: listing %>
</fieldset>
<fieldset class="listing-step" v-show="activeStep === 3">
<%= render 'listings/form/description', f: f, listing: listing %>
</fieldset>
<% end %>
Setting the CSRF token this way seems to work in development, but when I run the spec, I am seeing the following error:
Failure/Error: visit new_listing_path
Capybara::Poltergeist::JavascriptError:
One or more errors were raised in the Javascript code on the page. If you don't care about these errors, you can ignore them by setting js_errors: false in your Poltergeist configuration (see documentation for details).
TypeError: null is not an object (evaluating 'document.querySelector('input[name="authenticity_token"]').getAttribute')
TypeError: null is not an object (evaluating 'document.querySelector('input[name="authenticity_token"]').getAttribute')
at http://127.0.0.1:54450/packs-test/dashboard-ca7eeed2cc4b22399ade.js:13086
All I can think of is that poltergeist isn't waiting for the DOM to load fully, but that would be strange because I have explicitly written the vue code within document.addEventListener('DOMContentLoaded', () => {
As an aside, I also have a support/database_cleaner.rb file with the following contents:
RSpec.configure do |conf|
conf.before(:suite) do
DatabaseCleaner.clean_with :truncation
end
conf.before(:each) do
DatabaseCleaner.strategy = :transaction
end
conf.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
conf.before(:each) do
DatabaseCleaner.start
end
conf.after(:each) do
DatabaseCleaner.clean
end
end
Any idea what may be causing the aforementioned error? Any help is much appreciated!
Thanks in advance
UPDATE
Here is a copy of the test.log file that is generated when I run the spec:
(1.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
(0.2ms) BEGIN
(2.1ms) ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL;ALTER TABLE "subscriptions" DISABLE TRIGGER ALL;ALTER TABLE "listings" DISABLE TRIGGER ALL;ALTER TABLE "advertisements" DISABLE TRIGGER ALL;ALTER TABLE "chatroom_users" DISABLE TRIGGER ALL;ALTER TABLE "chatrooms" DISABLE TRIGGER ALL;ALTER TABLE "messages" DISABLE TRIGGER ALL;ALTER TABLE "pictures" DISABLE TRIGGER ALL;ALTER TABLE "friendly_id_slugs" DISABLE TRIGGER ALL;ALTER TABLE "contact_messages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
(0.7ms) COMMIT
(3.9ms) SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND tablename <> 'ar_internal_metadata' AND
schemaname = ANY (current_schemas(false))
(2.5ms) select table_name from information_schema.views where table_schema = 'salayo_test'
(48.9ms) TRUNCATE TABLE "public"."subscriptions", "public"."listings", "public"."advertisements", "public"."chatroom_users", "public"."chatrooms", "public"."messages", "public"."pictures", "public"."friendly_id_slugs", "public"."contact_messages", "public"."users" RESTART IDENTITY CASCADE;
(1.3ms) BEGIN
(1.7ms) ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" ENABLE TRIGGER ALL;ALTER TABLE "subscriptions" ENABLE TRIGGER ALL;ALTER TABLE "listings" ENABLE TRIGGER ALL;ALTER TABLE "advertisements" ENABLE TRIGGER ALL;ALTER TABLE "chatroom_users" ENABLE TRIGGER ALL;ALTER TABLE "chatrooms" ENABLE TRIGGER ALL;ALTER TABLE "messages" ENABLE TRIGGER ALL;ALTER TABLE "pictures" ENABLE TRIGGER ALL;ALTER TABLE "friendly_id_slugs" ENABLE TRIGGER ALL;ALTER TABLE "contact_messages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL
(0.6ms) COMMIT
(0.3ms) BEGIN
User Exists (2.0ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "dianna_kilback#okeefemccullough.org"], ["LIMIT", 1]]
SQL (1.1ms) INSERT INTO "users" ("first_name", "last_name", "email", "encrypted_password", "created_at", "updated_at", "role") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["first_name", "Hermann"], ["last_name", "VonRueden"], ["email", "dianna_kilback#okeefemccullough.org"], ["encrypted_password", "$2a$04$sSAdYthaHRhqjUqaing/weltoDcyHyR5Fyr2Pw/8xOtvz4mMPwWYm"], ["created_at", "2018-04-01 05:32:07.693349"], ["updated_at", "2018-04-01 05:32:07.693349"], ["role", 2]]
(0.6ms) COMMIT
Started GET "/en/listings/new" for 127.0.0.1 at 2018-04-01 14:32:09 +0900
(0.2ms) BEGIN
SQL (2.5ms) UPDATE "users" SET "sign_in_count" = $1, "current_sign_in_at" = $2, "last_sign_in_at" = $3, "current_sign_in_ip" = $4, "last_sign_in_ip" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["sign_in_count", 1], ["current_sign_in_at", "2018-04-01 05:32:09.833321"], ["last_sign_in_at", "2018-04-01 05:32:09.833321"], ["current_sign_in_ip", "127.0.0.1/32"], ["last_sign_in_ip", "127.0.0.1/32"], ["updated_at", "2018-04-01 05:32:09.866550"], ["id", 1]]
(0.6ms) COMMIT
Processing by ListingsController#new as HTML
Parameters: {"locale"=>"en"}
Rendering listings/new.html.erb within layouts/dashboard
Rendered listings/_prev_next_buttons.html.erb (3.6ms)
Rendered listings/form/_basics.html.erb (30.6ms)
Rendered listings/form/_location.html.erb (2.9ms)
Rendered listings/form/_amenities.html.erb (0.5ms)
Rendered listings/form/_description.html.erb (3.5ms)
Rendered listings/_form.html.erb (79.4ms)
Rendered listings/new.html.erb within layouts/dashboard (127.9ms)
Rendered common/_meta_tags.html.erb (1.2ms)
Rendered dashboard/_sidebar.html.erb (23.4ms)
Rendered dashboard/_topbar.html.erb (4.7ms)
Rendered common/_notices.html.erb (2.0ms)
Rendered common/_footer.html.erb (4.9ms)
Completed 200 OK in 980ms (Views: 877.4ms | ActiveRecord: 19.7ms)
Started GET "/assets/application-a2d7fced50ec51954f27ed1fab4792ab0cd3b9b88ff496fc07bd2489660a7c42.css" for 127.0.0.1 at 2018-04-01 14:32:10 +0900
Started GET "/assets/application-e7598b8619f2ba6c7b08ce9a5471f5e4b5223c384a09f8826ae19a864a9bc6b4.js" for 127.0.0.1 at 2018-04-01 14:32:10 +0900
Started GET "/cable" for 127.0.0.1 at 2018-04-01 14:32:11 +0900
Started GET "/assets/bg_logo-db2dd881e08b614d8971e623eb0a14df67c93a5615c04ec2d7c2967893d44b2c.svg" for 127.0.0.1 at 2018-04-01 14:32:11 +0900
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-04-01 14:32:11 +0900
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Started GET "/assets/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff" for 127.0.0.1 at 2018-04-01 14:32:11 +0900
(0.3ms) BEGIN
(1.6ms) ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL;ALTER TABLE "subscriptions" DISABLE TRIGGER ALL;ALTER TABLE "listings" DISABLE TRIGGER ALL;ALTER TABLE "advertisements" DISABLE TRIGGER ALL;ALTER TABLE "chatroom_users" DISABLE TRIGGER ALL;ALTER TABLE "chatrooms" DISABLE TRIGGER ALL;ALTER TABLE "messages" DISABLE TRIGGER ALL;ALTER TABLE "pictures" DISABLE TRIGGER ALL;ALTER TABLE "friendly_id_slugs" DISABLE TRIGGER ALL;ALTER TABLE "contact_messages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
(0.5ms) COMMIT
(56.7ms) TRUNCATE TABLE "public"."subscriptions", "public"."listings", "public"."advertisements", "public"."chatroom_users", "public"."chatrooms", "public"."messages", "public"."pictures", "public"."friendly_id_slugs", "public"."contact_messages", "public"."users" RESTART IDENTITY CASCADE;
(1.7ms) BEGIN
(2.7ms) ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" ENABLE TRIGGER ALL;ALTER TABLE "subscriptions" ENABLE TRIGGER ALL;ALTER TABLE "listings" ENABLE TRIGGER ALL;ALTER TABLE "advertisements" ENABLE TRIGGER ALL;ALTER TABLE "chatroom_users" ENABLE TRIGGER ALL;ALTER TABLE "chatrooms" ENABLE TRIGGER ALL;ALTER TABLE "messages" ENABLE TRIGGER ALL;ALTER TABLE "pictures" ENABLE TRIGGER ALL;ALTER TABLE "friendly_id_slugs" ENABLE TRIGGER ALL;ALTER TABLE "contact_messages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL
(0.5ms) COMMIT

Related

Rspec's expect change count not working

Here I'm testing the changes in current_user.messages.count after the current user sends a valid message. Here's my code:
spec
scenario 'adds to their messages', js: true do
expect { find('#message_content').send_keys(:enter) }.to \
change(current_user.messages, :count).by(1)
end
test.log
# ...
ConversationChannel is transmitting the subscription confirmation
ConversationChannel is streaming from conversation_channel_1
(0.6ms) SELECT COUNT(*) FROM "messages" WHERE "messages"."user_id" = $1 [["user_id", 1]]
ConversationChannel#send_message({"content"=>"foobar\n", "conversation_id"=>"1"})
(0.3ms) BEGIN
(0.9ms) SELECT COUNT(*) FROM "messages" WHERE "messages"."user_id" = $1 [["user_id", 1]]
Conversation Load (1.6ms) SELECT "conversations".* FROM "conversations" WHERE "conversations"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.7ms) SELECT "users"."id" FROM "users" INNER JOIN "user_conversations" ON "users"."id" = "user_conversations"."user_id" WHERE "user_conversations"."conversation_id" = $1 [["conversation_id", 1]]
SQL (1.0ms) INSERT INTO "messages" ("content", "user_id", "conversation_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["content", "foobar\n"], ["user_id", 1], ["conversation_id", 1], ["created_at", "2018-01-29 11:27:13.095277"], ["updated_at", "2018-01-29 11:27:13.095277"]]
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-01-29 19:27:13 +0800
ConversationChannel stopped streaming from conversation_channel_1
(0.2ms) BEGIN
(58.8ms) COMMIT
(16.7ms) ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL;ALTER TABLE "conversations" DISABLE TRIGGER ALL;ALTER TABLE "messages" DISABLE TRIGGER ALL;ALTER TABLE "user_conversations" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
Rendered messages/_message.html.erb (0.6ms)
[ActionCable] Broadcasting to conversation_channel_1: {:message=>"<p>User 1: foobar\n</p>\n"}
# ...
The spec fails expected #count to have changed by 1, but was changed by 0 even though in the log shows INSERT INTO actually happen.
This doesn't work because you're not waiting long enough for the message addition to actually occur. send_keys returns as soon as the browser has been sent the key event, but knows nothing at all about any request/action triggered by that key press in the browser. This is why direct DB access tests are generally a bad idea in feature/system tests (which should generally just test user visible changes/interactions) and make more sense as request or controller.
That being said you could fix this by just sleeping after sending the key, but a better solution is to use one of the Capybara provided matchers (have waiting/retrying behavior) to synchronize the test.
scenario 'adds to their messages', js: true do
expect do
find('#message_content').send_keys(:enter) }
expect(page).to have_css(...) # check for whatever visible change on the page indicates the action triggered by send_keys has completed
end.to change { current_user.reload.messages.count }.by(1)
end
Note: This test is also very simple for a feature test. It's okay to have multiple expectations in a feature test since it's really meant to test a whole user interaction with a specific feature of your app. You might want to look at combining this test with other tests of the same part of your app.
Try to write :
change{current_user.messages, :count}.by(1)
with {}

Cannot Login User when Using Selenium with Rails/RSpec

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!

Why am I seeing DISABLE TRIGGER ALL in this output?

So I have a slightly unconventional Rails 4.2 application. There are no migrations associated with the models you see in the below statement(s). Instead to create the database tables, a db/car.sql was used.
But now when I run bundle exec rspec spec/models I get the below output. What is causing this output to appear? As far as I can tell the schema.rb file looks the same as if I had built it up using rails migration generator. There's a few database indexes but that's it.
rspec output
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
(0.4ms) ALTER TABLE "kites" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "tails" DISABLE TRIGGER ALL;ALTER TABLE "cars" DISABLE TRIGGER ALL;ALTER TABLE "car_washes" DISABLE TRIGGER ALL;ALTER TABLE "cars_engines" DISABLE TRIGGER ALL;ALTER TABLE "cities" DISABLE TRIGGER ALL;ALTER TABLE "engines" DISABLE TRIGGER ALL;ALTER TABLE "wheels" DISABLE TRIGGER ALL;ALTER TABLE "cars_wheels" DISABLE TRIGGER ALL
(0.4ms) ALTER TABLE "kites" DISABLE TRIGGER USER;ALTER TABLE "schema_migrations" DISABLE TRIGGER USER;ALTER TABLE "tails" DISABLE TRIGGER USER;ALTER TABLE "cars" DISABLE TRIGGER USER;ALTER TABLE "car_washes" DISABLE TRIGGER USER;ALTER TABLE "cars_engines" DISABLE TRIGGER USER;ALTER TABLE "cities" DISABLE TRIGGER USER;ALTER TABLE "engines" DISABLE TRIGGER USER;ALTER TABLE "wheels" DISABLE TRIGGER USER;ALTER TABLE "cars_wheels" DISABLE TRIGGER USER
(1.0ms) SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND
schemaname = ANY (current_schemas(false))
(0.8ms) select table_name from information_schema.views where table_schema = 'automobile_test'
(758.2ms) TRUNCATE TABLE "public"."kites", "public"."tails", "public"."cars", "public"."car_washes", "public"."cars_engines", "public"."cities", "public"."engines", "public"."wheels", "public"."cars_wheels" RESTART IDENTITY CASCADE;
(0.4ms) ALTER TABLE "kites" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "tails" ENABLE TRIGGER ALL;ALTER TABLE "car_washes" ENABLE TRIGGER ALL;ALTER TABLE "cars_engines" ENABLE TRIGGER ALL;ALTER TABLE "cities" ENABLE TRIGGER ALL;ALTER TABLE "engines" ENABLE TRIGGER ALL;ALTER TABLE "cars" ENABLE TRIGGER ALL;ALTER TABLE "wheels" ENABLE TRIGGER ALL;ALTER TABLE "cars_wheels" ENABLE TRIGGER ALL
(0.5ms) ALTER TABLE "kites" ENABLE TRIGGER USER;ALTER TABLE "schema_migrations" ENABLE TRIGGER USER;ALTER TABLE "tails" ENABLE TRIGGER USER;ALTER TABLE "car_washes" ENABLE TRIGGER USER;ALTER TABLE "cars_engines" ENABLE TRIGGER USER;ALTER TABLE "cities" ENABLE TRIGGER USER;ALTER TABLE "engines" ENABLE TRIGGER USER;ALTER TABLE "cars" ENABLE TRIGGER USER;ALTER TABLE "wheels" ENABLE TRIGGER USER;ALTER TABLE "cars_wheels" ENABLE TRIGGER USER
(0.1ms) BEGIN
(0.1ms) SAVEPOINT active_record_1
(0.1ms) RELEASE SAVEPOINT active_record_1
(0.1ms) SAVEPOINT active_record_1
(0.2ms) ROLLBACK TO SAVEPOINT active_record_1
(0.1ms) ROLLBACK

Specs are long to run because of truncation of tables

I have a Rails 4 app with simple specs. When I run a spec, it takes 26 seconds. If I look at the log, I can see this :
(38.5ms) ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE .............# tons of tables
(10.3ms) SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND
schemaname = ANY (current_schemas(false))
(2.3ms) select table_name from information_schema.views where table_schema = 'lap-test'
(10708.2ms) TRUNCATE TABLE "public"."bounded_facets_service_boutiques", "public"."versions", ..... # Tons of tables
(10823.0ms) TRUNCATE TABLE "public"."bounded_facets_service_boutiques", "public"."versions", .... #Tons of tables
(26.2ms) ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "bounded_facets_service_boutiques" ENABLE TRIGGER ALL;ALTER TABLE "versions" .... #Tons of tables
(0.6ms) BEGIN
(0.3ms) COMMIT
(0.2ms) BEGIN
(0.2ms) SAVEPOINT active_record_1
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.2ms) SAVEPOINT active_record_1
(0.5ms) SAVEPOINT active_record_2
Administrator Exists (1.9ms) SELECT 1 AS one FROM "administrators" WHERE "administrators"."email" = 'person1#labandprocess.com' LIMIT 1
SQL (2.3ms) INSERT INTO "administrators" .....
(0.6ms) RELEASE SAVEPOINT active_record_2
(0.4ms) ROLLBACK TO SAVEPOINT active_record_1
(0.6ms) ROLLBACK
As you can see, The truncation takes 10 seconds 2 times.
I use database cleaner with this :
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
I tested with other strategies without result.
There is a lot of seeds in development mod but it's on another database. There is 107 models in this project.
Is there a solution ?

RSpec use_transactional_fixtures=false not working

Setting use_transactional_fixtures=false in my spec_helper.rb file, though when I look at the output of my test log, it appears a transaction is still being used? Why is that the case and how do I eliminate the transaction?
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'
# Add additional requires below this line. Rails is not loaded until this point!
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.use_transactional_fixtures = false
config.infer_spec_type_from_file_location!
config.include FactoryGirl::Syntax::Methods
end
spec_helper.rb...
require 'devise'
require "paperclip/matchers"
require 'simplecov'
require 'database_cleaner'
require 'capybara/rspec'
SimpleCov.start 'rails'
module SphinxHelpers
def index
ThinkingSphinx::Test.index
# Wait for Sphinx to finish loading in the new index files.
sleep 0.25 until index_finished?
end
def index_finished?
Dir[Rails.root.join(ThinkingSphinx::Test.config.indices_location, '*.{new,tmp}*')].empty?
end
end
RSpec.configure do |config|
config.include SphinxHelpers
config.before(:suite) do
# Ensure sphinx directories exist for the test environment
ThinkingSphinx::Test.init
# Configure and start Sphinx, and automatically
# stop Sphinx at the end of the test suite.
ThinkingSphinx::Test.start_with_autostop
end
config.before(:each) do |example|
index
end
config.include Paperclip::Shoulda::Matchers
config.include Devise::TestHelpers, :type => :controller
config.raise_errors_for_deprecations!
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
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
end
RSpec::Matchers.define :accept_nested_attributes_for do |association|
match do |model|
#model = model
#nested_att_present = model.respond_to?("#{association}_attributes=".to_sym)
if #nested_att_present && #reject
model.send("#{association}_attributes=".to_sym,[#reject])
#reject_success = model.send("#{association}").empty?
end
if #nested_att_present && #accept
model.send("#{association}_attributes=".to_sym,[#accept])
#accept_success = ! (model.send("#{association}").empty?)
end
#nested_att_present && ( #reject.nil? || #reject_success ) && ( #accept.nil? || #accept_success )
end
failure_message_for_should do
messages = []
messages << "expected #{#model.class} to accept nested attributes for #{association}" unless #nested_att_present
messages << "expected #{#model.class} to reject values #{#reject.inspect} for association #{association}" unless #reject_success
messages << "expected #{#model.class} to accept values #{#accept.inspect} for association #{association}" unless #accept_success
messages.join(", ")
end
description do
desc = "accept nested attributes for #{expected}"
if #reject
desc << ", but reject if attributes are #{#reject.inspect}"
end
end
chain :but_reject do |reject|
#reject = reject
end
chain :and_accept do |accept|
#accept = accept
end
end
a spec that displays the problem....
require 'rails_helper'
RSpec.describe "The homepage", :type => :feature do
it "displays articles" do
article = create(:article)
visit "/"
assert page.has_css?(".article")
end
end
the test log output when running the spec (note the transaction)...
(0.2ms) ALTER TABLE "annotations" DISABLE TRIGGER ALL;ALTER TABLE "categories" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "articles" DISABLE TRIGGER ALL;ALTER TABLE "comments" DISABLE TRIGGER ALL;ALTER TABLE "contents" DISABLE TRIGGER ALL;ALTER TABLE "galleries" DISABLE TRIGGER ALL;ALTER TABLE "gallery_images" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
(13.5ms) TRUNCATE TABLE "annotations", "categories", "articles", "comments", "contents", "galleries", "gallery_images", "users" RESTART IDENTITY CASCADE;
(0.7ms) ALTER TABLE "annotations" ENABLE TRIGGER ALL;ALTER TABLE "categories" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "articles" ENABLE TRIGGER ALL;ALTER TABLE "comments" ENABLE TRIGGER ALL;ALTER TABLE "contents" ENABLE TRIGGER ALL;ALTER TABLE "galleries" ENABLE TRIGGER ALL;ALTER TABLE "gallery_images" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL
ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
(0.6ms) ALTER TABLE "annotations" DISABLE TRIGGER ALL;ALTER TABLE "categories" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "articles" DISABLE TRIGGER ALL;ALTER TABLE "comments" DISABLE TRIGGER ALL;ALTER TABLE "contents" DISABLE TRIGGER ALL;ALTER TABLE "galleries" DISABLE TRIGGER ALL;ALTER TABLE "gallery_images" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
(1.0ms) select table_name from information_schema.views where table_schema = 'site_test'
(23.8ms) TRUNCATE TABLE "annotations", "categories", "articles", "comments", "contents", "galleries", "gallery_images", "users" RESTART IDENTITY CASCADE;
(0.7ms) ALTER TABLE "annotations" ENABLE TRIGGER ALL;ALTER TABLE "categories" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "articles" ENABLE TRIGGER ALL;ALTER TABLE "comments" ENABLE TRIGGER ALL;ALTER TABLE "contents" ENABLE TRIGGER ALL;ALTER TABLE "galleries" ENABLE TRIGGER ALL;ALTER TABLE "gallery_images" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL
(0.1ms) BEGIN
(0.1ms) COMMIT
(0.1ms) BEGIN
(0.1ms) SAVEPOINT active_record_1
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE "users"."username" = 'testuser' LIMIT 1
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'testuser#miscia.net' LIMIT 1
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'testuser#miscia.net' LIMIT 1
SQL (0.7ms) INSERT INTO "users" ("created_at", "email", "encrypted_password", "updated_at", "username") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", "2015-03-08 20:48:58.017027"], ["email", "testuser#miscia.net"], ["encrypted_password", "$2a$04$vHQdcMEuRC2mdrNebemS5e9zMOUaloIhcIBEHlu6z7ms8Rh2NJ0F."], ["updated_at", "2015-03-08 20:48:58.017027"], ["username", "testuser"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
Command :: file -b --mime '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hsarwm.png'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hlhno1.png[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hlhno1.png[0]'
Command :: convert '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hlhno1.png[0]' -auto-orient -resize "100%" '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hlhno120150308-5197-1j86yzw'
Command :: file -b --mime '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-hlhno120150308-5197-1j86yzw'
(0.1ms) SAVEPOINT active_record_1
Command :: file -b --mime '/var/folders/px/vlftvj1j43j7369cy2_sz_j40000gn/T/aacb8db341826e828273a80db5d60d5220150308-5197-h4xfii.png'
Article Exists (0.5ms) SELECT 1 AS one FROM "articles" WHERE "articles"."title" = 'Article Title' LIMIT 1
SQL (6.4ms) INSERT INTO "articles" ("body", "created_at", "description", "header_one", "header_two", "photo_content_type", "photo_file_name", "photo_file_size", "photo_updated_at", "posted_at", "title", "updated_at", "url", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING "id" [["body", "This is the article body."], ["created_at", "2015-03-08 20:48:58.218394"], ["description", "This is a test article!"], ["header_one", "Article Header One"], ["header_two", "Article Header Two"], ["photo_content_type", "image/png"], ["photo_file_name", "test_image.png"], ["photo_file_size", 96884], ["photo_updated_at", "2015-03-08 20:48:58.036313"], ["posted_at", "2015-03-08 20:48:51.398651"], ["title", "Article Title"], ["updated_at", "2015-03-08 20:48:58.218394"], ["url", "http://www.testurl.com"], ["user_id", 1]]
(0.2ms) RELEASE SAVEPOINT active_record_1
Started GET "/" for 127.0.0.1 at 2015-03-08 16:48:58 -0400
Processing by SiteController#index as HTML
Sphinx Query (9.3ms) SELECT * FROM `article_core` WHERE `sphinx_deleted` = 0 ORDER BY `created_at` DESC LIMIT 0, 5
Sphinx Found 0 results
Rendered articles/_pagination.html.erb (0.7ms)
Rendered articles/_list.html.erb (13.0ms)
Category Load (0.3ms) SELECT "categories".* FROM "categories"
Rendered site/homepage/_filters.html.erb (1.3ms)
Rendered site/homepage/_search.html.erb (57.1ms)
Rendered site/homepage/_twitter.html.erb (0.5ms)
Rendered site/homepage/_sidebar.html.erb (61.2ms)
Rendered site/index.html.erb within layouts/application (76.3ms)
Rendered site/_head.html.erb (19.8ms)
Rendered site/homepage/_social_media.html.erb (0.5ms)
Rendered site/homepage/_social_media.html.erb (0.1ms)
Rendered site/homepage/_social_media.html.erb (0.1ms)
Rendered site/homepage/_social_media.html.erb (0.1ms)
Rendered site/homepage/_menu.html.erb (8.0ms)
Content Load (0.4ms) SELECT "contents".* FROM "contents" WHERE "contents"."name_slug" = 'footer_left' ORDER BY "contents"."id" ASC LIMIT 1
Content Load (0.3ms) SELECT "contents".* FROM "contents" WHERE "contents"."name_slug" = 'footer_middle' ORDER BY "contents"."id" ASC LIMIT 1
Rendered site/_footer.html.erb (8.6ms)
Rendered site/_ga.html.erb (0.4ms)
Completed 200 OK in 128ms (Views: 116.4ms | ActiveRecord: 2.2ms)
(0.2ms) ROLLBACK
When you set config.use_transactional_fixtures = false you are telling RSpec to not bother cleaning the database each time it starts a new example. Sometimes I set this to false because I instead use database_cleaner (GitHub) to handle it.
So, based on your logs, I believe RSpec is doing exactly what it is supposed to be doing.
You can read about this setting in the RSpec manual

Resources