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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With