breaking into the unknown…

sample app with sinatra rspec capybara and selenium


I have been working with rails rspec capybara and selenium for long, but recently I have to build an API for client which he specifically requested in sinatra. I will list difference between rails and sinatra some other days. For now, I can quote below characteristic for sinatra

1->It not a framework i,e no folder , configuration file etc get created
2->no mvc concept, whole project may be written in a single file
3->can pack your app as a gem which can be used by other . ex : resque for managing background job is build on sinatra

You can download a no of available ebook on sinatra to know it in detail. Here, I will just create a “Hello sinatra” app and configure it with rspec capybara and selenium. STEPS 1 to 6 is just the basic steps Iam following in all the rails project as so adopted it here also a good practice

STEP 1: create your project folder and call it say sinatra_app

STEP 2: create a gemset sinatra_app if you are using RVM(I suggest all ruby dveloper to use it ) # detail on RVM is avilable here and here

If you are not using RVM, install bundler gem first with the command sudo gem install bundler. more detail on bundler is available here

STEP 3: create a file with name Gemfile in this folder and add the required gems to it. The Gemfile content will look like this

source ''

gem "thin" # sinatra by default run with thin, so this gem is also required
gem "sinatra"

group :test do
  gem "rspec", ">= 1.2.1"
  gem "capybara", ">= 1.1.2"

STEP 4: If you are using RVM create a .rvmrc file in your sinatra_app folder and add below line to it.

It will load the proper ruby version and your sinatra_app gemset everytime you cd to the sinatra_app folder

rvm ruby-1.9.3-p194@sinatra_app # Iam assuming that you are using ruby version rvm ruby-1.9.3-p194 and your gemset name is sinatra_app, change it accordingly

STEP 5 : go to terminal and cd to sinatra_app folder and run below command

$ bundle install # you will slow below trace on the terminal
Fetching gem metadata from
Fetching gem metadata from
Using addressable (2.3.2) 
Using mime-types (1.19) 
Installing nokogiri (1.5.6) with native extensions 
Installing rack (1.4.3) 
Using rack-test (0.6.2) 
Installing ffi (1.3.0) with native extensions 
Installing childprocess (0.3.6) 
Installing websocket (1.0.6) 
Installing libwebsocket ( 
Installing multi_json (1.5.0) 
Using rubyzip (0.9.9) 
Installing selenium-webdriver (2.27.2) 
Installing xpath (1.0.0) 
Installing capybara (2.0.2) 
Using daemons (1.1.9) 
Using diff-lcs (1.1.3) 
Using eventmachine (1.0.0) 
Using rack-protection (1.3.2) 
Installing rspec-core (2.12.2) 
Installing rspec-expectations (2.12.1) 
Installing rspec-mocks (2.12.1) 
Installing rspec (2.12.0) 
Using tilt (1.3.3) 
Using sinatra (1.3.3) 
Installing thin (1.5.0) with native extensions 
Using bundler (1.1.5)

Thus you can see that all our required gem thin, rspec,and  capybara get installed along with there dependency. You can also see a new file Gemfile.lock get created in sinatra_app folder. Since, our base is now ready, so better push our code to git in the next step

STEP 6 : pushing the existing files to GIT

$ cd sinatra_app #all mentioned command here will run only after moving to sinatra_app folder
$ git init .
$ git add .
$ git commit -a -m"my initial commit"

STEP 7: create my_sinatra_app.rb file and below line to it

require 'sinatra'
get '/' do
  "Hello....Sinatra :)"

STEP 8: Run the app on terminal with ruby command

$ ruby loanpath_api.rb
== Sinatra/1.3.3 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
>> Maximum connections set to 1024
>> Listening on, CTRL+C to stop

You can see that thin is Listining to port 4567 at

STEP 9: see your app in browser by typing #you can see the loaded page with message “Hello….Sinatra :)”

STEP 10: Adding rspec to sinatra

$ rspec --init
The --configure option no longer needs any arguments, so true was ignored.
  create   spec/spec_helper.rb
  create   .rspec

You can see that it has created two files for you within spec folder. The important one is spec_helper.rb. The default content of this file is as below

RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = 'random'

we will add, the require configuration to make rspec work with sinatra in the next step. Infact, any rspec configuration should go to this file.

STEP 11 : spec_helper.rb content after adding setting for sinatra is as below

require 'rack/test' # it is needed to run rspec
include Rack::Test::Methods # It contain different method like get,  last_response etc which
 you use to write your test

def app
  Sinatra::Application # It is must and tell rspec that test it running is for sinatra

set :environment, :test # setting the environment in which the test will run

RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = 'random'

STEP 12 : Writing the first test case
create a file with any name, but as a good practice, it should be same as the file you are testing so we will call it my_sinatra_app_specs.rb and add below line to it

require_relative '../my_sinatra_app.rb' # this load the file you are testing
require 'spec_helper.rb' # It will load the configuration you set in spec_helper.rb

describe 'sinatra app home page' do	
	it "should load the home page" do # the first test
	  get '/' # you are visiting the home page
	  last_response.should be_ok # it will true if the home page load successfully

STEP 13 : Run test file my_sinatra_app_specs.rb with rspec

$ rspec spec/my_sinatra_app_specs.rb
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}

Finished in 0.01908 seconds
1 example, 0 failures

Randomized with seed 28600

Thus, you can see that, our test has pass. till now we are using methods available to rspec, if you want to use methods like visit, response etc it will throw error as they are methods of capybara which we have still not configured. we will configure capybara and selenium in next step and then modify our test to use visit and response instead of get and last_reponse

