Coder Social home page Coder Social logo

capybara_discoball's Introduction

capybara_discoball

Build Status Code Climate

Spin up a rack app just for Capybara.

This is useful for when ShamRack won't cut it: when your JavaScript hits an external service, or you need to load an image or iframe from elsewhere, or in general something outside of your Ruby code needs to talk with an API.

Synopsis

# Use Sinatra, for example
require 'sinatra/base'
require 'capybara_discoball'

# Define a quick Rack app
class FakeMusicDB < Sinatra::Base
  cattr_reader :albums

  get '/musicians/:musician/albums' do |musician|
    <<-XML
    <albums for="#{musician}">
      #{@albums.map { |album| "<album>#{album}</album>" }.join}
    </albums>
    XML
  end
end

# Spin up the Rack app, then update the imaginary library we're
# using to point to the new URL.
Capybara::Discoball.spin(FakeMusicDB) do |server|
  MusicDB.endpoint_url = server.url
end

More details

You can instantiate a Capybara::Discoball::Runner, passing in a factory which will create a Rack app:

FakeMusicDBRunner = Capybara::Discoball::Runner.new(FakeMusicDB) do
  # tests to perform after server boot
end

This gives you back a runner, which you can boot from your features, specs, tests, console, whatever:

FakeMusicDBRunner.boot

These two steps can be merged with the spin class method:

Capybara::Discoball.spin(FakeMusicDB) do
  # tests to perform while server is spinning
end

It is always the case that you need to know the URL for the external API. We provide a way to access that URL; in fact, we offer the whole Capybara::Server for you to play with. In this example, we are using some MusicDB library in the code that knows to hit the .endpoint_url:

FakeMusicDBRunner = Capybara::Discoball::Runner.new(FakeMusicDB) do |server|
  MusicDB.endpoint_url = server.url
end

If no block is provided, the URL is also returned by #spin:

MusicDB.endpoint_url = Capybara::Discoball.spin(FakeMusicDB)

Integrating into your app

All of this means that you must be able to set the endpoint URL. There are two tricky cases:

When the third-party library does not have hooks to set the endpoint URL.

Open the class and add the hooks yourself. This requires understanding the source of the library. Here's an example where the library uses @@endpoint_url everywhere to refer to the endpoint URL:

class MusicDB
  def self.endpoint_url=(endpoint_url)
    @@endpoint_url = endpoint_url
  end
end

When your JavaScript needs to talk to the endpoint URL.

For this you must thread the URL through your app so that the JavaScript can find it:

<% content_for :javascript do %>
  <% javascript_tag do %>
    albumShower = new AlbumShower(<%= MusicDB.endpoint_url.to_json %>);
    albumShower.show();
  <% end %>
<% end %>

class @AlbumShower
  constructor: (@endpointUrl) ->
  show: ->
    $.get(@endpointUrl, (data) -> $('#albums').html(data))

Contributing

See the CONTRIBUTING document. Thank you, contributors!

License

capybara_discoball is Copyright (c) 2012-2018 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.

About

thoughtbot

capybara_discoball is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software! See our other projects or hire us to help build your product.

capybara_discoball's People

Contributors

aliismayilov avatar gabebw avatar georgebrock avatar jsom avatar mike-burns avatar odlp avatar pjg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

capybara_discoball's Issues

.spin should produce the URL

The most common case is to spin up a server and do something with its URL. Change .spin such that if there is no block it just produces the server.url('/') .

Capybara 3.0 support

Capybara 3.0 has been released so we should try and support it!

Currently the gemspec allows >= 2.7.0, < 3.0.0:

s.add_dependency 'capybara', '~> 2.7'

Notably the default server in Capybara is now Puma, but Webrick should still be available:
https://github.com/teamcapybara/capybara/blob/master/UPGRADING.md#server


Steps:

  • Get the build passing
    • It's failing locally for me, I think because aruba 1.0 has been released and there's no Gemfile.lock in this project
  • Use appraisal to test Capybara Discoball with Capybara 2.x & 3.0 - #19
  • Publish a new version on RubyGems

Using capybara_discoball to mount a Rails engine?

Hi,

Just wondering if there was any experience with using capybara_discoball to mount a Rails engine (rather than another Rack application eg Sinatra).

I am trying mount a Rails::Engine within Capybara_Discoball in a Rails application and running into dead ends so far.

Would be nice if there is an API to shutdown the running rack app.

I am using capybara_discoball in my system specs. I had to keep all of my test scenarios in a single block that will be passed to the spin method. I want to separate all these tests across multiple files. But I am getting an Address already in use error. Is there any way to stop the running rack app? Especially this is useful in parallel tests.

Why WEBrick?

Why is WEBrick necessary in CapybaraDiscoball?

We recently tried a simplified version for FakeStripe:

class FakeServer < Sinatra::Base
  def self.boot
    instance = new
    Capybara::Server.new(instance).tap { |server| server.boot }
  end
end

class FakeStripe < FakeServer
  # ...
end

server = FakeStripe.boot
Stripe.api_base = server.url('')
STRIPE_JS_URL = server.url('/stripe.js')

# config/environments/{development,staging,production}.rb
STRIPE_JS_URL = 'https://js.stripe.com/v1/'
<%= javascript_include_tag STRIPE_JS_URL %>

It seems to work well but don't want to have to fix the same issue that WEBrick already solved here.

Documenting how to view errors

Thanks for the library! I'm working on implementing a fake API in my tests, but one thing that I'm finding to be a little frustrating is figuring out the details of errors. Most of them I can get vague a sense of what is going wrong, though then I get Internal Server Error no implicit conversion of Array into String with no stack trace or logs, and I'm kind of stuck. Any recommendations on how to get better error information?

URI::InvalidURIError: bad URI(is not URI?)

I'm following this article, but I can't make capybara discoball work. I get this error:

Failure/Error: HTTParty.get(self.class.base_url + "/API/V1/programms", format: :json)

URI::InvalidURIError:
  bad URI(is not URI?): 127.0.0.1:49552/API/V1/programs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.