Search code examples
ruby-on-railsrspeccapybarapoltergeist

Puffing Billy with Poltergeist error: "rack-test requires a rack application, but none was given"


Using the Puffing Billy instructions for rspec with capybara I created a simple test to stub a request using the :poltergeist_billy driver resulting in error:

ArgumentError:
        rack-test requires a rack application, but none was given
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/rack_test/driver.rb:16:in `initialize'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara.rb:372:in `new'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara.rb:372:in `block in <top (required)>'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/session.rb:79:in `driver'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/session.rb:227:in `visit'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
      # ./spec/scraypa_spec.rb:52:in `block (4 levels) in <top (required)>'

With this code:

spec/spec_helper.rb

require "bundler/setup"
require "scraypa"
require 'billy/capybara/rspec'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = ".rspec_status"

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.include Capybara::DSL
end

spec/my_spec.rb:

it "should utilise capybara to download web content" do
  #Capybara.current_driver = :poltergeist_billy
  Capybara.javascript_driver = :poltergeist_billy
  proxy.stub('http://www.google.com/')
        .and_return(:text => "test response")
  visit "http://www.google.com/"
  expect(page.text).to eq('test response')
end

While digging around, I found an example that used Capybara.current_driver = :poltergeist_billy (which I have commented out in my test above), if I uncomment that code, I then get this error:

Cliver::Dependency::NotFound:
        Could not find an executable ["phantomjs"] on your path.
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/cliver-0.3.2/lib/cliver/dependency.rb:143:in `raise_not_found!'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/cliver-0.3.2/lib/cliver/dependency.rb:116:in `detect!'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/cliver-0.3.2/lib/cliver.rb:24:in `detect!'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/client.rb:36:in `initialize'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/client.rb:14:in `new'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/client.rb:14:in `start'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/driver.rb:42:in `client'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/driver.rb:25:in `browser'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/poltergeist-1.9.0/lib/capybara/poltergeist/driver.rb:95:in `visit'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/session.rb:227:in `visit'
      # /home/resrev/.rvm/gems/ruby-2.3.1/gems/capybara-2.4.4/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
      # ./spec/scraypa_spec.rb:52:in `block (4 levels) in <top (required)>'

Im not sure where to go from here or what im doing wrong, any ideas? thanks.


Solution

  • The errors are many here, so let's just start at the beginning

    1. You don't have require capybara/rails in your spec_helper.rb or rails_helper.rb - https://github.com/teamcapybara/capybara#setup - this means Capybara.app isn't getting set and is why you're getting the "rack-test requires a rack application" - of course you don't really want to be using the rack-test driver for your current test which #3 will deal with.

    2. Capybara already includes Capybara::DSL into feature specs, so use feature specs, and remove the include Capybara::DSL from your RSpec config shown above. This requires either putting your spec file into spec/features/my_spec.rb and enabling the RSpec config to determine test type by directory, or manually specifying that the test is a feature spec

      feature "should utilise capybara to download web content" do
        ...
      end
      

      or

      it "should utilise capybara to download web content", type: :feature do
        ...
      end
      
    3. Your test is actually using the rack_test driver and not the poltergeist-billy driver. This is because you're setting Capybara.javascript_driver inside the test. It needs to be set before the test, and then the test tagged with metadata to tell it to use the specific driver. Two options here, either set Capybara.javascript_driver = :poltergeist_billy in your spec_helper.rb and then specify :js metadata

       feature "should utilise capybara to download web content", :js do
         ...
       end
      

      or specify :driver metadata to identify which driver to use for the given test

      feature "should utilise capybara to download web content", driver: :poltergeist_billy do 
        ... 
      end
      
    4. When specifying to use poltergeist with billy you need to install PhantomJS (required by Poltergeist) in your path. If using OSX with homebrew you can do brew install phantomjs - on other systems you'll need to download the latest version of PhantomJS and put it somewhere in your PATH

    5. expect(page.text).to eq('test response'). This is a terrible way to do text matching when using Capybara. eq has no waiting/retrying behavior and since actions have no guarantees on being completed when Capybaras methods return will lead to flaky tests. Instead, use the matchers Capybara provides. If you are okay with a substring match do

      expect(page).to have_text('test_response')

      if it needs to be an exact match

      expect(page).to have_text('test_response', exact: true)