sauce 0.11.3 → 0.12.0
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/README.markdown +1 -2
- data/VERSION +1 -1
- data/lib/generators/sauce_generator.rb +40 -0
- data/lib/generators/templates/sauce.rake +1 -0
- data/lib/sauce/integrations.rb +111 -7
- data/lib/sauce/raketasks.rb +44 -2
- data/lib/sauce/utilities.rb +26 -5
- metadata +7 -5
data/README.markdown
CHANGED
@@ -10,13 +10,12 @@ Current:
|
|
10
10
|
* Drop-in replacement for Selenium::Client::Driver that takes care of connecting to Sauce OnDemand
|
11
11
|
* RSpec, Test::Unit, and Rails integration for tests, including automatic setup of Sauce Connect
|
12
12
|
* ActiveRecord-like interface for tunnels and jobs: Find/create/destroy
|
13
|
+
* Start/stop local instances of Sauce RC
|
13
14
|
|
14
15
|
Planned:
|
15
16
|
|
16
|
-
* Include selenium-client RSpec/Test::Unit integration
|
17
17
|
* Webrat integration
|
18
18
|
* Extend to automatic retrieval of jobs logs, videos, reverse tunnels
|
19
|
-
* Start/stop local instances of Sauce RC
|
20
19
|
|
21
20
|
Install
|
22
21
|
-------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.12.0
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class SauceGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("../templates", __FILE__)
|
3
|
+
|
4
|
+
argument :username, :type => nil
|
5
|
+
argument :api_key, :type => nil
|
6
|
+
|
7
|
+
def copy_rake_tasks
|
8
|
+
copy_file "sauce.rake", "lib/tasks/sauce.rake"
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup_spec
|
12
|
+
if File.directory? 'spec'
|
13
|
+
empty_directory "spec/selenium"
|
14
|
+
append_file "spec/spec_helper.rb", generate_config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup_test
|
19
|
+
empty_directory "test/selenium"
|
20
|
+
append_file "test/test_helper.rb", generate_config
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def generate_config
|
26
|
+
@random_id ||= rand(100000)
|
27
|
+
return <<-CONFIG
|
28
|
+
require 'sauce'
|
29
|
+
|
30
|
+
Sauce.config do |conf|
|
31
|
+
conf.browser_url = "http://#{@random_id}.test/"
|
32
|
+
conf.browsers = [
|
33
|
+
["Windows 2003", "firefox", "3."]
|
34
|
+
]
|
35
|
+
conf.application_host = "127.0.0.1"
|
36
|
+
conf.application_port = "3001"
|
37
|
+
end
|
38
|
+
CONFIG
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'sauce/raketasks'
|
data/lib/sauce/integrations.rb
CHANGED
@@ -4,10 +4,17 @@ begin
|
|
4
4
|
module RSpec
|
5
5
|
class SeleniumExampleGroup < Spec::Example::ExampleGroup
|
6
6
|
attr_reader :selenium
|
7
|
+
@@need_tunnel = false
|
8
|
+
|
9
|
+
def self.inherited(subclass)
|
10
|
+
# only setup tunnel if somebody needs it
|
11
|
+
@@need_tunnel = true
|
12
|
+
super(subclass)
|
13
|
+
end
|
7
14
|
|
8
15
|
before :suite do
|
9
16
|
config = Sauce::Config.new
|
10
|
-
if config.application_host && !config.local?
|
17
|
+
if @@need_tunnel && config.application_host && !config.local?
|
11
18
|
@@tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
|
12
19
|
@@tunnel.wait_until_ready
|
13
20
|
end
|
@@ -46,7 +53,66 @@ begin
|
|
46
53
|
end
|
47
54
|
end
|
48
55
|
rescue LoadError
|
49
|
-
# User doesn't have RSpec installed
|
56
|
+
# User doesn't have RSpec 1.x installed
|
57
|
+
end
|
58
|
+
|
59
|
+
begin
|
60
|
+
require 'rspec'
|
61
|
+
module Sauce
|
62
|
+
module RSpec
|
63
|
+
module SeleniumExampleGroup
|
64
|
+
attr_reader :selenium
|
65
|
+
alias_method :page, :selenium
|
66
|
+
alias_method :s, :selenium
|
67
|
+
|
68
|
+
def self.included(othermod)
|
69
|
+
othermod.around do |the_test|
|
70
|
+
config = Sauce::Config.new
|
71
|
+
description = the_test.metadata[:full_description]
|
72
|
+
config.browsers.each do |os, browser, version|
|
73
|
+
if config.local?
|
74
|
+
@selenium = ::Selenium::Client::Driver.new(:host => "127.0.0.1",
|
75
|
+
:port => 4444,
|
76
|
+
:browser => "*" + browser,
|
77
|
+
:url => "http://127.0.0.1:#{config.local_application_port}/")
|
78
|
+
else
|
79
|
+
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
|
80
|
+
:job_name => "#{description}"})
|
81
|
+
end
|
82
|
+
@selenium.start
|
83
|
+
begin
|
84
|
+
the_test.run
|
85
|
+
ensure
|
86
|
+
@selenium.stop
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
::RSpec.configuration.include(self, :example_group => {
|
93
|
+
:file_path => Regexp.compile('spec[\\\/]selenium')
|
94
|
+
})
|
95
|
+
::RSpec.configuration.before :suite do
|
96
|
+
need_tunnel = false
|
97
|
+
config = Sauce::Config.new
|
98
|
+
if config.application_host && !config.local?
|
99
|
+
need_tunnel = ::RSpec.configuration.settings[:files_to_run].any? {|file| file =~ /spec\/selenium\//}
|
100
|
+
end
|
101
|
+
if need_tunnel
|
102
|
+
@@tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
|
103
|
+
@@tunnel.wait_until_ready
|
104
|
+
end
|
105
|
+
end
|
106
|
+
::RSpec.configuration.after :suite do
|
107
|
+
if defined? @@tunnel
|
108
|
+
@@tunnel.disconnect
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
rescue LoadError
|
115
|
+
# User doesn't have RSpec 2.x installed
|
50
116
|
end
|
51
117
|
|
52
118
|
begin
|
@@ -59,7 +125,12 @@ begin
|
|
59
125
|
alias_method :s, :selenium
|
60
126
|
|
61
127
|
def run(*args, &blk)
|
62
|
-
|
128
|
+
if self.respond_to? :name
|
129
|
+
my_name = self.name
|
130
|
+
else
|
131
|
+
my_name = self.__name__
|
132
|
+
end
|
133
|
+
unless my_name =~ /^default_test/
|
63
134
|
config = Sauce::Config.new
|
64
135
|
config.browsers.each do |os, browser, version|
|
65
136
|
if config.local?
|
@@ -69,7 +140,7 @@ begin
|
|
69
140
|
:url => "http://127.0.0.1:#{config.local_application_port}/")
|
70
141
|
else
|
71
142
|
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
|
72
|
-
:job_name => "#{
|
143
|
+
:job_name => "#{my_name}"})
|
73
144
|
end
|
74
145
|
@selenium.start
|
75
146
|
super(*args, &blk)
|
@@ -83,6 +154,10 @@ begin
|
|
83
154
|
end
|
84
155
|
end
|
85
156
|
end
|
157
|
+
rescue LoadError
|
158
|
+
# User doesn't have Test::Unit installed
|
159
|
+
end
|
160
|
+
begin
|
86
161
|
require 'test/unit/ui/console/testrunner'
|
87
162
|
class Test::Unit::UI::Console::TestRunner
|
88
163
|
def attach_to_mediator_with_sauce_tunnel
|
@@ -111,7 +186,31 @@ begin
|
|
111
186
|
end
|
112
187
|
end
|
113
188
|
rescue LoadError
|
114
|
-
# User
|
189
|
+
# User is on Ruby 1.9
|
190
|
+
end
|
191
|
+
|
192
|
+
begin
|
193
|
+
require 'minitest/unit'
|
194
|
+
module MiniTest
|
195
|
+
class Unit
|
196
|
+
run_without_tunnel = self.instance_method(:run)
|
197
|
+
|
198
|
+
define_method(:run) do |args|
|
199
|
+
config = Sauce::Config.new
|
200
|
+
if config.application_host && !config.local?
|
201
|
+
@sauce_tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
|
202
|
+
@sauce_tunnel.wait_until_ready
|
203
|
+
end
|
204
|
+
result = run_without_tunnel.bind(self).call(args)
|
205
|
+
if defined? @sauce_tunnel
|
206
|
+
@sauce_tunnel.disconnect
|
207
|
+
end
|
208
|
+
return result
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
rescue LoadError
|
213
|
+
# User is not on Ruby 1.9
|
115
214
|
end
|
116
215
|
|
117
216
|
if defined?(ActiveSupport::TestCase)
|
@@ -123,7 +222,12 @@ if defined?(ActiveSupport::TestCase)
|
|
123
222
|
alias_method :s, :selenium
|
124
223
|
|
125
224
|
def run(*args, &blk)
|
126
|
-
|
225
|
+
if self.respond_to? :name
|
226
|
+
my_name = self.name
|
227
|
+
else
|
228
|
+
my_name = self.__name__
|
229
|
+
end
|
230
|
+
unless my_name =~ /^default_test/
|
127
231
|
config = Sauce::Config.new
|
128
232
|
config.browsers.each do |os, browser, version|
|
129
233
|
if config.local?
|
@@ -133,7 +237,7 @@ if defined?(ActiveSupport::TestCase)
|
|
133
237
|
:url => "http://127.0.0.1:#{config.local_application_port}/")
|
134
238
|
else
|
135
239
|
@selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
|
136
|
-
:job_name => "#{
|
240
|
+
:job_name => "#{my_name}"})
|
137
241
|
end
|
138
242
|
@selenium.start
|
139
243
|
super(*args, &blk)
|
data/lib/sauce/raketasks.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require 'sauce'
|
2
2
|
|
3
|
-
spec_prereq = File.exist?(File.join(
|
3
|
+
spec_prereq = File.exist?(File.join(::Rails.root.to_s, 'config', 'database.yml')) ? "db:test:prepare" : :noop
|
4
4
|
task :noop do
|
5
5
|
end
|
6
6
|
|
7
|
+
class Rake::Task
|
8
|
+
def abandon
|
9
|
+
@actions.clear
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
include Sauce::Utilities
|
8
14
|
|
9
15
|
if defined?(Spec::Rake::SpecTask)
|
@@ -27,13 +33,49 @@ if defined?(Spec::Rake::SpecTask)
|
|
27
33
|
|
28
34
|
desc "" # Hide it from rake -T
|
29
35
|
Spec::Rake::SpecTask.new :runtests do |t|
|
30
|
-
t.spec_opts = ['--options', "\"#{
|
36
|
+
t.spec_opts = ['--options', "\"#{Rails.root.join('spec', 'spec.opts')}\""]
|
31
37
|
t.spec_files = FileList["spec/selenium/**/*_spec.rb"]
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
35
41
|
task :selenium => "selenium:sauce"
|
36
42
|
end
|
43
|
+
|
44
|
+
Rake::Task[:spec].abandon
|
45
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
46
|
+
Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t|
|
47
|
+
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
|
48
|
+
t.spec_files = FileList['spec/**/*_spec.rb'].exclude('spec/selenium/*')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if defined?(RSpec::Core::RakeTask)
|
53
|
+
namespace :spec do
|
54
|
+
namespace :selenium do
|
55
|
+
desc "Run the Selenium acceptance tests in spec/selenium using Sauce OnDemand"
|
56
|
+
task :sauce => spec_prereq do
|
57
|
+
with_rails_server do
|
58
|
+
Rake::Task["spec:selenium:runtests"].invoke
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Run the Selenium acceptance tests in spec/selenium using a local Selenium server"
|
63
|
+
task :local => spec_prereq do
|
64
|
+
with_rails_server do
|
65
|
+
with_selenium_rc do
|
66
|
+
Rake::Task["spec:selenium:runtests"].invoke
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "" # Hide it from rake -T
|
72
|
+
RSpec::Core::RakeTask.new :runtests do |t|
|
73
|
+
t.pattern = "spec/selenium/**/*_spec.rb"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
task :selenium => "selenium:sauce"
|
78
|
+
end
|
37
79
|
end
|
38
80
|
|
39
81
|
namespace :test do
|
data/lib/sauce/utilities.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'socket'
|
3
|
+
|
1
4
|
module Sauce
|
2
5
|
module Utilities
|
3
6
|
def silence_stream(stream)
|
@@ -9,6 +12,22 @@ module Sauce
|
|
9
12
|
stream.reopen(old_stream)
|
10
13
|
end
|
11
14
|
|
15
|
+
def wait_for_server_on_port(port)
|
16
|
+
while true
|
17
|
+
begin
|
18
|
+
Timeout::timeout(2) do
|
19
|
+
socket = TCPSocket.new('127.0.0.1', port)
|
20
|
+
socket.close unless socket.nil?
|
21
|
+
return
|
22
|
+
end
|
23
|
+
rescue Errno::ECONNREFUSED,
|
24
|
+
Errno::EBADF, # Windows
|
25
|
+
Timeout::Error
|
26
|
+
end
|
27
|
+
sleep 2
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
12
31
|
def with_selenium_rc
|
13
32
|
ENV['LOCAL_SELENIUM'] = "true"
|
14
33
|
STDERR.puts "Starting Selenium RC server on port 4444..."
|
@@ -16,7 +35,7 @@ module Sauce
|
|
16
35
|
server.jar_file = File.expand_path(File.dirname(__FILE__) + "/../../support/selenium-server.jar")
|
17
36
|
silence_stream(STDOUT) do
|
18
37
|
server.start :background => true
|
19
|
-
|
38
|
+
wait_for_server_on_port(4444)
|
20
39
|
end
|
21
40
|
STDERR.puts "Selenium RC running!"
|
22
41
|
begin
|
@@ -28,11 +47,13 @@ module Sauce
|
|
28
47
|
|
29
48
|
def with_rails_server
|
30
49
|
STDERR.puts "Starting Rails server on port 3001..."
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
50
|
+
if File.exists?('script/server')
|
51
|
+
server = IO.popen("ruby script/server RAILS_ENV=test --port 3001 --daemon")
|
52
|
+
elsif File.exists?('script/rails')
|
53
|
+
server = IO.popen("script/rails server -p 3001 -e test")
|
35
54
|
end
|
55
|
+
|
56
|
+
wait_for_server_on_port(3001)
|
36
57
|
STDERR.puts "Rails server running!"
|
37
58
|
begin
|
38
59
|
yield
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sauce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 47
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 12
|
9
|
+
- 0
|
10
|
+
version: 0.12.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sean Grove
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-12-
|
19
|
+
date: 2010-12-13 00:00:00 -08:00
|
20
20
|
default_executable: sauce
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -147,6 +147,8 @@ files:
|
|
147
147
|
- examples/test_saucelabs2.rb
|
148
148
|
- generators/sauce/sauce_generator.rb
|
149
149
|
- generators/sauce/templates/sauce.rake
|
150
|
+
- lib/generators/sauce_generator.rb
|
151
|
+
- lib/generators/templates/sauce.rake
|
150
152
|
- lib/sauce.rb
|
151
153
|
- lib/sauce/client.rb
|
152
154
|
- lib/sauce/config.rb
|