saucelabs-adapter 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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