require "webrat"
gem "selenium-client", ">=1.2.9"
require "selenium/client"
require "webrat/selenium/selenium_session"
require "webrat/selenium/matchers"
module Webrat
def self.with_selenium_server #:nodoc:
start_selenium_server
yield
stop_selenium_server
end
def self.start_selenium_server #:nodoc:
unless Webrat.configuration.selenium_server_address
remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5)
remote_control.jar_file = File.expand_path(__FILE__ + "../../../../vendor/selenium-server.jar")
remote_control.start :background => true
end
TCPSocket.wait_for_service :host => (Webrat.configuration.selenium_server_address || "0.0.0.0"), :port => Webrat.configuration.selenium_server_port
end
def self.stop_selenium_server #:nodoc:
::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5).stop unless Webrat.configuration.selenium_server_address
end
def self.pid_file
if File.exists?('config.ru')
prepare_pid_file(Dir.pwd, 'rack.pid')
else
prepare_pid_file("#{RAILS_ROOT}/tmp/pids", "mongrel_selenium.pid")
end
end
# Start the appserver for the underlying framework to test
#
# Sinatra: requires a config.ru in the root of your sinatra app to use this
# Merb: Attempts to use bin/merb and falls back to the system merb
# Rails: Calls mongrel_rails to startup the appserver
def self.start_app_server
case Webrat.configuration.application_framework
when :sinatra
fork do
File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
end
when :merb
cmd = 'merb'
if File.exist?('bin/merb')
cmd = 'bin/merb'
end
system("#{cmd} -d -p #{Webrat.configuration.application_port} -e #{Webrat.configuration.application_environment}")
else # rails
system("mongrel_rails start -d --chdir='#{RAILS_ROOT}' --port=#{Webrat.configuration.application_port} --environment=#{Webrat.configuration.application_environment} --pid #{pid_file} &")
end
TCPSocket.wait_for_service :host => Webrat.configuration.application_address, :port => Webrat.configuration.application_port.to_i
end
# Stop the appserver for the underlying framework under test
#
# Sinatra: Reads and kills the pid from the pid file created on startup
# Merb: Reads and kills the pid from the pid file created on startup
# Rails: Calls mongrel_rails stop to kill the appserver
def self.stop_app_server
case Webrat.configuration.application_framework
when :sinatra
pid = File.read('rack.pid')
system("kill -9 #{pid}")
FileUtils.rm_f 'rack.pid'
when :merb
pid = File.read("log/merb.#{Webrat.configuration.application_port}.pid")
system("kill -9 #{pid}")
FileUtils.rm_f "log/merb.#{Webrat.configuration.application_port}.pid"
else # rails
system "mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
end
end
def self.prepare_pid_file(file_path, pid_file_name)
FileUtils.mkdir_p File.expand_path(file_path)
File.expand_path("#{file_path}/#{pid_file_name}")
end
# To use Webrat's Selenium support, you'll need the selenium-client gem installed.
# Activate it with (for example, in your env.rb):
#
# require "webrat"
#
# Webrat.configure do |config|
# config.mode = :selenium
# end
#
# == Dropping down to the selenium-client API
#
# If you ever need to do something with Selenium not provided in the Webrat API,
# you can always drop down to the selenium-client API using the selenium method.
# For example:
#
# When "I drag the photo to the left" do
# selenium.dragdrop("id=photo_123", "+350, 0")
# end
#
# == Choosing the underlying framework to test
#
# Webrat assumes you're using rails by default but it can also work with sinatra
# and merb. To take advantage of this you can use the configuration block to
# set the application_framework variable.
# require "webrat"
#
# Webrat.configure do |config|
# config.mode = :selenium
# config.application_port = 4567
# config.application_framework = :sinatra # could also be :merb
# end
#
# == Auto-starting of the appserver and java server
#
# Webrat will automatically start the Selenium Java server process and an instance
# of Mongrel when a test is run. The Mongrel will run in the "selenium" environment
# instead of "test", so ensure you've got that defined, and will run on port
# Webrat.configuration.application_port.
#
# == Waiting
#
# In order to make writing Selenium tests as easy as possible, Webrat will automatically
# wait for the correct elements to exist on the page when trying to manipulate them
# with methods like fill_in, etc. In general, this means you should be able to write
# your Webrat::Selenium tests ignoring the concurrency issues that can plague in-browser
# testing, so long as you're using the Webrat API.
module Selenium
module Methods
def response
webrat_session.response
end
def wait_for(*args, &block)
webrat_session.wait_for(*args, &block)
end
def save_and_open_screengrab
webrat_session.save_and_open_screengrab
end
end
end
end
if defined?(ActionController::IntegrationTest)
module ActionController #:nodoc:
IntegrationTest.class_eval do
include Webrat::Methods
include Webrat::Selenium::Methods
include Webrat::Selenium::Matchers
end
end
end