Support for running tests against a local Selenium RC

Also did some code cleanup and re-organization
This commit is contained in:
Eric Allen 2010-11-02 11:21:13 -07:00
parent aa5a4fa891
commit d05795f1b7
11 changed files with 166 additions and 80 deletions

View File

@ -13,9 +13,10 @@ Current:
Planned:
* Include selenium-client RSpec/Test::Unit integration
* Webrat integration
* Extend to automatic retrieval of jobs logs, videos, reverse tunnels
* Start/stop local instances of Sauce RC
* Webrat integration
Install
-------

View File

@ -1,51 +1 @@
spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop
task :noop do
end
namespace :spec do
namespace :selenium do
desc "Run the Selenium acceptance tests in spec/selenium using Sauce OnDemand"
task :sauce => spec_prereq do
server = IO.popen("script/server RAILS_ENV=test --port 3001")
begin
Rake::Task["spec:selenium:runtests"].invoke
ensure
Process.kill("INT", server.pid)
end
end
desc "" # Hide it from rake -T
Spec::Rake::SpecTask.new :runtests do |t|
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
t.spec_files = FileList["spec/selenium/**/*_spec.rb"]
end
end
task :selenium => "selenium:sauce"
end
namespace :test do
namespace :selenium do
desc "Run the Selenium acceptance tests in test/selenium using Sauce OnDemand"
task :sauce do
server = IO.popen("script/server --port 3001")
begin
Rake::Task["test:selenium:runtests"].invoke
ensure
Process.kill("INT", server.pid)
end
end
Rake::TestTask.new(:runtests) do |t|
t.libs << "test"
t.pattern = 'test/selenium/**/*_test.rb'
t.verbose = true
end
desc "" # Hide it from rake -T
Rake::Task['test:selenium:runtests'].instance_variable_set(:@full_comment, nil)
Rake::Task['test:selenium:runtests'].instance_variable_set(:@comment, nil)
Rake::Task['test:selenium:runtests'].enhance(["db:test:prepare"])
end
task :selenium => "selenium:sauce"
end
require 'sauce/raketasks'

View File

@ -1,4 +1,5 @@
require 'rubygems'
require 'sauce/utilities'
require 'sauce/tunnel'
require 'sauce/job'
require 'sauce/client'

View File

@ -14,6 +14,7 @@ module Sauce
class Config
attr_reader :opts
DEFAULT_OPTIONS = {
:host => "saucelabs.com",
:port => 4444,
@ -21,7 +22,8 @@ module Sauce
:os => "Linux",
:browser => "firefox",
:browser_version => "3.",
:job_name => "Unnamed Ruby job"
:job_name => "Unnamed Ruby job",
:local_application_port => "3001"
}
def initialize(opts={})
@ -65,6 +67,10 @@ module Sauce
return URI.parse(@opts[:browser_url]).host
end
def local?
return ENV['LOCAL_SELENIUM']
end
private
def load_options_from_environment

View File

@ -30,7 +30,7 @@ module Sauce
if line =~ /- (Problem.*)$/
@error = $1
end
puts line
puts line unless options[:quiet]
end
@ready = false
}

View File

@ -1,3 +1,5 @@
# NOTE: This has been superseded by sauce/connect. Consider for deprecation
# http://groups.google.com/group/capistrano/browse_thread/thread/455c0c8a6faa9cc8?pli=1
class Net::SSH::Gateway
# Opens a SSH tunnel from a port on a remote host to a given host and port

View File

