Search code examples
rubyphantomjscapybarapoltergeistwebmock

How can I fake a response to Capybara/poltergeist using webmock?


I'm testing a webscraper and I'd like to use Webmock to deliver fake websites for faster testing. When I mock a website, Ruby's native HTTP library works fine, but Capybara doesn't seem capable of receiving the mocked response. I know that webmock is stubbing low level HTTP requests, and I assume it matters which one capybara uses and which one webmock is configured to use. However, I need to know how Capybara makes HTTP requests and how I can configure webmock to stub that particular method set.

require 'capybara/poltergeist'
require 'webmock'
require 'pry'
include WebMock::API
WebMock.disable_net_connect!(allow_localhost:true)


Capybara.register_driver :poltergeist do |app|
    Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
# Configure Capybara to use Poltergeist as the driver
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist

U = /google.com/

b = Capybara.current_session

stub_request(:any, U).
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
to_return(status:200, body:"abc", headers:{})

puts Net::HTTP.get(U,'/') #=> This returns "abc"

b.visit U
puts b.html  #=> Throws error

The error I'm getting is as follows: command': Request failed to reach server, check DNS and/or server status (Capybara::Poltergeist::StatusFailError)

I've tried using FakeWeb as well, but that simply was not capable of registering URIs. I'm open to using other APIs besides webmock if you think this is the wrong tool for the job.

Thanks in advance :)


Solution

  • Tom Walpole is correct. You can use WebMock to mock things your server is connecting to, but the browser makes its own connections and is unaffected by the changes you make to the server.

    If you want to fake responses that the browser requests from other servers try something like Puffing Billy. Take a look at the Caching capability which can be setup to re-play results (much like VCR).

    If you're working with something VERY simple you could try just loading the data you need with Capybara.string. But that's probably too limited for what you want.