saucelabs-adapter 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +150 -0
- data/Rakefile +108 -0
- data/VERSION +1 -0
- data/generators/saucelabs_adapter/saucelabs_adapter_generator.rb +49 -0
- data/generators/saucelabs_adapter/templates/jsunit.rake +62 -0
- data/generators/saucelabs_adapter/templates/jsunit_suite_example.rb +19 -0
- data/generators/saucelabs_adapter/templates/saucelabs_adapter.rake +53 -0
- data/generators/saucelabs_adapter/templates/selenium.yml +66 -0
- data/lib/saucelabs-adapter.rb +1 -0
- data/lib/saucelabs_adapter.rb +6 -0
- data/lib/saucelabs_adapter/jsunit_selenium_support.rb +121 -0
- data/lib/saucelabs_adapter/run_utils.rb +14 -0
- data/lib/saucelabs_adapter/sauce_tunnel.rb +122 -0
- data/lib/saucelabs_adapter/selenium_config.rb +152 -0
- data/lib/saucelabs_adapter/test_unit_adapter.rb +49 -0
- data/lib/saucerest-ruby/gateway.rb +35 -0
- data/lib/saucerest-ruby/saucerest.rb +56 -0
- data/spec/selenium_config_spec.rb +151 -0
- data/test/helper.rb +10 -0
- data/test/test_saucelabs-adapter.rb +10 -0
- metadata +124 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
if defined?(ActiveSupport)
|
2
|
+
puts "[saucelabs-adapter] Inserting ActiveSupport::TestCase before_setup :configure_selenium hook" if ENV['SAUCELABS_ADAPTER_DEBUG']
|
3
|
+
|
4
|
+
module ::ActiveSupport
|
5
|
+
class TestCase
|
6
|
+
setup :configure_selenium # 'before_setup' callback from ActiveSupport::TestCase
|
7
|
+
|
8
|
+
def configure_selenium
|
9
|
+
puts "[saucelabs-adapter] gem is loading..." if ENV['SAUCELABS_ADAPTER_DEBUG']
|
10
|
+
selenium_config = SaucelabsAdapter::SeleniumConfig.new(ENV['SELENIUM_ENV'])
|
11
|
+
if defined?(Polonium)
|
12
|
+
polonium_config = Polonium::Configuration.instance
|
13
|
+
selenium_config.configure_polonium(polonium_config)
|
14
|
+
elsif defined?(Webrat)
|
15
|
+
webrat_config = Webrat.configuration
|
16
|
+
selenium_config.configure_webrat(webrat_config)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if defined?(Test)
|
24
|
+
puts "[saucelabs-adapter] Inserting Test::Unit::UI::Console::TestRunner attach_to_mediator tunnel start hook" if ENV['SAUCELABS_ADAPTER_DEBUG']
|
25
|
+
|
26
|
+
class Test::Unit::UI::Console::TestRunner
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def attach_to_mediator_with_sauce_tunnel
|
31
|
+
attach_to_mediator_without_sauce_tunnel
|
32
|
+
@selenium_config = SaucelabsAdapter::SeleniumConfig.new(ENV['SELENIUM_ENV'])
|
33
|
+
if @selenium_config.start_sauce_tunnel?
|
34
|
+
@mediator.add_listener(Test::Unit::UI::TestRunnerMediator::STARTED, &method(:setup_tunnel))
|
35
|
+
@mediator.add_listener(Test::Unit::UI::TestRunnerMediator::FINISHED, &method(:teardown_tunnel))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method_chain :attach_to_mediator, :sauce_tunnel unless private_method_defined?(:attach_to_mediator_without_sauce_tunnel)
|
40
|
+
|
41
|
+
def setup_tunnel(suite_name)
|
42
|
+
@tunnel = SaucelabsAdapter::SauceTunnel.new(@selenium_config)
|
43
|
+
end
|
44
|
+
|
45
|
+
def teardown_tunnel(suite_name)
|
46
|
+
@tunnel.shutdown
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# http://groups.google.com/group/capistrano/browse_thread/thread/455c0c8a6faa9cc8?pli=1
|
2
|
+
class Net::SSH::Gateway
|
3
|
+
# Opens a SSH tunnel from a port on a remote host to a given host and port
|
4
|
+
# on the local side
|
5
|
+
# (equivalent to openssh -R parameter)
|
6
|
+
def open_remote(port, host, remote_port, remote_host = "127.0.0.1")
|
7
|
+
ensure_open!
|
8
|
+
|
9
|
+
@session_mutex.synchronize do
|
10
|
+
@session.forward.remote(port, host, remote_port, remote_host)
|
11
|
+
end
|
12
|
+
|
13
|
+
if block_given?
|
14
|
+
begin
|
15
|
+
yield [remote_port, remote_host]
|
16
|
+
ensure
|
17
|
+
close_remote(remote_port, remote_host)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
return [remote_port, remote_host]
|
21
|
+
end
|
22
|
+
rescue Errno::EADDRINUSE
|
23
|
+
retry
|
24
|
+
end
|
25
|
+
|
26
|
+
# Cancels port-forwarding over an open port that was previously opened via
|
27
|
+
# #open_remote.
|
28
|
+
def close_remote(port, host = "127.0.0.1")
|
29
|
+
ensure_open!
|
30
|
+
|
31
|
+
@session_mutex.synchronize do
|
32
|
+
@session.forward.cancel_remote(port, host)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rest_client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module SauceREST
|
6
|
+
|
7
|
+
# A simple class for using the Sauce Labs REST API
|
8
|
+
class Client
|
9
|
+
@@roots = {
|
10
|
+
:script => 'scripts',
|
11
|
+
:job => 'jobs',
|
12
|
+
:result => 'results',
|
13
|
+
:tunnel => 'tunnels'
|
14
|
+
}
|
15
|
+
|
16
|
+
def initialize base_url
|
17
|
+
@base_url = base_url
|
18
|
+
@resource = RestClient::Resource.new @base_url
|
19
|
+
end
|
20
|
+
|
21
|
+
def create type, *args
|
22
|
+
doc = args[-1]
|
23
|
+
doc_json = doc.to_json
|
24
|
+
resp_json = @resource[@@roots[type]].post(doc_json,
|
25
|
+
:content_type =>
|
26
|
+
'application/octet-stream')
|
27
|
+
resp = JSON.parse resp_json
|
28
|
+
return resp
|
29
|
+
end
|
30
|
+
|
31
|
+
def get type, docid
|
32
|
+
resp_json = @resource[@@roots[type] + '/' + docid].get
|
33
|
+
resp = JSON.parse resp_json
|
34
|
+
return resp
|
35
|
+
end
|
36
|
+
|
37
|
+
def attach docid, name, data
|
38
|
+
resp_json = @resource[@@roots[:script] + '/' + docid + '/' + name].put data
|
39
|
+
resp = JSON.parse resp_json
|
40
|
+
return resp
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete type, docid
|
44
|
+
resp_json = @resource[@@roots[type] + '/' + docid].delete
|
45
|
+
resp = JSON.parse resp_json
|
46
|
+
return resp
|
47
|
+
end
|
48
|
+
|
49
|
+
def list type
|
50
|
+
resp_json = @resource[@@roots[type] + '/'].get
|
51
|
+
resp = JSON.parse resp_json
|
52
|
+
return resp
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support/core_ext/object' # for .blank?
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'saucelabs_adapter')
|
5
|
+
SELENIUM_YML_FIXTURE_FILE = File.join(File.dirname(__FILE__), 'fixtures', 'selenium.yml')
|
6
|
+
|
7
|
+
# Doing this to capture args because I seriously doubt we can mock out .new()
|
8
|
+
module Selenium
|
9
|
+
module Client
|
10
|
+
class Driver
|
11
|
+
attr_reader :args
|
12
|
+
def initialize(args)
|
13
|
+
@args = args
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "SeleniumConfig" do
|
20
|
+
|
21
|
+
context "given a local configuration" do
|
22
|
+
before do
|
23
|
+
@selenium_config = SaucelabsAdapter::SeleniumConfig.new('local', SELENIUM_YML_FIXTURE_FILE)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#start_sauce_tunnel?" do
|
27
|
+
it "should return false" do
|
28
|
+
@selenium_config.start_sauce_tunnel?.should be_false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "selenium_browser_key" do
|
33
|
+
it "should contain just the string from the yml file" do
|
34
|
+
@selenium_config.selenium_browser_key.should == "*chrome /Applications/Firefox.app/Contents/MacOS/firefox-bin"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#configure_polonium" do
|
39
|
+
before do
|
40
|
+
@polonium_configuration = mock("Polonium::Configuration")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should call the appropriate configuration methods on the polonium configuration object" do
|
44
|
+
@polonium_configuration.should_receive(:'selenium_server_host=').with("127.0.0.1")
|
45
|
+
@polonium_configuration.should_receive(:'selenium_server_port=').with("4444")
|
46
|
+
@polonium_configuration.should_receive(:'browser=').with(@selenium_config.selenium_browser_key)
|
47
|
+
@polonium_configuration.should_receive(:'external_app_server_host=').with("127.0.0.1")
|
48
|
+
@polonium_configuration.should_receive(:'external_app_server_port=').with("4000")
|
49
|
+
|
50
|
+
@selenium_config.configure_polonium(@polonium_configuration)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#configure_webrat" do
|
55
|
+
before do
|
56
|
+
@webrat_configuration = mock("Webrat::Configuration")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should call the appropriate configuration methods on the webrat configuration object" do
|
60
|
+
@webrat_configuration.should_receive(:'selenium_server_address=').with("127.0.0.1")
|
61
|
+
@webrat_configuration.should_receive(:'selenium_server_port=').with("4444")
|
62
|
+
@webrat_configuration.should_receive(:'selenium_browser_key=').with(@selenium_config.selenium_browser_key)
|
63
|
+
@webrat_configuration.should_receive(:'application_address=').with("127.0.0.1")
|
64
|
+
@webrat_configuration.should_receive(:'application_port=').with("4000")
|
65
|
+
|
66
|
+
@selenium_config.configure_webrat(@webrat_configuration)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "given a saucelabs/firefix/linux configuration" do
|
72
|
+
before do
|
73
|
+
@selenium_config = SaucelabsAdapter::SeleniumConfig.new('stanza_saucelabs_firefox_linux_saucetunnel', SELENIUM_YML_FIXTURE_FILE)
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#start_sauce_tunnel?" do
|
77
|
+
it "should return true" do
|
78
|
+
@selenium_config.start_sauce_tunnel?.should be_true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "selenium_browser_key" do
|
83
|
+
before do
|
84
|
+
@browser_data = JSON.parse(@selenium_config.selenium_browser_key)
|
85
|
+
end
|
86
|
+
|
87
|
+
{
|
88
|
+
'username' => "YOUR-SAUCELABS-USERNAME",
|
89
|
+
'access-key' => "YOUR-SAUCELABS-ACCESS-KEY",
|
90
|
+
'os' => "Linux",
|
91
|
+
'browser' => "firefox",
|
92
|
+
'browser-version' => "3.",
|
93
|
+
'max-duration' => 1234
|
94
|
+
}.each do |browser_data_key, browser_data_value|
|
95
|
+
it "should contain a #{browser_data_key} of #{browser_data_value}" do
|
96
|
+
@browser_data[browser_data_key].should == browser_data_value
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should contain a job_name of our hostname" do
|
101
|
+
@browser_data['job-name'].should == Socket.gethostname
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#configure_polonium" do
|
106
|
+
before do
|
107
|
+
@polonium_configuration = mock("Polonium::Configuration")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should call the appropriate configuration methods on the polonium configuration object" do
|
111
|
+
@polonium_configuration.should_receive(:'selenium_server_host=').with("saucelabs.com")
|
112
|
+
@polonium_configuration.should_receive(:'selenium_server_port=').with("4444")
|
113
|
+
@polonium_configuration.should_receive(:'browser=').with(@selenium_config.selenium_browser_key)
|
114
|
+
@polonium_configuration.should_receive(:'external_app_server_host=').with(@selenium_config.application_address)
|
115
|
+
@polonium_configuration.should_receive(:'external_app_server_port=').with("80")
|
116
|
+
|
117
|
+
@selenium_config.configure_polonium(@polonium_configuration)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#configure_webrat" do
|
122
|
+
before do
|
123
|
+
@webrat_configuration = mock("Webrat::Configuration")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should call the appropriate configuration methods on the webrat configuration object" do
|
127
|
+
@webrat_configuration.should_receive(:'selenium_server_address=').with("saucelabs.com")
|
128
|
+
@webrat_configuration.should_receive(:'selenium_server_port=').with("4444")
|
129
|
+
@webrat_configuration.should_receive(:'selenium_browser_key=').with(@selenium_config.selenium_browser_key)
|
130
|
+
@webrat_configuration.should_receive(:'application_address=').with(@selenium_config.application_address)
|
131
|
+
@webrat_configuration.should_receive(:'application_port=').with("80")
|
132
|
+
|
133
|
+
@selenium_config.configure_webrat(@webrat_configuration)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#create_driver" do
|
138
|
+
before do
|
139
|
+
@driver = @selenium_config.create_driver
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should call Driver.new with the correct arguments" do
|
143
|
+
@driver.args[:host].should == 'saucelabs.com'
|
144
|
+
@driver.args[:port].should == '4444'
|
145
|
+
@driver.args[:browser].should_not be_blank
|
146
|
+
@driver.args[:url].should == "http://#{@selenium_config.application_address}:80"
|
147
|
+
@driver.args[:timeout_in_seconds].should == 600
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSaucelabsAdapter < Test::Unit::TestCase
|
4
|
+
should "test happy paths" do
|
5
|
+
flunk "Practically, it's usually not useful to unit test stuff like saucelabs adapter. You just end up " +
|
6
|
+
"debugging the implementation and making the tests match. We really should have some happy path tests " +
|
7
|
+
"run under CI which run some dummy happy-path integration tests against the real sauce environment. " +
|
8
|
+
"Unfortunately, we don't have those. Yet."
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saucelabs-adapter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kelly Felkins, Chad Woolley & Sam Pierson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-18 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rest-client
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: net-ssh
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.12
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: net-ssh-gateway
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.1
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: selenium-client
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.17
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: lsof
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.3.0
|
64
|
+
version:
|
65
|
+
description: "This gem augments Test::Unit and Polonium/Webrat to run Selenium tests in the cloud. "
|
66
|
+
email: pair+kelly+sam@pivotallabs.com
|
67
|
+
executables: []
|
68
|
+
|
69
|
+
extensions: []
|
70
|
+
|
71
|
+
extra_rdoc_files:
|
72
|
+
- LICENSE
|
73
|
+
- README.markdown
|
74
|
+
files:
|
75
|
+
- LICENSE
|
76
|
+
- Rakefile
|
77
|
+
- VERSION
|
78
|
+
- generators/saucelabs_adapter/saucelabs_adapter_generator.rb
|
79
|
+
- generators/saucelabs_adapter/templates/jsunit.rake
|
80
|
+
- generators/saucelabs_adapter/templates/jsunit_suite_example.rb
|
81
|
+
- generators/saucelabs_adapter/templates/saucelabs_adapter.rake
|
82
|
+
- generators/saucelabs_adapter/templates/selenium.yml
|
83
|
+
- lib/saucelabs-adapter.rb
|
84
|
+
- lib/saucelabs_adapter.rb
|
85
|
+
- lib/saucelabs_adapter/jsunit_selenium_support.rb
|
86
|
+
- lib/saucelabs_adapter/run_utils.rb
|
87
|
+
- lib/saucelabs_adapter/sauce_tunnel.rb
|
88
|
+
- lib/saucelabs_adapter/selenium_config.rb
|
89
|
+
- lib/saucelabs_adapter/test_unit_adapter.rb
|
90
|
+
- lib/saucerest-ruby/gateway.rb
|
91
|
+
- lib/saucerest-ruby/saucerest.rb
|
92
|
+
- README.markdown
|
93
|
+
has_rdoc: true
|
94
|
+
homepage: http://github.com/pivotal/saucelabs-adapter
|
95
|
+
licenses: []
|
96
|
+
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options:
|
99
|
+
- --charset=UTF-8
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "0"
|
107
|
+
version:
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0"
|
113
|
+
version:
|
114
|
+
requirements: []
|
115
|
+
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 1.3.5
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: Adapter for running Selenium tests using SauceLabs.com
|
121
|
+
test_files:
|
122
|
+
- spec/selenium_config_spec.rb
|
123
|
+
- test/helper.rb
|
124
|
+
- test/test_saucelabs-adapter.rb
|