Rails rspec No response yet. Request a page first - ruby-on-rails

I'm running a rspec, the script is like this:
require 'spec_helper'
describe Stb do
let(:app) { Stb.new }
before do
#stb = FactoryGirl.create(:stb)
end
subject { #stb }
describe ".login" do
it "ok" do
RestClient.get "http://www.example.com"
last_response.should be_ok
end
end
end
But it turns out:
1) Stb.login ok
Failure/Error: last_response.should ok
Rack::Test::Error:
No response yet. Request a page first.
When I run RestClient.get "http://www.example.com" in the irb, it can return some valid things.
Could someone help me what's wrong with it, or is there something special about last_response
My *spec_helper.rb* is:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec'
require 'rspec/rails'
require 'rspec/autorun'
require 'rack/test'
require 'em-rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
#config.before(:each, type: :controller) { #routes = Api::Engine.routes }
# config.before(:each, type: :routing) { #routes = Api::V4::Server.routes }
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
#config.before(:each, type: :controller) { #routes = Api::Engine.routes }
config.before(:each, type: :routing) { #routes = Api::Engine.routes }
# make rspec stop operation immediately after failed
config.fail_fast = true
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
config.include Rack::Test::Methods
end

Related

Why rspec doesn't run single spec?

When I trying to run single test, like
bundle exec rspec spec/some_path/some_spec.rb
It runs all specs anyway, like it would be if I run bundle exec rspec spec/
Even when it print out failed specs and I only copy failed examples and put it again, the Rspec will run all existed specs. I haven't found any information about such behaviour in rspec documentation. Thank you very much if you know, what is wrong with my code! (or configuration, I suppose)
spec_helper.rb:
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.filter_run_when_matching :focus
config.disable_monkey_patching!
if config.files_to_run.one?
config.default_formatter = 'doc'
end
config.profile_examples = 10
config.order = :random
Kernel.srand config.seed
end
require 'webmock/rspec'
def body_as_json
json_str_to_hash response.body
end
def json_str_to_hash(str)
JSON.parse(str).with_indifferent_access
end
.rspec:
--require rails_helper
--format progress
--color
--order random
--profile 10
rails_helper.rb
# frozen_string_literal: true
unless ENV['COVERAGE'].to_s == ''
require 'simplecov'
SimpleCov.start 'rails'
end
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../config/environment', __dir__)
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
require 'capybara-screenshot/rspec'
require 'timecop'
require 'sidekiq/testing'
require 'database_cleaner'
require 'webmock/rspec'
require 'audited-rspec'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Base.connection.reconnect!
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.infer_base_class_for_anonymous_controllers = false
config.include Capybara::DSL
config.include FactoryBot::Syntax::Methods
config.include CapybaraHelpers
config.include ProcessingHelpers
config.include RequestsHelper, type: :request
config.include ApiHelper
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with :truncation, except: %w[spatial_ref_sys schema_migrations]
Faker::Config.locale = :en
# Rails.application.load_seed
Sidekiq::Testing.fake!
end
config.around do |example|
DatabaseCleaner.cleaning do
example.run
end
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# 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!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(
app,
phantomjs_logger: Rails.root.join('log', 'poltergeist.log'),
inspector: true
)
end
Capybara.javascript_driver = :poltergeist
Capybara.server_port = 3001
Capybara.app_host = 'http://localhost:3001'

Rails 5.1: Rspec can't see Capybara features

