adds support to run Jasmine suites on CI using Sauce Labs

This commit is contained in:
Nate Clark 2009-12-16 17:27:06 -08:00
parent 40ff1cb4c8
commit 849a4efda8
8 changed files with 171 additions and 43 deletions

View File

@ -119,8 +119,11 @@ jasmine.version_= {
end end
namespace :test do namespace :test do
desc "Run continuous integration tests" desc "Run continuous integration tests using a local Selenium runner"
task :ci => 'jasmine:build' do task :ci => :'ci:local'
namespace :ci do
task :local => 'jasmine:build' do
require "spec" require "spec"
require 'spec/rake/spectask' require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:lambda_ci) do |t| Spec::Rake::SpecTask.new(:lambda_ci) do |t|
@ -130,6 +133,12 @@ jasmine.version_= {
Rake::Task[:lambda_ci].invoke Rake::Task[:lambda_ci].invoke
end end
desc "Run continuous integration tests using Sauce Labs 'Selenium in the Cloud'"
task :saucelabs => 'jasmine:build' do
ENV['SAUCELABS'] = 'true'
Rake::Task['jasmine:test:ci:local'].invoke
end
end
end end
end end

View File

@ -228,46 +228,53 @@ module Jasmine
@browser = options[:browser] ? options[:browser].delete(:browser) : 'firefox' @browser = options[:browser] ? options[:browser].delete(:browser) : 'firefox'
@selenium_pid = nil @selenium_pid = nil
@jasmine_server_pid = nil @jasmine_server_pid = nil
@selenium_host = 'localhost'
@jasmine_server_port = Jasmine::find_unused_port
@selenium_server_port = Jasmine::find_unused_port
end end
def start def start
start_servers start_jasmine_server
@client = Jasmine::SimpleClient.new("localhost", @selenium_server_port, "*#{@browser}", "http://localhost:#{@jasmine_server_port}/") start_selenium_server
@client = Jasmine::SimpleClient.new(@selenium_host, @selenium_server_port, "*#{@browser}", "http://localhost:#{@jasmine_server_port}/")
@client.connect @client.connect
end end
def stop def stop
@client.disconnect @client.disconnect
stop_servers stop_selenium_server
stop_jasmine_server
end end
def start_servers def start_jasmine_server
@jasmine_server_port = Jasmine::find_unused_port
@selenium_server_port = Jasmine::find_unused_port
@selenium_pid = fork do
Process.setpgrp
exec "java -jar #{@selenium_jar_path} -port #{@selenium_server_port} > /dev/null 2>&1"
end
puts "selenium started. pid is #{@selenium_pid}"
@jasmine_server_pid = fork do @jasmine_server_pid = fork do
Process.setpgrp Process.setpgrp
Jasmine::SimpleServer.start(@jasmine_server_port, @spec_files, @dir_mappings, @options) Jasmine::SimpleServer.start(@jasmine_server_port, @spec_files, @dir_mappings, @options)
exit! 0 exit! 0
end end
puts "jasmine server started. pid is #{@jasmine_server_pid}" puts "jasmine server started. pid is #{@jasmine_server_pid}"
Jasmine::wait_for_listener(@selenium_server_port, "selenium server")
Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server") Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
end end
def stop_servers def start_selenium_server
puts "shutting down the servers..." @selenium_pid = fork do
Jasmine::kill_process_group(@selenium_pid) if @selenium_pid Process.setpgrp
exec "java -jar #{@selenium_jar_path} -port #{@selenium_server_port} > /dev/null 2>&1"
end
puts "selenium started. pid is #{@selenium_pid}"
Jasmine::wait_for_listener(@selenium_server_port, "selenium server")
end
def stop_jasmine_server
puts "shutting down Jasmine server..."
Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
end end
def stop_selenium_server
puts "shutting down Selenium server..."
Jasmine::kill_process_group(@selenium_pid) if @selenium_pid
end
def run def run
begin begin
start start
@ -284,6 +291,40 @@ module Jasmine
end end
end end
class SauceLabsRunner < Runner
def initialize(spec_files, dir_mappings, options={})
@spec_files = spec_files
@dir_mappings = dir_mappings
@options = options
@browser = options[:browser] ? options[:browser].delete(:browser) : 'firefox'
@jasmine_server_pid = nil
@jasmine_server_port = Jasmine::find_unused_port
@saucelabs_config = SeleniumConfig.new(options[:saucelabs_config], options[:saucelabs_config_file], @jasmine_server_port)
end
def start_selenium_server
@sauce_tunnel = SauceTunnel.new(@saucelabs_config)
end
def start
start_jasmine_server
start_selenium_server
@client = Jasmine::SimpleClient.new(@saucelabs_config['selenium_server_address'],
4444,
@saucelabs_config['selenium_browser_key'],
"http://#{@saucelabs_config['application_address']}")
@client.connect
end
def stop
@client.disconnect
@sauce_tunnel.shutdown
stop_jasmine_server
end
end
def self.files(f) def self.files(f)
result = f result = f
result = result.call if result.respond_to?(:call) result = result.call if result.respond_to?(:call)

View File

@ -2,13 +2,22 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec/jasmine_helper.
namespace :test do namespace :test do
desc "Run continuous integration tests" desc "Run continuous integration tests"
task :ci => :'ci:local'
namespace :ci do
require "spec" require "spec"
require 'spec/rake/spectask' require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:ci) do |t| Spec::Rake::SpecTask.new(:local) do |t|
t.spec_opts = ["--color", "--format", "specdoc"] t.spec_opts = ["--color", "--format", "specdoc"]
t.spec_files = ["spec/jasmine_spec.rb"] t.spec_files = ["spec/jasmine_spec.rb"]
end end
desc "Run continuous integration tests using Sauce Labs 'Selenium in the Cloud'"
task :saucelabs do
ENV['SAUCELABS'] = 'true'
Rake::Task['test:ci:local'].invoke
end
end
end end
desc "Run specs via server" desc "Run specs via server"

