Permalink
Browse files

Initial commit

  • Loading branch information...
mkremer committed Aug 1, 2012
0 parents commit b03dee08110c71a880e393f3c102dccf181d3fd9
Showing with 295 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +2 −0 .travis.yml
  3. +7 −0 Gemfile
  4. +48 −0 Gemfile.lock
  5. +21 −0 README.md
  6. +7 −0 Rakefile
  7. +39 −0 Vagrantfile
  8. +3 −0 config.ru
  9. +13 −0 echo.rb
  10. +32 −0 provision
  11. +10 −0 test/echo_test.rb
  12. +96 −0 test/test_helper.rb
  13. +15 −0 views/form.erb
@@ -0,0 +1,2 @@
+.vagrant
+chromedriver.log
@@ -0,0 +1,2 @@
+rvm:
+ - 1.9.3
@@ -0,0 +1,7 @@
+# A sample Gemfile
+source "https://rubygems.org"
+
+gem "sinatra", require: false
+gem "rake"
+gem "capybara"
+gem "headless"
@@ -0,0 +1,48 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.3.2)
+ capybara (1.1.2)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ selenium-webdriver (~> 2.0)
+ xpath (~> 0.1.4)
+ childprocess (0.3.4)
+ ffi (~> 1.0, >= 1.0.6)
+ ffi (1.1.1)
+ headless (0.3.1)
+ libwebsocket (0.1.5)
+ addressable
+ mime-types (1.19)
+ multi_json (1.3.6)
+ nokogiri (1.5.5)
+ rack (1.4.1)
+ rack-protection (1.2.0)
+ rack
+ rack-test (0.6.1)
+ rack (>= 1.0)
+ rake (0.9.2.2)
+ rubyzip (0.9.9)
+ selenium-webdriver (2.25.0)
+ childprocess (>= 0.2.5)
+ libwebsocket (~> 0.1.3)
+ multi_json (~> 1.0)
+ rubyzip
+ sinatra (1.3.2)
+ rack (~> 1.3, >= 1.3.6)
+ rack-protection (~> 1.2)
+ tilt (~> 1.3, >= 1.3.3)
+ tilt (1.3.3)
+ xpath (0.1.4)
+ nokogiri (~> 1.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ capybara
+ headless
+ rake
+ sinatra
@@ -0,0 +1,21 @@
+Echo [![Build Status](https://secure.travis-ci.org/mkremer/echo.png)](http://travis-ci.org/mkremer/echo)
+==============
+Example of a basic Sinatra application tested with Capybara and Selenium using various options.
+
+Echo has been tested with Ruby 1.9.3
+
+If you have any issues, suggestions, improvements, etc. then please log them using GitHub issues.
+
+Usage
+-----
+To run the Echo run "bundle exec rackup"
+
+License
+-------
+Echo is released under the MIT license.
+
+Author
+------
+[Mark Kremer](https://github.com/mkremer)
+
+
@@ -0,0 +1,7 @@
+require "rake/testtask"
+
+task :default => :test
+Rake::TestTask.new do |t|
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test\.rb'
+end
@@ -0,0 +1,39 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant::Config.run do |config|
+ # All Vagrant configuration is done here. The most common configuration
+ # options are documented and commented below. For a complete reference,
+ # please see the online documentation at vagrantup.com.
+
+ # Hostname
+ config.vm.host_name = "echo"
+
+ # Every Vagrant virtual environment requires a box to build off of.
+ config.vm.box = "precise64"
+
+ # The url from where the 'config.vm.box' box will be fetched if it
+ # doesn't already exist on the user's system.
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
+
+ # Boot with a GUI so you can see the screen. (Default is headless)
+ # config.vm.boot_mode = :gui
+
+ # Assign this VM to a host-only network IP, allowing you to access it
+ # via the IP. Host-only networks can talk to the host machine as well as
+ # any other machines on the same network, but cannot be accessed (through this
+ # network interface) by any external networks.
+ config.vm.network :hostonly, "192.168.33.10"
+
+ # Forward a port from the guest to the host, which allows for outside
+ # computers to access the VM, whereas host only networking does not.
+ # config.vm.forward_port 80, 8080
+
+ # Share an additional folder to the guest VM. The first argument is
+ # an identifier, the second is the path on the guest to mount the
+ # folder, and the third is the path on the host to the actual folder.
+ config.vm.share_folder "v-root", "/vagrant", ".", :nfs => !(ENV["OS"] =~ /windows/i)
+
+ # Provision with a shell script
+ config.vm.provision :shell, :path => "provision"
+end
@@ -0,0 +1,3 @@
+require "./echo"
+
+run Echo
13 echo.rb
@@ -0,0 +1,13 @@
+require "bundler/setup"
+require "sinatra/base"
+require "cgi"
+
+class Echo < Sinatra::Base
+ get "/" do
+ erb :form, locals: {message: nil}
+ end
+
+ post "/" do
+ erb :form, locals: {message: params[:message]}
+ end
+end
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+export DEBIAN_FRONTEND=noninteractive
+
+apt-get update > /dev/null
+
+apt-get -y install build-essential git-core unzip xvfb firefox chromium-browser ruby1.9.1 ruby1.9.1-dev libxml2-dev libxslt1-dev
+
+gem install bundler pry
+
+mkdir -p /home/vagrant/downloads
+mkdir -p /home/vagrant/bin
+chown -R vagrant:vagrant /home/vagrant/bin
+
+if [ "$GUI" == "headless" ]; then
+ echo "GUI is already set to headless"
+else
+ echo "export GUI=\"headless\"" >> /home/vagrant/.profile
+ echo "export GUI=\"headless\"" >> /home/vagrant/.zshenv
+fi
+
+if [ -f "/home/vagrant/bin/chromedriver" ]; then
+ echo "Chromedriver already installed"
+else
+ echo "export PATH=\"/home/vagrant/bin:$PATH\"" >> /home/vagrant/.profile
+ echo "export PATH=\"/home/vagrant/bin:$PATH\"" >> /home/vagrant/.zshenv
+ wget -q http://chromedriver.googlecode.com/files/chromedriver_linux64_21.0.1180.4.zip
+ unzip chromedriver_linux64_21.0.1180.4.zip
+ chown vagrant:vagrant chromedriver && mv chromedriver /home/vagrant/bin/chromedriver
+fi
+
+su -c 'cd /vagrant && bundle' vagrant
@@ -0,0 +1,10 @@
+require "test_helper"
+
+class EchoTest < CapybaraTestCase
+ def test_echo
+ visit "/"
+ fill_in "message", with: "Hello, World!"
+ click_on "Submit"
+ assert page.has_content? "Echo: Hello, World!"
+ end
+end
@@ -0,0 +1,96 @@
+require_relative "../echo"
+require "capybara/dsl"
+require "headless"
+require "minitest/autorun"
+
+# SELENIUM_SERVER is the IP address or hostname of the system running Selenium
+# Server, this is used to determine where to connect to when using one of the
+# selenium_remote_* drivers
+ENV["SELENIUM_SERVER"] ||= "192.168.33.1"
+
+# SELENIUM_APP_HOST is the IP address or hostname of this system (where the
+# tests run against) as reachable for the SELENIUM_SERVER. This is used to set
+# the Capybara.app_host when using one of the selenium_remote_* drivers
+ENV["SELENIUM_APP_HOST"] ||= "192.168.33.10"
+
+# CAPYBARA_DRIVER is the Capybara driver to use, this defaults to Selenium with
+# Firefox
+ENV["CAPYBARA_DRIVER"] ||= "selenium_firefox"
+
+# Setup Capybara to work with the Echo application
+Capybara.app = Echo
+
+# Set the default driver to CAPYBARA_DRIVER, when you change the driver in one
+# of your tests resetting it to the default will ensure that its reset to what
+# you specified when starting the tests.
+Capybara.default_driver = ENV["CAPYBARA_DRIVER"].to_sym
+
+# CapybaraDriverRegistrar is a helper class that enables you to easily register
+# Capybara drivers
+class CapybaraDriverRegistrar
+ # register a Selenium driver for the given browser to run on the localhost
+ def self.register_selenium_local_driver(browser)
+ Capybara.register_driver "selenium_#{browser}".to_sym do |app|
+ Capybara::Selenium::Driver.new(app, browser: browser)
+ end
+ end
+
+ # register a Selenium driver for the given browser to run with a Selenium
+ # Server on another host
+ def self.register_selenium_remote_driver(browser)
+ Capybara.register_driver "selenium_remote_#{browser}".to_sym do |app|
+ Capybara::Selenium::Driver.new(app, browser: :remote, url: "http://#{ENV["SELENIUM_SERVER"]}:4444/wd/hub", desired_capabilities: browser)
+ end
+ end
+end
+
+# Register various Selenium drivers
+CapybaraDriverRegistrar.register_selenium_local_driver(:firefox)
+CapybaraDriverRegistrar.register_selenium_local_driver(:chrome)
+CapybaraDriverRegistrar.register_selenium_remote_driver(:firefox)
+CapybaraDriverRegistrar.register_selenium_remote_driver(:chrome)
+CapybaraDriverRegistrar.register_selenium_remote_driver(:internet_explorer)
+
+# Base test case class to use for tests using Capybara
+class CapybaraTestCase < MiniTest::Unit::TestCase
+ include Capybara::DSL
+
+ # setup is run before each test and sets up the environment appropriately,
+ # the code should pretty much explain itself
+ def setup
+ if headless?
+ @headless = Headless.new
+ @headless.start
+ end
+
+ if selenium_remote?
+ Capybara.app_host = "http://#{ENV["SELENIUM_APP_HOST"]}:#{page.driver.rack_server.port}"
+ end
+ end
+
+ # teardown is run after each test, it saves a screenshot if the last test
+ # failed and resets Capybara for the next test
+ def teardown
+ save_screenshot(__name__) unless passed?
+ Capybara.reset_sessions!
+ Capybara.use_default_driver
+ Capybara.app_host = Capybara.default_host
+ end
+
+ # Determines if a selenium_remote_* driver is being used
+ def selenium_remote?
+ Capybara.current_driver.to_s =~ /\Aselenium_remote/
+ end
+
+ # Determines if the test runs on a headless environment
+ def headless?
+ ENV["GUI"] == "headless" && !selenium_remote?
+ end
+
+ # Saves a screenshot in PNG format with a timestamp and the given name in test/tmp/
+ # Note that this code assumes that you're using a Selenium driver
+ def save_screenshot(name)
+ filename = File.join(File.dirname(__FILE__), "tmp", "#{Time.now.strftime("%Y-%m-%d-%H-%M-%S")}_#{name}.png")
+ page.driver.browser.save_screenshot(filename)
+ end
+end
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <title>Echo</title>
+ </head>
+ <body>
+ <% unless message.nil? %>
+ Echo: <%= CGI.escape_html(message) %>
+ <% end %>
+ <form method="post" action="/">
+ <label for="message">Message</label>
+ <input type="text" name="message" id="message" />
+ <input type="submit" value="Submit" />
+ </form>
+ </body>
+</html>

0 comments on commit b03dee0

Please sign in to comment.