Test database wont use fixtures created inside feature tests - ruby-on-rails

I added selenium webdriver to my test setup to start writing some tests based on javascript. I added
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.javascript_driver = :selenium_chrome
Capybara.configure do |config|
config.default_max_wait_time = 5
config.default_driver = :selenium
end
to my rails helper which now look like this
rails_helper.rb
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../config/environment", __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require "rspec/rails"
require "capybara/rspec"
Dir[Rails.root.join("spec", "support", "**", "*.rb")].each { |f| require f }
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.javascript_driver = :selenium_chrome
Capybara.configure do |config|
config.default_max_wait_time = 5
config.default_driver = :selenium
end
# 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")
# Include Factory Bot syntax methods
config.include FactoryBot::Syntax::Methods
# Configure Database Cleaner
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
After these changes, my previous feature tests broke because now they do not use the fixtures created within the tests.
i.e features/article_spec.rb
require "rails_helper"
RSpec.describe "articles", type: :feature do
before :each do
create(:article, published: false)
create(
:article,
name: "Published article",
body_text: "Lorem ipsum",
published_at: Time.now,
published: true
)
end
describe "article feature" do
it "shows only published articles" do
visit("/articles")
expect(page).to have_css(".article-container", count: 1)
end
end
end
The tests are not running headless so I can follow along and see that no articles are present despite the creation within article_spec.rb. I assume the driver executes the tests using another server and/or another database but I'm not sure. In which case don't know how to change that or how to seed that database. You guys have any clue?

You can't use an around hook for database cleaner with RSpec and Capybara because of the order the hooks get run in. If you're going to continue using database cleaner you need to be using closer to the recommended configuration - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example
That being said, since Rails 5.1 assuming you're using a normal configuration (testing with local app, normal DB config, up to date rspec-rails, etc) you don't need to use database cleaner at all, just set config.use_transactional_fixtures = true in your RSpec configuration, remove all references to database cleaner, and the DB connection should be safely shared between your tests and the app under test.

Related

How to disable screenshot in rails 6 rspec app

I'm currently running a Rails 6 App with Rspec and Capybara. When running the system specs, rails automatically generates screenshots. This makes my tests slow. I would like to disable the screenshots. How do i disable screenshots?
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
end
rails_helper.rb
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include FactoryBot::Syntax::Methods# config.filter_gems_from_backtrace("gem name")
end
Capybara.default_driver = :selenium_chrome_headless
Currently, the only way to disable screenshot is by including a before block like this:
require 'rails_helper'
RSpec.describe 'Hello world', type: :system do
before do
driven_by(:selenium_chrome_headless)
end
describe 'index page' do
it 'shows the right content' do
get hello_world_index_path
expect(page).to have('hello world')
end
end
end
I'm looking for a more sustainable way to disable the screenshots by default.
Rails calls the take_failed_screenshot by default in the teardown phase of the tests https://github.com/rails/rails/blob/c5bf2b4736f2ddafbc477af5b9478dd7143e5466/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb#L8
I don't see any configuration to turn that off.
The method is defined here https://github.com/rails/rails/blob/c5bf2b4736f2ddafbc477af5b9478dd7143e5466/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb#L44-L46
Maybe you can try to override that method to not take the screenshot? something like this is you use minitest:
# test/application_system_test_case.rb
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
def take_failed_screenshot
end
end
or if you use RSpec:
# spec/rails_helper.rb
module NoFailedScreenshots
def take_failed_screenshot
end
end
RSpec.configure do |config|
config.include(NoFailedScreenshots)
...
But one comment, if these are the screenshots you refer to, then you have a problem with too many failing specs if that slows things down, you should fix the specs instead.
If this is not what's happening to you then you probably have some custom setup taking screenshots that it's not standard Rails

capybara-webkit js: true rspec tests not able to interact with database