@ -7,7 +7,7 @@ begin
before :suite do
config = Sauce::Config.new
if config.application_host
if config.application_host && !config.local?
@@tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
@@tunnel.wait_until_ready
end
@ -19,21 +19,22 @@ begin
end
end
before(:each) do
@selenium.start
end
after(:each) do
@selenium.stop
end
def execute(*args)
config = Sauce::Config.new
description = [self.class.description, self.description].join(" ")
config.browsers.each do |os, browser, version|
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{description}"})
if config.local?
@selenium = ::Selenium::Client::Driver.new(:host => "127.0.0.1",
:port => 4444,
:browser => "*" + browser,
:url => "http://127.0.0.1:#{config.local_application_port}/")
else
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{description}"})
end
@selenium.start
super(*args)
@selenium.stop
end
end
@ -61,8 +62,15 @@ begin
unless name =~ /^default_test/
config = Sauce::Config.new
config.browsers.each do |os, browser, version|
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{name}"})
if config.local?
@selenium = ::Selenium::Client::Driver.new(:host => "127.0.0.1",
:port => 4444,
:browser => "*" + browser,
:url => "http://127.0.0.1:#{config.local_application_port}/")
else
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{name}"})
end
@selenium.start
super(*args, &blk)
@selenium.stop
@ -73,11 +81,6 @@ begin
# Placeholder so test/unit ignores test cases without any tests.
def default_test
end
def self.ensure_tunnel_running
unless defined?(@tunnel)
end
end
end
end
require 'test/unit/ui/console/testrunner'
@ -95,7 +98,7 @@ begin
def start_tunnel(msg)
config = Sauce::Config.new
if config.application_host
if config.application_host && !config.local?
@sauce_tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
@sauce_tunnel.wait_until_ready
end
@ -123,8 +126,15 @@ if defined?(ActiveSupport::TestCase)
unless name =~ /^default_test/
config = Sauce::Config.new
config.browsers.each do |os, browser, version|
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{name}"})
if config.local?
@selenium = ::Selenium::Client::Driver.new(:host => "127.0.0.1",
:port => 4444,
:browser => "*" + browser,
:url => "http://127.0.0.1:#{config.local_application_port}/")
else
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
:job_name => "#{name}"})
end
@selenium.start
super(*args, &blk)
@selenium.stop
@ -135,11 +145,6 @@ if defined?(ActiveSupport::TestCase)
# Placeholder so test/unit ignores test cases without any tests.
def default_test
end
def self.ensure_tunnel_running
unless defined?(@tunnel)
end
end
end
end
end

67
lib/sauce/raketasks.rb Normal file
View File

@ -0,0 +1,67 @@
require 'sauce'
spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop
task :noop do
end
include Sauce::Utilities
namespace :spec do
namespace :selenium do
desc "Run the Selenium acceptance tests in spec/selenium using Sauce OnDemand"
task :sauce => spec_prereq do
with_rails_server do
Rake::Task["spec:selenium:runtests"].invoke
end
end
desc "Run the Selenium acceptance tests in spec/selenium using a local Selenium server"
task :local => spec_prereq do
with_rails_server do
with_selenium_rc do
Rake::Task["spec:selenium:runtests"].invoke
end
end
end
desc "" # Hide it from rake -T
Spec::Rake::SpecTask.new :runtests do |t|
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
t.spec_files = FileList["spec/selenium/**/*_spec.rb"]
end
end
task :selenium => "selenium:sauce"
end
namespace :test do
namespace :selenium do
desc "Run the Selenium acceptance tests in test/selenium using Sauce OnDemand"
task :sauce do
with_rails_server do
Rake::Task["test:selenium:runtests"].invoke
end
end
desc "Run the Selenium acceptance tests in spec/selenium using a local Selenium server"
task :local do
with_rails_server do
with_selenium_rc do
Rake::Task["test:selenium:runtests"].invoke
end
end
end
Rake::TestTask.new(:runtests) do |t|
t.libs << "test"
t.pattern = 'test/selenium/**/*_test.rb'
t.verbose = true
end
# Hide it from rake -T
Rake::Task['test:selenium:runtests'].instance_variable_set(:@full_comment, nil)
Rake::Task['test:selenium:runtests'].instance_variable_set(:@comment, nil)
Rake::Task['test:selenium:runtests'].enhance(["db:test:prepare"])
end
task :selenium => "selenium:sauce"
end

View File

@ -1,3 +1,5 @@
# NOTE: This has been superseded by sauce/connect. Consider for deprecation
require 'net/telnet'
require 'net/ssh'
require 'net/ssh/gateway'

52
lib/sauce/utilities.rb Normal file
View File

@ -0,0 +1,52 @@
module Sauce
module Utilities
def silence_stream(stream)
old_stream = stream.dup
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
stream.sync = true
yield
ensure
stream.reopen(old_stream)
end
def with_selenium_rc
ENV['LOCAL_SELENIUM'] = "true"
STDERR.puts "Starting Selenium RC server on port 4444..."
server = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", 4444)
server.jar_file = File.expand_path(File.dirname(__FILE__) + "/../../support/selenium-server.jar")
silence_stream(STDOUT) do
server.start :background => true
TCPSocket.wait_for_service(:host => "127.0.0.1", :port => 4444)
end
STDERR.puts "Selenium RC running!"
begin
yield
ensure
server.stop
end
end
def with_rails_server
STDERR.puts "Starting Rails server on port 3001..."
server = IO.popen("script/server RAILS_ENV=test --port 3001 2>&1")
pid = nil
Thread.new do
while (line = server.gets)
if line =~ /pid=(.*) /
pid = $1.to_i
end
end
end
silence_stream(STDOUT) do
TCPSocket.wait_for_service(:host => "127.0.0.1", :port => 3001)
end
STDERR.puts "Rails server running!"
begin
yield
ensure
Process.kill("INT", pid)
end
end
end
end

BIN
support/selenium-server.jar Normal file

Binary file not shown.