View File

@ -1,11 +1,20 @@
require 'rubygems' require 'rubygems'
require "selenium_rc"
require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_helper.rb")) require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_helper.rb"))
require File.expand_path(File.join(JasmineHelper.jasmine_root, "contrib/ruby/jasmine_spec_builder")) require File.expand_path(File.join(JasmineHelper.jasmine_root, "contrib/ruby/jasmine_spec_builder"))
jasmine_runner = Jasmine::Runner.new(SeleniumRC::Server.new.jar_path, jasmine_runner = if ENV['SAUCELABS'] == 'true'
require 'sauce_tunnel'
require 'selenium_config'
Jasmine::SauceLabsRunner.new(JasmineHelper.specs,
JasmineHelper.dir_mappings,
:saucelabs_config => 'saucelabs',
:saucelabs_config_file => File.expand_path(File.join(File.dirname(__FILE__), "saucelabs.yml")))
else
require "selenium_rc"
Jasmine::Runner.new(SeleniumRC::Server.new.jar_path,
JasmineHelper.specs, JasmineHelper.specs,
JasmineHelper.dir_mappings) JasmineHelper.dir_mappings)
end
spec_builder = Jasmine::SpecBuilder.new(JasmineHelper.raw_spec_files, jasmine_runner) spec_builder = Jasmine::SpecBuilder.new(JasmineHelper.raw_spec_files, jasmine_runner)

View File

@ -0,0 +1,24 @@
local:
application_framework: :selenium
#
# Possible Sauce Labs configurations as of 2009/11/19
# From: http://saucelabs.com/products/docs/sauce-ondemand/browsers
# os: "Windows 2003"
# browser: "iexplore"
# browser-version: "6.", "7.", "8."
# browser: "firefox"
# browser-version: "2.", "3.0", "3.5"
# browser: "safari"
# browser-version: "3.", "4."
# browser: "opera"
# browser-version: "9."
# browser: "googlechrome"
# browser-version: ""
# os: "Linux"
# browser: "firefox"
# browser-version: "3."
saucelabs:
application_framework: :external
selenium_server_address: "saucelabs.com"
selenium_browser_key: '{"username": "--YOUR-SAUCELABS-USERNAME--", "access-key": "--YOUR-SAUCELABS-ACCESS-KEY--", "os": "Linux", "browser": "firefox", "browser-version": "3."}'
application_port: "80"

View File

@ -18,3 +18,6 @@ gems:
version: 1.2.9 version: 1.2.9
- name: selenium-client - name: selenium-client
version: 1.2.17 version: 1.2.17
- name: saucelabs-adapter
version: 0.3.2
install_options: --source=http://gems.pivotallabs.com

View File

@ -1,11 +1,20 @@
require 'rubygems' require 'rubygems'
require "selenium_rc"
require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_helper.rb")) require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_helper.rb"))
require File.expand_path(File.join(JasmineHelper.jasmine_root, "contrib/ruby/jasmine_spec_builder")) require File.expand_path(File.join(JasmineHelper.jasmine_root, "contrib/ruby/jasmine_spec_builder"))
jasmine_runner = Jasmine::Runner.new(SeleniumRC::Server.new.jar_path, jasmine_runner = if ENV['SAUCELABS'] == 'true'
require 'sauce_tunnel'
require 'selenium_config'
Jasmine::SauceLabsRunner.new(JasmineHelper.specs,
JasmineHelper.dir_mappings,
:saucelabs_config => 'saucelabs',
:saucelabs_config_file => File.expand_path(File.join(File.dirname(__FILE__), "saucelabs.yml")))
else
require "selenium_rc"
Jasmine::Runner.new(SeleniumRC::Server.new.jar_path,
JasmineHelper.specs, JasmineHelper.specs,
JasmineHelper.dir_mappings) JasmineHelper.dir_mappings)
end
spec_builder = Jasmine::SpecBuilder.new(JasmineHelper.raw_spec_files, jasmine_runner) spec_builder = Jasmine::SpecBuilder.new(JasmineHelper.raw_spec_files, jasmine_runner)

24
spec/saucelabs.yml Normal file
View File

@ -0,0 +1,24 @@
local:
application_framework: :selenium
#
# Possible Sauce Labs configurations as of 2009/11/19
# From: http://saucelabs.com/products/docs/sauce-ondemand/browsers
# os: "Windows 2003"
# browser: "iexplore"
# browser-version: "6.", "7.", "8."
# browser: "firefox"
# browser-version: "2.", "3.0", "3.5"
# browser: "safari"
# browser-version: "3.", "4."
# browser: "opera"
# browser-version: "9."
# browser: "googlechrome"
# browser-version: ""
# os: "Linux"
# browser: "firefox"
# browser-version: "3."
saucelabs:
application_framework: :external
selenium_server_address: "saucelabs.com"
selenium_browser_key: '{"username": "--YOUR-SAUCELABS-USERNAME--", "access-key": "--YOUR-SAUCELABS-ACCESS-KEY--", "os": "Linux", "browser": "firefox", "browser-version": "3."}'
application_port: "80"