I have used RSpec in conjunction with Capybara and Capybara-webkit on many Rails projects and it usually works smoothly. For some reason I'm having problems configuring the js: true feature specs to work this time around. They are not interacting with the database properly. I use factory_girl and database_cleaner to manage the test db content. I have DatabaseCleaner.strategy = :truncation in database_cleaner.rb for the js: true tests but it still doesn't work. Oddly, when I put in ActiveRecord::Base.establish_connection into databse_cleaner.rb the tests work fine. Why??
Here is rails_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__)
abort("The Rails environment is running in production mode!") if
Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
Capybara::Webkit.configure(&:block_unknown_urls)
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!
# 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
This is the important parts of spec_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
Bundler.require
require 'pry-byebug'
require 'capybara/rspec'
require 'capybara/webkit'
require 'database_cleaner'
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
# use `describe 'Feature', type: :feature, js: true` to use this driver
Capybara.javascript_driver = :webkit
# tests use regular (faster) driver if they don't require js
Capybara.default_driver = :rack_test
Capybara::Webkit.configure do |config|
config.allow_unknown_urls
end
RSpec.configure do |config|
config.after(:suite) do
FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
end
config.include Capybara::DSL
...
This is database_cleaner.rb (located in spec/support):
RSpec.configure do |config|
config.before(:suite) do
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
end
When I change this, the tests can interact with the db properly:
config.before(:each, js: true) do
ActiveRecord::Base.establish_connection
DatabaseCleaner.strategy = :truncation
end
Why? I shouldn't have to explicitly tell it to establish a db connection.
Your question states that you're using :transaction for your js tests, but the code shows :truncation. Truncation is what you should be using for your js tests so I assume the question is a typo.
You should be using the recommended database_cleaner - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example - which detects whether truncation is needed based on the driver being used rather than the 'js: true' metadata and also uses append_after rather than just after, which is very important for test stability.
I also don't see a require 'capybara/rails' anywhere in your rails_helper or spec_helper
When you set js: true, you're essentially just using Capybara which in essence is a Selenium-driven browser request. Any code running outside the test process (like this Selenium browser request) does not see the database fixture.
Preferable to what you're doing though, is to share the data state across the Selenium web server and test the code itself.
Somewhere in Rspec.config (possibly your database_cleaner.rb), you'll want to set
config.use_transactional_fixtures = false
"Everyday Rails Testing with Rspec" has a trick that was sometimes needed for certain test scenarios where you need to share the same DB connection before Rails 5. Although it can cause other issues as pointed out in comments below:
Make a spec/support/shared_db_connection.rb file and add this content:
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

Can't log in with Capybara-webkit, but RSpec/Capybara works fine

