{"id":13747294,"url":"https://github.com/thoughtbot/capybara_discoball","last_synced_at":"2025-10-31T09:30:53.944Z","repository":{"id":3853057,"uuid":"4937595","full_name":"thoughtbot/capybara_discoball","owner":"thoughtbot","description":"Spin up an external server just for Capybara","archived":false,"fork":false,"pushed_at":"2024-08-16T18:20:31.000Z","size":37,"stargazers_count":129,"open_issues_count":2,"forks_count":7,"subscribers_count":37,"default_branch":"main","last_synced_at":"2025-02-09T13:07:52.314Z","etag":null,"topics":["capybara","capybara-discoball","rack","ruby","testing","testing-tools","thoughtbot"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoughtbot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-07-07T12:50:54.000Z","updated_at":"2024-08-16T18:20:36.000Z","dependencies_parsed_at":"2024-08-16T19:10:53.373Z","dependency_job_id":null,"html_url":"https://github.com/thoughtbot/capybara_discoball","commit_stats":{"total_commits":33,"total_committers":9,"mean_commits":"3.6666666666666665","dds":0.5454545454545454,"last_synced_commit":"4e89bfe5531eea1bf6dac42c46c26d0c687d6ddf"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fcapybara_discoball","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fcapybara_discoball/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fcapybara_discoball/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fcapybara_discoball/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoughtbot","download_url":"https://codeload.github.com/thoughtbot/capybara_discoball/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239138438,"owners_count":19588240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["capybara","capybara-discoball","rack","ruby","testing","testing-tools","thoughtbot"],"created_at":"2024-08-03T06:01:24.144Z","updated_at":"2025-10-31T09:30:53.594Z","avatar_url":"https://github.com/thoughtbot.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"capybara_discoball\n==================\n\n[![Build Status](https://travis-ci.org/thoughtbot/capybara_discoball.svg?branch=master)](https://travis-ci.org/thoughtbot/capybara_discoball)\n[![Code Climate](https://codeclimate.com/github/thoughtbot/capybara_discoball/badges/gpa.svg)](https://codeclimate.com/github/thoughtbot/capybara_discoball)\n\nSpin up a rack app just for Capybara.\n\nThis is useful for when ShamRack won't cut it: when your JavaScript hits\nan external service, or you need to load an image or iframe from\nelsewhere, or in general something outside of your Ruby code needs to\ntalk with an API.\n\nSynopsis\n--------\n\n```ruby\n# Use Sinatra, for example\nrequire 'sinatra/base'\nrequire 'capybara_discoball'\n\n# Define a quick Rack app\nclass FakeMusicDB \u003c Sinatra::Base\n  cattr_reader :albums\n\n  get '/musicians/:musician/albums' do |musician|\n    \u003c\u003c-XML\n    \u003calbums for=\"#{musician}\"\u003e\n      #{@albums.map { |album| \"\u003calbum\u003e#{album}\u003c/album\u003e\" }.join}\n    \u003c/albums\u003e\n    XML\n  end\nend\n\n# Spin up the Rack app, then update the imaginary library we're\n# using to point to the new URL.\nCapybara::Discoball.spin(FakeMusicDB) do |server|\n  MusicDB.endpoint_url = server.url\nend\n```\n\nMore details\n------------\n\nYou can instantiate a `Capybara::Discoball::Runner`, passing in a\nfactory which will create a Rack app:\n\n```ruby\nFakeMusicDBRunner = Capybara::Discoball::Runner.new(FakeMusicDB) do\n  # tests to perform after server boot\nend\n```\n\nThis gives you back a runner, which you can boot from your features,\nspecs, tests, console, whatever:\n\n```ruby\nFakeMusicDBRunner.boot\n```\n\nThese two steps can be merged with the `spin` class method:\n\n```ruby\nCapybara::Discoball.spin(FakeMusicDB) do\n  # tests to perform while server is spinning\nend\n```\n\nIt is always the case that you need to know the URL for the external\nAPI. We provide a way to access that URL; in fact, we offer the whole\n`Capybara::Server` for you to play with. In this example, we are using\nsome `MusicDB` library in the code that knows to hit the\n`.endpoint_url`:\n\n```ruby\nFakeMusicDBRunner = Capybara::Discoball::Runner.new(FakeMusicDB) do |server|\n  MusicDB.endpoint_url = server.url\nend\n```\n\nIf no block is provided, the URL is also returned by `#spin`:\n\n```ruby\nMusicDB.endpoint_url = Capybara::Discoball.spin(FakeMusicDB)\n```\n\nIntegrating into your app\n-------------------------\n\nAll of this means that you must be able to set the endpoint URL. There\nare two tricky cases:\n\n*When the third-party library does not have hooks to set the endpoint\nURL*.\n\nOpen the class and add the hooks yourself. This requires understanding\nthe source of the library. Here's an example where the library uses\n`@@endpoint_url` everywhere to refer to the endpoint URL:\n\n```ruby\nclass MusicDB\n  def self.endpoint_url=(endpoint_url)\n    @@endpoint_url = endpoint_url\n  end\nend\n```\n\n*When your JavaScript needs to talk to the endpoint URL*.\n\nFor this you must thread the URL through your app so that the JavaScript\ncan find it:\n\n```ruby\n\u003c% content_for :javascript do %\u003e\n  \u003c% javascript_tag do %\u003e\n    albumShower = new AlbumShower(\u003c%= MusicDB.endpoint_url.to_json %\u003e);\n    albumShower.show();\n  \u003c% end %\u003e\n\u003c% end %\u003e\n\nclass @AlbumShower\n  constructor: (@endpointUrl) -\u003e\n  show: -\u003e\n    $.get(@endpointUrl, (data) -\u003e $('#albums').html(data))\n```\n\nContributing\n------------\n\nSee the [CONTRIBUTING] document. Thank you, [contributors]!\n\n[CONTRIBUTING]: /CONTRIBUTING.md\n[contributors]: https://github.com/thoughtbot/capybara_discoball/graphs/contributors\n\nLicense\n-------\n\ncapybara_discoball is Copyright (c) 2012-2018 thoughtbot, inc. It is free software,\nand may be redistributed under the terms specified in the [LICENSE] file.\n\n[LICENSE]: /LICENSE\n\nAbout\n-----\n\n![thoughtbot](https://thoughtbot.com/logo.png)\n\ncapybara_discoball is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community]\nor [hire us][hire] to help build your product.\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fcapybara_discoball","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoughtbot%2Fcapybara_discoball","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fcapybara_discoball/lists"}