STEP 14 : configuring rspec to work with capybara and selenium

Since, now we are going to use capybara, we do not need get, last_rsponse etc method of  Rack::Test::Methods, so we will remove the top two line and replace them with capybara configuration. The spec_helper.rb will now look as below. You can read more about capybara here

require 'capybara' # loading capybara
include Capybara::DSL # It contain all the methods you use for writing test. If you do not use it , 
get this error.
Capybara.default_driver = :selenium # it will tell capybara to use selenium. It should be noted that  
By default, Capybara uses the :rack_test driver, which is fast but limited: it does not support 
JavaScript, nor is it able to access HTTP resources outside of your Rack application, such as remote 
APIs and OAuth services.

def app 

set :environment, :test 
RSpec.configure do |config| 
  config.treat_symbols_as_metadata_keys_with_true_values = true 
  config.run_all_when_everything_filtered = true 
  config.filter_run :focus config.order = 'random' 

STEP 15 : modifying our test case

We will now rewrite, our test case in steps 12 with capybara methods like visit ,page etc

describe 'make API call to loanpath' do	
  it "should load the home page" do
    visit ''
    page.should have_content("sinatra")

Now, when you run your test again with rspec spec/my_sinatra_app_specs.rb command, you can see capybara working and selenium web driver simulating your app


Author: arunyadav4u

over 7 years experience in web development with Ruby on Rails.Involved in all stage of development lifecycle : requirement gathering, planing, coding, deployment & Knowledge transfer. I can adept to any situation, mixup very easily with people & can be a great friend.

4 thoughts on “sample app with sinatra rspec capybara and selenium

  1. Hi Arun,

    Iam new to ruby application ,and currently am working for a testing application which is designed on Ruby,capybara,rspec and am having an issue i.e when am on a button a javascript popup is displaying and sometime modalpopup also displaying but am unable to click the alert and even i have tried different ways through google but none of them worked for example the script whic i have used is
    alert.send(‘Stay on Page’)

    2. page.evaluate_script(‘window.confirm = function() { return true; }’)“Stay on Page”)

    .My spec_helper.rb looks like this

    require ‘capybara’
    require ‘capybara/rspec’
    require ‘capybara/dsl’
    require ‘selenium-webdriver’
    require ‘yaml’
    #require ‘capybara-screenshot/rspec’

    Capybara.default_driver = :selenium
    Capybara.run_server = false
    # See
    RSpec.configure do |config|
    config.include Capybara::DSL
    config.include Capybara::RSpecMatchers
    config.treat_symbols_as_metadata_keys_with_true_values = true
    config.run_all_when_everything_filtered = true
    config.filter_run :focus

    # Run specs in random order to surface order dependencies. If you find an
    # order dependency and want to debug it, you can fix the order by providing
    # the seed, which is printed after each run.
    # –seed 1234
    #config.order = ‘random’

    #Capybara configuration changes from the default that are needed.
    Capybara.configure do |config|
    config.match = :prefer_exact
    config.exact_options = true
    config.ignore_hidden_elements = true
    config.visible_text_only = true


    require_relative ‘configuration’
    require_relative ‘helpers/common/application’

    #this recursively pulls all files under the ‘helpers’ folder.
    #puts ‘Current Directory:-‘ + File.dirname(__FILE__)
    #puts [File.join(File.dirname(__FILE__), ‘helpers’, ‘*.rb’)]
    current_path = File.expand_path File.dirname(__FILE__)
    #puts “CURRENT” + current_path
    helpers_path = File.join current_path, “helpers”
    #puts “HELPERS” + helpers_path
    Dir[“#{helpers_path}/**/*.rb”].each { |file|
    require file
    #puts file

    4.My Testcase file
    .My test file looks like this

    require ‘spec_helper’
    feature ‘Apply to all levels copies the string ID’,js:true do
    #Config changes
    app =

    #Specify Object Maps
    scenario ‘Apply to all levels copies the string ID_spec’ do
    app.utilities.setup_directory(‘L1 – Apply to all levels copies the string ID_spec’)
    Capybara.current_driver = selenium

    #Specify Test data
    if app.env == ‘ACP’
    app.client_finder.client_id = ‘1612823’


    #Launch the web site, Login and open Application
    visit app.url

    app.login.enter_user_password_and_login(app.user_id, app.password)


    #Enter search criteria, click Search and select Program
    #Verify Brochure Builder page is displayed
    app.utilities.verify_page_content(‘Brochure Design Options’)

    #Click on Award Level Message in Selected Blocks Brochure Builder page is displayed


    rescue Exception => e
    app.utilities.capture_screen_shot(‘script failed’,’fail’)
    raise e

    The remaining configuration files and common files and those have nothing just page urls credentials and common methods so please guide me for clicking that popups what i need to change and how should i work .


    • Hi Venkat,

      I didn’t exactly get your problem.

      This is what, I understand…

      You have a page with some links which open up a popup with certain content.
      Now you want to test this behaviour i,e on that particular page , when a particular link is clicked,
      some popup will open up with some specific content, the test should pass.

      It should fail, if the popup do not openup or do not have the specific content.

      If this is what you want, I will try to figure out how to do this

  2. Can you please explain how to create API’s for Image uploading and video uploading and Authentication API using devise

    • The basic architecture on any API is same. It is explained here .

      I will suggest you to develop in below steps:

      1. Decide Where you are going to upload the data- box, google drive, your own server etc
      2. Implement the method(say image_upload and video_upload) which achieve your goal
      3. Work on exposing the method as an API
      4. Decide on choice for authenticating the API – basic_authentication, token based authentication etc

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s