I have an RSpec feature spec that tests the login for my app. It passes when I run it in RSpec with Capybara, but when I try to run it flagged with js: true using Capybara-webkit, it fails. This is a problem because my entire app is behind the login, and if I can't get this bit to run I don't know how to do feature specs for the rest of the app.
Here's what I have tried:
Installing all the Capybara-webkit dependencies listed here. I'm running my app in a Docker container built on the ruby:2.3 image, which is built on Jessie.
Setting up DatabaseCleaner per this blog post. My database_cleaner.rb file is below.
Using the Headless gem (headless.rb below)
Running RSpec like so: xvfb-run -a bin/rspec spec/features/log_in_spec.rb (seems no different than running it normally with Headless)
How do I get my login specs to work under Capybara-webkit? Some of my specs will need to be flagged for JS and some won't, but they'll all need the user to be logged in. Thank you.
log_in_spec.rb
require 'rails_helper'
RSpec.feature "Log in", type: :feature do
scenario "as admin" do
user = create(:admin)
# Tried this instead of with Capybara, works with Capybara but not capybara-webkit
# login_as user, scope: :user, run_callbacks: false
visit root_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
find('.btn-primary').click
expect(page).to have_content('Admin')
end
end
spec_helper.rb
require 'capybara/rspec'
require 'paperclip/matchers'
RSpec.configure do |config|
Capybara.javascript_driver = :webkit
Capybara.app_host = 'https://192.168.99.101'
config.include Paperclip::Shoulda::Matchers
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
mocks.verify_doubled_constant_names = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.disable_monkey_patching!
if config.files_to_run.one?
config.default_formatter = 'doc'
end
end
rails_helper.rb
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/rails'
require 'devise'
require 'support/controller_macros'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
# 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|
config.use_transactional_fixtures = false
config.filter_rails_from_backtrace!
config.include Warden::Test::Helpers
config.before :suite do
Warden.test_mode!
end
config.after :each do
Warden.test_reset!
end
end
# Added headless gem and this code thanks to this post: http://stackoverflow.com/a/28706535/3043668
if ENV['HEADLESS']
require 'headless'
headless = Headless.new
headless.start
at_exit { headless.stop }
end
spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
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
end
spec/support/headless.rb
RSpec.configure do |config|
config.around type: :feature do |example|
Headless.ly do
example.run
end
end
end
spec/support/capybara.rb
Capybara::Webkit.configure do |config|
config.debug = true
config.allow_unknown_urls
config.timeout = 5
config.ignore_ssl_errors
config.skip_image_loading
end
Here is a gist of the debug output from Capybara-webkit when I run the test. It looks like it's trying the same thing over and over.
UPDATE
I removed my Capybara.app_host setting, and the non-JS test still passes, but when I run it under capybara-webkit, I see this in the debig output:
Received 0 from "https://127.0.0.1:37193/login"
Page finished with false
Load finished
Page load from command finished
Wrote response false "{"class":"InvalidResponseError","message":"Unable to load URL: http://127.0.0.1:37193/login because of error loading https://127.0.0.1:37193/login: Unknown error"}"
Received "Reset()"
Started "Reset()"
undefined|1|SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
It's trying to visit("/login") and it is being redirected to the https version, and this is making it fail. How do I make it succeed?
The first reason is that the record after save procedure c=keep not the password in plain view, but seems that it is good in this case:
user = create(:admin)
# ...
user = User.first # wrong way
#...
fill_in 'Password', with: 'password'
The second reason in fail to login is that factory girl and capybara uses separate connections, so and data created in one session isn't available in another. To fix it use single connection patch (put it to spec/support) as described here.
This was a hard one. But the issue was that I had set force_ssl = true in my application.rb, stupidly, instead of putting it in production.rb and development.rb like a normal person.
I also had set Capybara-webkit's app_host, which, as it turned out, I did not need to do. After removing that, and running capybara-webkit with debug on, I saw that it was trying to redirect from http://localhost:45362/login (or whatever port) to https://localhost:45362/login (note the https!) and that this was causing a DOM 18 security error or whatever, and this was making it choke. I turned off force_ssl and now it works like a champ. Hope this helps you not tear your hair out.

Rails test environment partials not appearing in Redis cache

