Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 958
Mark Avatar asked Nov 12 '22 01:11

Mark


1 Answers

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.

like image 77
Mark Avatar answered Nov 15 '22 05:11

Mark