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.
@@ -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 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'saucelabs-adapter'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -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