I've got a Rails 3.2.21 app on Ruby 2.1.5 that uses Postgres, Redis as the cache store (config.cache_store = :redis_store), background workers (mostly for view cache warming) with sidekiq. Russian doll caching used with the cache_digests gem so you end up with cache keys like views/my_lovely_partial/5506949e3754753ad58190924d5b029f. Running tests with RSpec, Factory Girl and Capybara.
For the test environment I have set up a parallel Redis server, different port to production and dev, and have "config.action_controller.perform_caching = true" in test rb. It's the same redis setup in dev and test apart from the port being different.
Testing through either controller spec or feature spec I see the presence of objects cached in Redis, either through the tests themselves or directly viewing the keys in redis-cli.
When I try to test for view partials in Redis I find they are not being cached e.g. In dev environment on the same machine the view partials appear in the redis cache whereas in test they don't - only cached objects appear; this is confirmed by viewing through the redis-cli for both dev and test redis instances. 'render_template' and 'have_content' together with viewing the tested page (Using the 'capybara-screenshot' gem) confirm the content is being served successfully but the partials are not being cached in test.
Gems used specifically in test : rspec-rails, factory_girl_rails, faker, capybara, capybara-screenshot, capybara-user_agent, pry, guard-rspec, launchy, database_cleaner, shoulda-matchers, redis, turn.
I've checked in the spec.rb's that perform_caching is still true; tried temporarily removing pry, guard-rspec, launchy, shoulda-matchers gems but no difference. Tried removing database_cleaner gem, disabling all test cache clearing and ran tests again to find only object caching present in redis, no partials.
test.rb
SmashingSuperApp::Application.configure do
config.cache_classes = true
config.whiny_nils = true
config.consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
config.action_controller.allow_forgery_protection = false
config.action_mailer.delivery_method = :test
config.active_support.deprecation = :stderr
config.action_controller.perform_caching = true
config.cache_store = :redis_store, "redis://localhost:6378/0/cache", { expires_in: 1176.hours }
ENV["REDIS_URL"] ||= "redis://localhost:6378/0"
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.action_dispatch.best_standards_support = :builtin
config.active_record.mass_assignment_sanitizer = :strict
config.active_record.auto_explain_threshold_in_seconds = 0.5
config.log_tags = [:uuid, :remote_ip]
config.before_initialize do |app|
app.config.paths.add 'app/models', :eager_load => true
end
config.to_prepare do
Dir["#{Rails.root}/app/models/*"].each do |model_name|
require_dependency model_name unless model_name == "." || model_name == ".."
end
end
Rails.application.routes.default_url_options[:host]= 'smashingsuperapp.co.uk:3000'
end
rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara-screenshot/rspec'
require 'shoulda/matchers'
require 'faker'
require 'redis'
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
config.infer_spec_type_from_file_location!
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
Rails.cache.clear # Clear redis cache
end
config.before(:each) do |example|
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
Rails.cache.clear # Clear redis cache
end
config.include FactoryGirl::Syntax::Methods
config.after do |example|
if example.metadata[:type] == :feature and example.exception.present?
save_and_open_page
end
end
end
def set_host (host)
default_url_options[:host] = host
Capybara.app_host = "http://" + host
end
spec_helper.rb
require 'capybara/user_agent'
Capybara::UserAgent.add_user_agents(mechanize: 'Mechanize')
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.include Capybara::UserAgent::DSL
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
=begin
config.filter_run :focus
config.run_all_when_everything_filtered = true
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
end
def get_path(path)
parsed_params = Rails.application.routes.recognize_path path
controller = parsed_params.delete(:controller)
action = parsed_params.delete(:action)
get(action, parsed_params)
end
Feature specs use 'visit' and controller specs use 'get' to the correct URL's and render the correct content.
Any pointers as to why partials wouldn't be being cached in this situation very much appreciated. Thanks in advance.
Thought I'd try adding the 'selenium-webdriver' gem and after lots of irony debugging/trial/error in the test environment I then found cached partials were appearing in Redis.
In case it helps others as I found a information a bit patchy;
Further added
gem 'selenium-webdriver'
into test group of Gem file.
Modified /spec/rails_helper.rb below. Note particularly Capybara.server_port = 10000, Capybara.always_include_port = true, Capybara.javascript_driver = :selenium - default port was not being picked up in js marked tests so had to lock it down there.
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara-screenshot/rspec'
require "rack_session_access/capybara"
require 'shoulda/matchers'
require 'faker'
require 'redis'
require 'support/wait_for_ajax'
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
config.infer_spec_type_from_file_location!
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
Rails.cache.clear # Clear redis cache
# To prevent FactoryGirl creating persons with an id that are reserved for 'special' persons
ActiveRecord::Base.connection.execute("ALTER SEQUENCE persons_id_seq START with 4000 RESTART;")
end
config.before(:each) do |example|
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
Rails.cache.clear # Clear redis cache
end
config.include FactoryGirl::Syntax::Methods
config.after do |example|
if example.metadata[:type] == :feature and example.exception.present?
save_and_open_page
end
end
end
Capybara.server_port = 10000
Capybara.always_include_port = true
Capybara.javascript_driver = :selenium
def set_host (host)
# host! host
default_url_options[:host] = host
Capybara.app_host = "http://" + host
end
The "require 'support/wait_for_ajax'" in the above, described here, is something I came across whilst trying to get selenium up and running that looks handy for ajax testing. Although ajax was not playing a role in the cached partials I was testing for this, there are others with ajax calls where this would be handy.
For the feature tests using selenium, have those tests in their own describe block e.g.
describe "special person accesses event with JS tests" do
before(:each) do
Capybara.current_driver = :selenium
end
after(:all) do
Capybara.use_default_driver
end
scenario 'can view persons partial with cache insertion', js: true do
visit some_cached_page_path(id:some_page_id)
...
And then any following tests that use rack_test (default no full browser and no js tests) put them in a separate describe block but without 'js: true' and those before and after blocks. Initially I thought I would only need to mark selenium driven test blocks with "js: true" but found issues then with the basic rack_test based blocks until I took the above describe block approach.

Tests using rspec, capybara and poltergeist return empty html and empty screenshots