I have some feature specs in my project that look roughly like this:
# specs/features/canvas_integration.rb
require 'spec_helper'
feature 'Routes to default page' do
let!(:mode) { create(:mode) }
scenario 'as anyone' do
visit root_path
expect(page).to have_content('Your home')
end
end
But running the specs results in nothing:
rspec spec/features
No examples found.
My spec_helper.rb looks like this:
# frozen_string_literal: true
require 'simplecov'
SimpleCov.start 'rails'
require File.expand_path('../../config/environment', __FILE__)
require 'codeclimate-test-reporter'
require 'rspec/rails'
require 'webmock/rspec'
require 'devise'
require 'codeship'
require 'capybara/rspec'
require 'capybara/rails'
WebMock.disable_net_connect!(allow_localhost: true)
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include Devise::Test::ControllerHelpers, type: :view
config.include FactoryGirl::Syntax::Methods
config.extend ControllerMacros, type: :controller
config.include Macros
config.color = true
config.fixture_path = "#{::Rails.root}/spec/factories/fixtures"
config.infer_spec_type_from_file_location!
config.infer_base_class_for_anonymous_controllers = false
config.order = 'random'
config.warnings = false
config.default_formatter = 'doc' if config.files_to_run.one?
config.profile_examples = 10
config.use_transactional_examples = false
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
# config.before(:each, type: :system) { driven_by :rack_test }
config.mock_with :rspec do |mocks|
mocks.verify_doubled_constant_names = true
end
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
Why can't Rspec find my features?
Your files need to end in _spec.rb in order for RSpec to load them when specifying a directory. So rename to specs/features/canvas_integration_spec.rb
Also note that in Rails 5.1 database cleaner is probably not necessary (if you're using one of the usual databases) - so you should be able to remove/comment out that and re-enable transactional testing. Additionally use_transactional_examples is an alias of use_transactional_fixtures so specifying both doesn't make sense.
I think your test spec filename should be specs/features/canvas_integration_spec.rb instead of specs/features/canvas_integration.rb
Why?
The files read by the rspec-rails gem are those that end in _spec.rb

Capybara holds only one authorized request, all others return 401

My problem is that capybara holds only one authorized request (doesn't matter was it authorization through the login form or through the helper login_as method)
Other (second, third) requests are unauthorized!
It doesn't mater what driver I use. Where the problem can be?
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/poltergeist'
# NOTE: For Chrome support
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
# Capybara.register_driver(:poltergeist) { |app| Capybara::Poltergeist::Driver.new(app, js_errors: false) }
# Capybara.javascript_driver = :poltergeist
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
# Checks for pending migration and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include WaitForAjax
config.include FeatureHelpers
config.include Devise::TestHelpers, type: :controller
config.include Warden::Test::Helpers
config.extend ControllerHelpers, type: :controller
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# 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!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.before :suite do
Warden.test_mode!
end
end
Most probably between the first request and the second, rspec cleans up the DB.
For this second request the user form the first request no more exists. You should create another user and login/authorize it.
Ex:
For each it block you'll have to do a login_as(a_new_just_created_user). Yes, you can put this into a before block to be executed for the entire test suite.
describe '' do
before do
login_as(a_new_just_created_user)
end
context '' do
it '' { get 'api/url' } # first user logged in
it '' { get 'api/url' } # second user logged in
end
context '' do
it '' { get 'api/url' } # third user logged in
end
end

Capybara.javascript_driver = :poltergeist not showing browser during testing

I am trying to test using poltergeist, but the browser is not shown when I run my tests.
This is my spec_helper.rb:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'rspec/page-regression'
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist do |app|
#Capybara::Poltergeist::Driver.new(app, {debug: true, :timeout => 90})
Capybara::Poltergeist::Driver.new(app, {debug: false, :default_wait_time => 30, :timeout => 90})
end
Capybara.javascript_driver = :poltergeist
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
config.include Capybara::DSL
end
# from http://stackoverflow.com/questions/8524839/sending-rails-errors-to-rspec-output
# to output all errors to rspec output
ActionController::Base.class_eval do
def rescue_action(exception)
raise exception
end
end
I don't know if I am correctly setting Capybara.javascript_driver.
You won't see the browser. Poltergeist is for headless testing, this means it programmatically renders everything underneath, and programmatically processes interactions with the page.

Having Issues with cache_classes / Spork after changing to Capybara-Webkit from Selenium

For a while I was using Selenium / Spork / Rspec, with cache_classes on false, and everything seemed to be working.
In switching over to webkit, I've started to get errors related to cache_classes (e.g. Expected User, got User), so I've been fighting with it to try to get cache_classes set to true.
However no matter what I do, I end up with the following error:
Capybara::Driver::Webkit::WebkitInvalidResponseError:
Unable to load URL: http://127.0.0.1:56398/login
I have tried all kinds of things... including:
ActiveSupport::Dependencies.clear in both the prefork and each _run blocks
The code here: http://my.rails-royce.org/2012/01/14/reloading-models-in-rails-3-1-when-usign-spork-and-cache_classes-true/
Starting to wonder if I should just live with cache_classes = false, and figure out how to avoid the Factory girl errors. Any help would be appreciated. My spork file is as follows:
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'
require 'database_cleaner'
require 'factory_girl'
require 'authlogic/test_case'
require 'email_spec'
include Authlogic::TestCase
require File.expand_path("../../config/environment", __FILE__)
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
ApplicationController.skip_before_filter :activate_authlogic
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
config.include Capybara::DSL
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation, {:except => %w[ages coefficients weights1 weights2 weights3 weights4 weights5 weights6 weights7 weights8 etfs]}
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.start
Capybara.current_driver = :webkit if example.metadata[:js]
#Capybara.current_driver = :selenium if example.metadata[:js]
activate_authlogic
ActiveRecord::Base.instantiate_observers
end
config.after(:each) do
DatabaseCleaner.clean
Capybara.use_default_driver if example.metadata[:js]
end
Capybara.default_selector = :css
end
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
## SUPPORT METHODS ##
## (erased for clarity) ##
## ##
ActiveSupport::Dependencies.clear
end
Spork.each_run do
#FactoryGirl.reload
# Required to fix a recurring error when testing Active_Admin stuff
# See here: http://railsgotchas.wordpress.com/2012/01/31/activeadmin-spork-and-the-infamous-undefined-local-variable-or-method-view_factory/
# Delete at some point if active admin or whoever fixes this
ActionView::Template.register_template_handler :arb, lambda { |template|
"self.class.send :include, Arbre::Builder; #_helpers = self; self.extend ActiveAdmin::ViewHelpers; #__current_dom_element__ = Arbre::Context.new(assigns, self); begin; #{template.source}; end; current_dom_context"
}
#ActiveSupport::Dependencies.clear
end
UPDATE : Adding an example spec just in case it helps....
describe "Items" do
before(:each) do
#user = Factory.create(:user)
activate_authlogic
b = # something not important
end
describe "usage paths" do
it "the form directly from the basic_simulation show page should have correctly functioning javascript validation", :js => true do
request_sign_in(#user) # This is a helper method which goes through the login form
visit '/basic_simulation'
fill_in "amount", :with => "-5000"
click_button "Calculate"
page.should have_selector("label.jquery-validator.amount-error", :text => "Please enter a value greater than or")
fill_in "amount", :with => "5000"
click_button "Calculate"
page.should have_selector("input#amount", :value => "5000")
end
end
You are having issues due to threading problems with Capybara-webkit and the test suite.
Jose Valim explains it much more clearly in a recent blog post.
If you follow his recommendations then you should be able to turn on transactional fixtures, remove database cleaner altogether and no longer have issues with your data during tests while using capybara-webkit. You'll get a nice boost in testing performance as well.
The trick though is to make sure that Jose's suggestion is in the Spork.each_run block or it will not work. For clarity here are the relevant parts of my spec_helper.rb.
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
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
Capybara.default_driver = :rack_test
Capybara.default_selector = :css
Capybara.javascript_driver = :webkit
end
end
Spork.each_run do
if Spork.using_spork?
ActiveRecord::Base.instantiate_observers
end
require 'factory_girl_rails'
# Forces all threads to share the same connection, works on Capybara because it starts the web server in a thread.
class ActiveRecord::Base
mattr_accessor :shared_connection
##shared_connection = nil
def self.connection
##shared_connection || retrieve_connection
end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
end
A few other small suggestions:
If you are using the latest version of factory_girl_rails then you
should be using require factory_girl_rails in the Spork.each_run
block and require factory_girl should be removed from the prefork
The latest factory_girl_rails also no longer requires ActiveSupport::Dependencies.clear at all, although some people are still having issues without it so you should test removing it.
I'm still not sure about the need for ActiveRecord::Base.instantiate_observers but in any case you would only need it if you are using observers and I understand that it should be in the each_run block.
Try all that and see if it works for you.

Resources