So I've been struggling with this for quite some time now and I can't seem to figure our what's going wrong, and couldn't find much on what could possibly cause this issue.
I'm relatively new to Ruby and Rails, as well as test/behavior driven development and am trying to write some acceptance (browser) tests using PhantomJS through Poltergeist, using Rspec and Capybara. I believe some people also call this integration tests (they may be from some perspective), but that's a whole other discussion.
I have a really simple feature that I can't get to do what I want:
require 'feature_helper'
feature 'Logging in', :js => true do
scenario 'with incorrect credentials' do
visit '/login'
puts page.html
save_and_open_page
page.driver.render('_screenshot.png', :full => true)
page.html.should have_selector("title", :text => "hi")
end
end
So. Simple, right. It should just go to /login and throw the HTML content at me, as well I want to see the page using save_and_open_page, and I want it to take a screenshot. I added a simple should have_selector in order to have the test fail in an attempt to get more feedback.
The relative contents of my feature_helper.rb:
require 'spec_helper'
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
include Capybara::DSL
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
:debug => true,
:inspector => true
})
end
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
FakeWeb.allow_net_connect = %r[^https?://(127.0.0.1|localhost)] # allow phantomjs/poltergeist requests
DatabaseCleaner.strategy = :truncation
RSpec.configure do |config|
config.before :each do
# Set the hostname to something with test
#host = "test.iome:3003"
host! #host
Capybara.default_host = Capybara.app_host = "http://#{#host}/"
Capybara.server_port = 3003
Capybara.reset_sessions!
# Start the database cleaner
config.use_transactional_fixtures = false
DatabaseCleaner.start
end
config.after :each do
DatabaseCleaner.clean
end
end
And also 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 'pry'
require 'fakeweb'
FakeWeb.allow_net_connect = false
It's all fairly simple.
Now, in my console I see the following:
{"name"=>"visit", "args"=>["http://test.iome:3003//login"]}
{"response"=>{"status"=>"fail"}}
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
<html><head></head><body></body></html>
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
{"name"=>"render", "args"=>["_screenshot.png", true]}
{"response"=>true}
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
Also, the screenshot is just a white and empty page. When I tail my log/test.log file, I don't see that a request is being performed. I've tried changing the method visit to get, and that'll make the request, but won't change any of the results.
I've completely run out of ideas of what this could be and it's rather frustrating :(
Final information then about versions:
rspec 2.10.0
capybara 1.1.4
poltergeist 1.0.3
ruby 1.8.7
rails 3.2.13
Unfortunately we're still at ruby 1.8.7, but are working on bumping that version up. Still, I think this shouldn't influence the tests.
Any help would be greatly appreciated!
So eventually I got help from a colleague, and we managed to fix it. We used the lvh.me domain for this, as any request to that domain will resolve in localhost, allowing you to use subdomains without a problem. You could probably also use hostname.127.0.0.1.xip.io for this.
Our spec_helper.rb now looks like this:
# Use capybara in combination with poltergeist for integration tests
require 'capybara/rails'
require 'capybara/rspec'
require 'capybara/poltergeist'
require 'rack_session_access/capybara'
Capybara.default_driver = :poltergeist
Capybara.always_include_port = true
Capybara.app_host = 'http://application-test.lvh.me' # Any lvh.me domain resolves to localhost
Capybara.default_wait_time = 8 # How long capybara should look for html elements
require 'vcr'
VCR.configure do |config|
config.cassette_library_dir = 'spec/vcr_cassettes'
config.hook_into :fakeweb
config.ignore_localhost = true
config.configure_rspec_metadata!
config.ignore_hosts 'codeclimate.com'
end
require 'fakeweb'
FakeWeb.allow_net_connect = false
Because we hooked in VCR to record any requests going out during the first run of the integration tests, all your integration tests, or features, should contain this code:
before(:all) do
FakeWeb.allow_net_connect = true
end
after(:all) do
FakeWeb.allow_net_connect = false
end
If you want to change the subdomain during your specs, you can use the following:
before(:each) do
#original_host = Capybara.app_host
Capybara.app_host = 'http://does-not-exist.lvh.me'
visit '/login'
end
after(:each) do
Capybara.app_host = #original_host
end
Making screenshots can now be done using page.save_screenshot during specs. Hope this helps.

Resources