sauce 2.5.2 → 3.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjE4ZWNmYmY5YTI3NDNjM2IzYTg3M2EwYWVmOGEwM2EzZmFiMTA3Nw==
4
+ MWU4Y2I5MTU4YTZmNGYyODc2OTFjZjFjM2U5NTI4M2VlZjgxZTlmMw==
5
5
  data.tar.gz: !binary |-
6
- NmZiN2M0NWZkYzE2NjAxMmYxZDY0NDgyYzYzNzM3OGI0YjcwNmQyMA==
6
+ ZDExNzRjOWJhZTIzZDczYjdiZDg4ZTc3YzZkZmVhZDQ1OGZkMWU5Yw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NmRiZDYxZWE0ZTIxNTg1ZTFiNTZiYWRlMDYxZTA0Yjg2MTBhN2U5ZTdlMjVh
10
- NDY3ZThkMzhlZWI4ZjNiOTdlMDBmMGM1ZTYyZTg0YTIyYjViNjRhYTZiYmYw
11
- MzQyMjVjNjZlY2FkYzhiOWZlNDE5Y2I1M2ZlZjM5Mzg0ZmQ3MTg=
9
+ YzQ0OWE1MTYyZjQzMThlMTBhMjAxZjBiZDNmYzI3Zjc3MDY3NDAxNTAwMGJm
10
+ MGYwN2RkMmYyN2RiOTRlOWMzMzI1NTBkYTAzNjBkYjY4YWVlOTkzMzdhNGYw
11
+ NzBmN2JhNWZhYWYxNjFlNTA2MDlmNWYwNzgwNzgyM2NmMTQxOGY=
12
12
  data.tar.gz: !binary |-
13
- MjExNmMxMDQxMDA0NDA5NDM0ZjhiMWI2YmUzOGVkZmE1OTY0ZWFkYTcwYWUz
14
- ODFjY2ZlMzNmY2M0YzRiNzcyMDYyOGRhY2Q0MmRhZTE4YmRiNDdjODg5YjVj
15
- ZGM5OTA4N2MzNWVlZDEzZDA2YjgyYTRkYjZkZTMzOTYwYTMwYzg=
13
+ Njk2NWFhNmJmYzA2ZDRkNWNhMTg2MDUzMGI1NzM5MjBkODBjMDg3NzRiZjA0
14
+ OTQxM2FiMGYyNTE4MTUxNWZhMzc2MzU4NTM4ZjhiZTRjMmQ3OTAyYzUyOGI2
15
+ N2VhY2U4Y2UxYTAzNTQ3OWEyNGJmNWQxNzQwZGY1ODdlNjkxYzU=
@@ -0,0 +1,19 @@
1
+ module ParallelTests
2
+ class CLI
3
+ def run_tests_in_parallel(num_processes, options)
4
+ test_results = nil
5
+
6
+ report_time_taken do
7
+ groups = @runner.tests_in_groups(options[:files], num_processes, options)
8
+ Sauce::TestBroker.test_groups = groups
9
+ report_number_of_tests(groups)
10
+
11
+ test_results = execute_in_parallel(groups, groups.size, options) do |group|
12
+ run_tests(group, Sauce::TestBroker.group_index(group), num_processes, options)
13
+ end
14
+
15
+ report_results(test_results)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ require "yaml"
2
+ require "parallel_tests/rspec/runner"
3
+
4
+ module ParallelTests
5
+ module Saucerspec
6
+ class Runner < ParallelTests::RSpec::Runner
7
+
8
+ def self.run_tests(test_files, process_number, num_processes, options)
9
+ exe = executable # expensive, so we cache
10
+ version = (exe =~ /\brspec\b/ ? 2 : 1)
11
+ cmd = [exe, options[:test_options], (rspec_2_color if version == 2), spec_opts, *test_files].compact.join(" ")
12
+ env = Sauce::TestBroker.next_environment(test_files)
13
+ env << " #{rspec_1_color}" if version == 1
14
+ options = options.merge(:env => env)
15
+ execute_command(cmd, process_number, num_processes, options)
16
+ end
17
+
18
+
19
+ def self.tests_in_groups(tests, num_groups, options={})
20
+ all_tests = super.flatten * Sauce::TestBroker.test_platforms.length
21
+ base_group_size = all_tests.length / num_groups
22
+ num_full_groups = all_tests.length - (base_group_size * num_groups)
23
+
24
+ curpos = 0
25
+ groups = []
26
+ num_groups.times do |i|
27
+ group_size = base_group_size
28
+ if i < num_full_groups
29
+ group_size += 1
30
+ end
31
+ groups << all_tests.slice(curpos, group_size)
32
+ curpos += group_size
33
+ end
34
+
35
+ groups
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/sauce.rb CHANGED
@@ -5,6 +5,8 @@ require 'sauce/client'
5
5
  require 'sauce/config'
6
6
  require 'sauce/selenium'
7
7
  require 'sauce/integrations'
8
+ require 'tasks/parallel_testing'
9
+ require 'parallel_tests/saucerspec/runner'
8
10
 
9
11
  # Ruby before 1.9.3-p382 does not handle exit codes correctly when nested
10
12
  if RUBY_VERSION == "1.9.3" && RUBY_PATCHLEVEL < 392
@@ -18,4 +20,4 @@ if RUBY_VERSION == "1.9.3" && RUBY_PATCHLEVEL < 392
18
20
  end
19
21
  end
20
22
  end
21
- end
23
+ end
@@ -4,15 +4,26 @@ require 'sauce/config'
4
4
  require 'sauce/selenium'
5
5
  require 'sauce/version'
6
6
 
7
- require 'sauce/utilities'
8
-
9
7
 
10
8
  $sauce_tunnel = nil
11
9
 
12
10
  module Sauce
13
11
  module Capybara
14
12
  def connect_tunnel(options={})
15
- Sauce::Utilities::Connect.start(options)
13
+ begin
14
+ require 'sauce/connect'
15
+ rescue LoadError
16
+ puts 'Please install the `sauce-connect` gem if you intend on using Sauce Connect with your tests!'
17
+ raise
18
+ end
19
+
20
+ unless $sauce_tunnel.nil?
21
+ return $sauce_tunnel
22
+ end
23
+ $sauce_tunnel = Sauce::Connect.new(options)
24
+ $sauce_tunnel.connect
25
+ $sauce_tunnel.wait_until_ready
26
+ $sauce_tunnel
16
27
  end
17
28
  module_function :connect_tunnel
18
29
 
@@ -84,15 +95,15 @@ module Sauce
84
95
 
85
96
  def browser
86
97
  unless existing_browser?
87
- unless @browser = rspec_browser
88
- if Sauce.get_config[:start_tunnel]
89
- Sauce::Capybara.connect_tunnel(:quiet => true)
90
- end
98
+ @browser = rspec_browser
99
+ unless @browser
91
100
 
92
101
  @browser = Sauce::Selenium2.new
93
- at_exit do
94
- finish!
95
- end
102
+ # This at_exit call is causing failed rspec tests to exit(0).
103
+ # Should remain disabled until it's fixed.
104
+ # at_exit do
105
+ # finish!
106
+ # end
96
107
  end
97
108
  end
98
109
  @browser
@@ -118,13 +129,12 @@ module Sauce
118
129
  def finish!
119
130
  @browser.quit if existing_browser?
120
131
  @browser = nil
121
- Sauce::Utilities::Connect.close
122
132
  end
123
133
 
124
134
  def render(path)
125
135
  browser.save_screenshot path
126
136
  end
127
-
137
+
128
138
  end
129
139
  end
130
140
  end
data/lib/sauce/config.rb CHANGED
@@ -28,7 +28,8 @@ module Sauce
28
28
  :job_name => "Unnamed Ruby job",
29
29
  :local_application_port => "3001",
30
30
  :capture_traffic => false,
31
- :start_tunnel => true
31
+ :start_tunnel => true,
32
+ :start_local_application => true
32
33
  }
33
34
 
34
35
  ENVIRONMENT_VARIABLES = %w{SAUCE_HOST SAUCE_PORT SAUCE_BROWSER_URL SAUCE_USERNAME
@@ -119,6 +120,12 @@ module Sauce
119
120
  end
120
121
 
121
122
  def browsers
123
+ if @undefaulted_opts[:browser]
124
+ # If a specific browser was requested, ignore :browsers and
125
+ # use that one. This allows a setup with :browsers to launch
126
+ # sub-processes pointed just at each browser in the list.
127
+ return [[os, browser, browser_version]]
128
+ end
122
129
  return @opts[:browsers] if @opts.include? :browsers
123
130
  return [[os, browser, browser_version]]
124
131
  end
@@ -127,7 +134,7 @@ module Sauce
127
134
  if @undefaulted_opts[:browser]
128
135
  return @undefaulted_opts[:browser]
129
136
  end
130
- if @opts[:browsers]
137
+ if !ENV["TEST_ENV_NUMBER"] && @opts[:browsers]
131
138
  @opts[:browsers][0][1]
132
139
  else
133
140
  @opts[:browser]
@@ -138,7 +145,7 @@ module Sauce
138
145
  if @undefaulted_opts[:os]
139
146
  return @undefaulted_opts[:os]
140
147
  end
141
- if @opts[:browsers]
148
+ if !ENV["TEST_ENV_NUMBER"] && @opts[:browsers]
142
149
  @opts[:browsers][0][0]
143
150
  else
144
151
  @opts[:os]
@@ -149,7 +156,7 @@ module Sauce
149
156
  if @undefaulted_opts[:browser_version]
150
157
  return @undefaulted_opts[:browser_version]
151
158
  end
152
- if @opts[:browsers]
159
+ if !ENV["TEST_ENV_NUMBER"] && @opts[:browsers]
153
160
  @opts[:browsers][0][2]
154
161
  else
155
162
  @opts[:browser_version]
@@ -267,7 +274,11 @@ module Sauce
267
274
  opts[:os] = env['SAUCE_OS']
268
275
  opts[:browser] = env['SAUCE_BROWSER']
269
276
  opts[:browser_version] = env['SAUCE_BROWSER_VERSION']
277
+
270
278
  opts[:job_name] = env['SAUCE_JOB_NAME'] || env['JOB_NAME']
279
+ opts[:build] = (env['BUILD_NUMBER'] ||
280
+ env['TRAVIS_BUILD_NUMBER'] ||
281
+ env['CIRCLE_BUILD_NUM'])
271
282
 
272
283
  opts[:firefox_profile_url] = env['SAUCE_FIREFOX_PROFILE_URL']
273
284
  opts[:user_extensions_url] = env['SAUCE_USER_EXTENSIONS_URL']
@@ -19,11 +19,12 @@ begin
19
19
  config = Sauce::Config.new
20
20
  if @@need_tunnel
21
21
  if config[:application_host]
22
- @@tunnel = Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
22
+ @@tunnel = Sauce::Connect.new(:host => config[:application_host], :port => config[:application_port] || 80)
23
23
  @@tunnel.connect
24
24
  @@tunnel.wait_until_ready
25
25
  end
26
- if Sauce::Utilities::RailsServer.is_rails_app?
26
+ if config[:start_local_application] &&
27
+ Sauce::Utilities::RailsServer.is_rails_app?
27
28
  @@server = Sauce::Utilities::RailsServer.new
28
29
  @@server.start
29
30
  end
@@ -101,14 +102,18 @@ begin
101
102
 
102
103
  config = Sauce::Config.new
103
104
  if config[:application_host]
104
- @@tunnel ||= Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
105
+ @@tunnel ||= Sauce::Connect.new(:host => config[:application_host], :port => config[:application_port] || 80)
105
106
  @@tunnel.connect
106
107
  @@tunnel.wait_until_ready
107
108
  end
108
109
 
109
- if Sauce::Utilities::RailsServer.is_rails_app?
110
- @@server = Sauce::Utilities::RailsServer.new
111
- @@server.start
110
+ if config[:start_local_application] &&
111
+ Sauce::Utilities::RailsServer.is_rails_app?
112
+ # Start the app before the tests if this is a parallel run
113
+ if ENV["TEST_ENV_NUMBER"].nil?
114
+ @@server = Sauce::Utilities::RailsServer.new
115
+ @@server.start
116
+ end
112
117
  end
113
118
  end
114
119
 
@@ -120,14 +125,18 @@ begin
120
125
  if config[:application_host]
121
126
  need_tunnel = files_to_run.any? {|file| file =~ /spec\/selenium\//}
122
127
  end
123
- if need_tunnel
124
- @@tunnel ||= Sauce::Connect.new(:host => config.application_host, :port => config.application_port || 80)
128
+
129
+ if need_tunnel || config[:start_tunnel]
130
+ @@tunnel ||= Sauce::Connect.new(:host => config[:application_host], :port => config[:application_port] || 80)
125
131
  @@tunnel.connect
126
132
  @@tunnel.wait_until_ready
127
133
  end
128
134
 
129
- if files_to_run.any? {|file| file =~ /spec\/selenium\//} &&
135
+ if config[:start_local_application] &&
136
+ files_to_run.any? {|file| file =~ /spec\/selenium\//} &&
130
137
  Sauce::Utilities::RailsServer.is_rails_app?
138
+ ## Only open the tunnel once.
139
+ ## TODO: Why is this here? It's above, also
131
140
  @@server = Sauce::Utilities::RailsServer.new
132
141
  @@server.start
133
142
  end
@@ -163,13 +172,14 @@ module Sauce
163
172
  config = Sauce::Config.new
164
173
  if config[:application_host]
165
174
  unless ENV['TEST_ENV_NUMBER'].to_i > 1
166
- Sauce::Connect.ensure_connected(:host => config.application_host, :port => config.application_port || 80)
175
+ Sauce::Connect.ensure_connected(:host => config[:application_host], :port => config[:application_port] || 80)
167
176
  end
168
177
  end
169
178
 
170
179
  unless defined?(@@server)
171
180
  unless ENV['TEST_ENV_NUMBER'].to_i > 1
172
- if Sauce::Utilities::RailsServer.is_rails_app?
181
+ if config[:start_local_application] &&
182
+ Sauce::Utilities::RailsServer.is_rails_app?
173
183
  @@server = Sauce::Utilities::RailsServer.new
174
184
  @@server.start
175
185
  at_exit do
@@ -0,0 +1,67 @@
1
+ require "rest-client"
2
+ require "json"
3
+ require "yaml"
4
+ require "sauce/parallel/test_group"
5
+
6
+ module Sauce
7
+ class TestBroker
8
+
9
+ def self.next_environment(group)
10
+ unless test_groups.has_key? group
11
+ test_groups[group] = TestGroup.new(self.test_platforms)
12
+ end
13
+
14
+ test_groups[group].next_platform
15
+ end
16
+
17
+ def self.test_groups
18
+ @groups ||= {}
19
+ end
20
+
21
+ def self.test_groups=(groups)
22
+ @groups = groups.reduce({}) do |hash, g|
23
+ hash[g] = TestGroup.new(self.test_platforms)
24
+ hash
25
+ end
26
+
27
+ @group_indexes = groups.uniq.reduce({}) do |rh, g|
28
+ rh[g] =(groups.each_index.select {|i| groups[i] == g})
29
+ rh
30
+ end
31
+ end
32
+
33
+ def self.group_index(group)
34
+ @group_indexes[group].shift
35
+ end
36
+
37
+ def self.test_platforms
38
+ unless defined? @@platforms
39
+ load_sauce_config
40
+ brokers = Sauce.get_config
41
+ @@platforms ||= brokers[:browsers]
42
+ end
43
+ @@platforms
44
+ end
45
+
46
+ def self.concurrencies
47
+ response = RestClient.get "#{rest_jobs_url}/#{SAUCE_USERNAME}/limits"
48
+ res = JSON.parse(response)["concurrency"]
49
+ end
50
+
51
+ def self.rest_jobs_url
52
+ "https://#{AUTH_DETAILS}@saucelabs.com/rest/v1"
53
+ end
54
+
55
+ def self.load_sauce_config
56
+ if File.exists? "./spec/sauce_helper.rb"
57
+ require "./spec/sauce_helper"
58
+ else
59
+ require "./spec/spec_helper"
60
+ end
61
+ end
62
+
63
+ SAUCE_USERNAME = ENV["SAUCE_USERNAME"]
64
+ SAUCE_ACCESS_KEY = ENV["SAUCE_ACCESS_KEY"]
65
+ AUTH_DETAILS = "#{SAUCE_USERNAME}:#{SAUCE_ACCESS_KEY}"
66
+ end
67
+ end
@@ -0,0 +1,22 @@
1
+ module Sauce
2
+ class TestGroup
3
+ def initialize(platforms)
4
+ @platforms = platforms
5
+ @index = 0
6
+ end
7
+
8
+ def next_platform
9
+ platform = @platforms[@index]
10
+ begin
11
+ @index = @index + 1
12
+ {
13
+ :SAUCE_OS => "'#{platform[0]}'",
14
+ :SAUCE_BROWSER => "'#{platform[1]}'",
15
+ :SAUCE_BROWSER_VERSION => "'#{platform[2]}'"
16
+ }
17
+ rescue NoMethodError => e
18
+ puts "I don't have any config"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -31,39 +31,6 @@ module Sauce
31
31
  end
32
32
  end
33
33
 
34
- class Connect
35
-
36
- def self.start(options={})
37
- begin
38
- require "sauce/connect"
39
- rescue LoadError => e
40
- STDERR.puts <<-ERROR
41
- Please install the `sauce-connect` gem if you intend on using Sauce Connect with your tests!
42
-
43
- If you don't wish to use Sauce Connect, set [:start_tunnel] to false:
44
- Sauce.config do |config|
45
- config[:start_tunnel] = false
46
- end
47
- ERROR
48
- exit(1)
49
- end
50
-
51
- unless @tunnel
52
- @tunnel = Sauce::Connect.new options
53
- @tunnel.connect
54
- @tunnel.wait_until_ready
55
- end
56
- @tunnel
57
- end
58
-
59
- def self.close
60
- if @tunnel
61
- @tunnel.disconnect
62
- @tunnel = nil
63
- end
64
- end
65
- end
66
-
67
34
  class RailsServer
68
35
  include Sauce::Utilities
69
36
 
@@ -72,16 +39,32 @@ If you don't wish to use Sauce Connect, set [:start_tunnel] to false:
72
39
  end
73
40
 
74
41
  def start
75
- STDERR.puts "Starting Rails server on port 3001..."
42
+ port = 3001
43
+
44
+ if ENV["TEST_ENV_NUMBER"]
45
+ @test_env = ENV["TEST_ENV_NUMBER"].to_i
46
+ port = port + @test_env
47
+ end
48
+
49
+ STDERR.puts "Starting Rails server on port #{port}..."
50
+
76
51
  if File.exists?('script/server')
77
- @server = ChildProcess.build("ruby", "script/server", "-e", "test", "--port", "3001")
52
+ @process_args = ["ruby", "script/server", "-e", "test", "--port", "#{port}"]
53
+ #@server = ChildProcess.build("ruby", "script/server", "-e", "test", "--port", "#{port}")
78
54
  elsif File.exists?('script/rails')
79
- @server = ChildProcess.build("bundle", "exec", "rails", "server", "-e", "test", "--port", "3001")
55
+ @process_args = ["bundle", "exec", "rails", "server", "-e", "test", "--port", "#{port}"]
56
+ #@server = ChildProcess.build("bundle", "exec", "rails", "server", "-e", "test", "--port", "#{port}")
80
57
  end
58
+
59
+ if @test_env
60
+ @process_args.push *["--pid", "#{Dir.pwd}/tmp/pids/server-#{@test_env}"]
61
+ end
62
+
63
+ @server = ChildProcess.build *@process_args
81
64
  @server.io.inherit!
82
65
  @server.start
83
66
 
84
- wait_for_server_on_port(3001)
67
+ wait_for_server_on_port(port)
85
68
 
86
69
  at_exit do
87
70
  @server.stop(3, "INT")
data/lib/sauce/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Sauce
2
- MAJOR_VERSION = '2.5'
3
- PATCH_VERSION = '2'
2
+ MAJOR_VERSION = '3.0'
3
+ PATCH_VERSION = '0.beta.2'
4
4
 
5
5
  def version
6
6
  "#{MAJOR_VERSION}.#{PATCH_VERSION}"
@@ -0,0 +1,62 @@
1
+ require "sauce/parallel/test_broker"
2
+ require "parallel_tests"
3
+ require "parallel_tests/tasks"
4
+ require "parallel_tests/cli_patch"
5
+
6
+ namespace :sauce do
7
+ task :spec, :arg1 do |t, args|
8
+
9
+ ::RSpec::Core::Runner.disable_autorun!
10
+
11
+ args.with_defaults(:arg1 => [Sauce::TestBroker.concurrencies, 20].min)
12
+ concurrency = args[:arg1]
13
+ ParallelTests::CLI.new.run(["--type", "saucerspec",
14
+ "-n", "#{concurrency}",
15
+ "spec"])
16
+ end
17
+
18
+ task :install => :create_helper do
19
+ spec_helper_path = "spec/spec_helper.rb"
20
+ unless File.open(spec_helper_path) { |f| f.read.match "require \"sauce_helper\""}
21
+ File.open("spec/spec_helper.rb", "a") do |f|
22
+ f.write "require \"sauce_helper\""
23
+ end
24
+ else
25
+ puts "WARNING - The Sauce gem is already integrated into your rspec setup"
26
+ end
27
+ puts <<-ENDLINE
28
+ The Sauce gem is now installed!
29
+
30
+ Next steps:
31
+
32
+ 1. Edit spec/sauce_helper.rb with your required platforms
33
+ 2. Make sure we've not mangled your spec/spec_helper.rb requiring sauce_helper
34
+ 3. Set the SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables
35
+ 3. Run your tests with 'rake sauce:spec'
36
+
37
+ ENDLINE
38
+ end
39
+
40
+ task :create_helper do
41
+ sauce_helper_path = "spec/sauce_helper.rb"
42
+ unless File.exists? sauce_helper_path
43
+ File.open(sauce_helper_path, "w") do |f|
44
+ f.write (<<-ENDFILE
45
+ # You should edit this file with the browsers you wish to use
46
+ # For options, check out http://saucelabs.com/platforms
47
+ require "sauce"
48
+
49
+ Sauce.config do |config|
50
+ config[:browsers] = [
51
+ ["OS", "BROWSER", "VERSION"],
52
+ ["OS", "BROWSER", "VERSION"]
53
+ ]
54
+ end
55
+ ENDFILE
56
+ )
57
+ end
58
+ else
59
+ STDERR.puts "WARNING - sauce_helper has already been created."
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ require "sauce"
2
+ require "sauce/connect"
3
+
4
+ Sauce.config do |c|
5
+ c[:start_tunnel] = true
6
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe "Sauce::Config" do
4
+ it "should start Connect when start_tunnel is set" do
5
+ Sauce::RSpec::SeleniumExampleGroup.class_variable_defined?(:@@tunnel).should be_true
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require "rspec"
2
+ require "sauce"
3
+ require "parallel_tests"
4
+
5
+ describe "Sauce Rspec Runner" do
6
+ describe "#self.tests_in_groups" do
7
+ it "should return a group for every environment" do
8
+ Sauce.config do |c|
9
+ c.browsers = [
10
+ ["Windows 7", "Opera", "10"],
11
+ ["Linux", "Firefox", "19"],
12
+ ["Windows 8", "Chrome", ""]
13
+ ]
14
+ end
15
+
16
+ ParallelTests::Test::Runner.stub(:tests_in_groups).with(anything, anything, anything) {
17
+ ["spec/one_spec", "spec/two_spec"]
18
+ }
19
+ test_groups = ParallelTests::Saucerspec::Runner.tests_in_groups ["spec/one_spec.rb"], "3"
20
+ test_groups.length.should eq 6
21
+ end
22
+ end
23
+ end
@@ -3,12 +3,11 @@ require 'sauce/capybara'
3
3
  require 'sauce/connect'
4
4
 
5
5
  describe Sauce::Capybara do
6
-
7
- after :each do
8
- Sauce::Utilities::Connect.instance_variable_set(:@tunnel, false)
9
- end
10
-
11
6
  describe '#connect_tunnel' do
7
+ before :each do
8
+ $sauce_tunnel = nil
9
+ end
10
+
12
11
  let(:connector) do
13
12
  connector = double()
14
13
  connector.should_receive(:connect)
@@ -16,8 +15,13 @@ describe Sauce::Capybara do
16
15
  connector
17
16
  end
18
17
 
18
+ it 'should not do anything if the sauce tunnel exists' do
19
+ $sauce_tunnel = 1337
20
+ Sauce::Capybara.connect_tunnel.should == 1337
21
+ end
22
+
19
23
  it 'should connect if the tunnel is not connected' do
20
- Sauce::Connect.should_receive(:new).with(anything).and_return(connector)
24
+ Sauce::Connect.should_receive(:new).and_return(connector)
21
25
 
22
26
  Sauce::Capybara.connect_tunnel
23
27
  end
@@ -27,6 +31,10 @@ describe Sauce::Capybara do
27
31
  hash_including(:quiet => true)).and_return(connector)
28
32
  Sauce::Capybara.connect_tunnel(:quiet => true)
29
33
  end
34
+
35
+ after :each do
36
+ $sauce_tunnel = nil
37
+ end
30
38
  end
31
39
 
32
40
  describe Sauce::Capybara::Driver do
@@ -92,6 +92,7 @@ describe Sauce::Config do
92
92
  ENV['SAUCE_OS'] = "Linux"
93
93
  ENV['SAUCE_BROWSER'] = "firefox"
94
94
  ENV['SAUCE_BROWSER_VERSION'] = "3."
95
+ ENV['BUILD_NUMBER'] = 'test env build'
95
96
 
96
97
  config = Sauce::Config.new
97
98
  browser_data = JSON.parse(config.to_browser_string)
@@ -100,7 +101,8 @@ describe Sauce::Config do
100
101
  'os' => 'Linux',
101
102
  'username' => 'test_user',
102
103
  'browser-version' => '3.',
103
- 'browser' => 'firefox'}
104
+ 'browser' => 'firefox',
105
+ 'build' => 'test env build'}
104
106
  end
105
107
 
106
108
  it 'should create a browser string from the environment set by the jenkins plugin' do
@@ -110,6 +112,7 @@ describe Sauce::Config do
110
112
  ENV['SAUCE_BROWSER'] = 'firefox'
111
113
  ENV['SAUCE_BROWSER_VERSION'] = '3.'
112
114
  ENV['SAUCE_JOB_NAME'] = 'Named Ruby Job'
115
+ ENV['BUILD_NUMBER'] = 'test env build'
113
116
 
114
117
  config = Sauce::Config.new
115
118
  browser_data = JSON.parse(config.to_browser_string)
@@ -118,7 +121,8 @@ describe Sauce::Config do
118
121
  'os' => 'Linux',
119
122
  'username' => 'test_user',
120
123
  'browser-version' => '3.',
121
- 'browser' => 'firefox'}
124
+ 'browser' => 'firefox',
125
+ 'build' => 'test env build'}
122
126
 
123
127
  end
124
128
 
@@ -127,7 +131,8 @@ describe Sauce::Config do
127
131
  :access_key => 'test_access',
128
132
  :os => 'Linux',
129
133
  :browser => 'firefox',
130
- :browser_version => '3.')
134
+ :browser_version => '3.',
135
+ :build => 'test param build')
131
136
 
132
137
  browser_data = JSON.parse(config.to_browser_string)
133
138
  browser_data.should == {'name' => 'Unnamed Ruby job',
@@ -135,12 +140,14 @@ describe Sauce::Config do
135
140
  'os' => 'Linux',
136
141
  'username' => 'test_user',
137
142
  'browser-version' => '3.',
138
- 'browser' => 'firefox'}
143
+ 'browser' => 'firefox',
144
+ 'build' => 'test param build'}
139
145
  end
140
146
 
141
147
  it 'should create a browser string with optional parameters' do
142
148
  config = Sauce::Config.new(:username => "test_user", :access_key => "test_access",
143
149
  :os => "Linux", :browser => "firefox", :browser_version => "3.",
150
+ :build => "test opt build",
144
151
  :"user-extensions-url" => "testing")
145
152
  browser_data = JSON.parse(config.to_browser_string)
146
153
  browser_data.should == {'name' => 'Unnamed Ruby job',
@@ -149,12 +156,15 @@ describe Sauce::Config do
149
156
  'username' => 'test_user',
150
157
  'browser-version' => '3.',
151
158
  'browser' => 'firefox',
152
- 'user-extensions-url' => 'testing'}
159
+ 'build' => 'test opt build',
160
+ 'user-extensions-url' => 'testing',
161
+ }
153
162
  end
154
163
 
155
164
  it 'should create a browser string with optional parameters as underscored symbols' do
156
165
  config = Sauce::Config.new(:username => "test_user", :access_key => "test_access",
157
166
  :os => "Linux", :browser => "firefox", :browser_version => "3.",
167
+ :build => "test opt build",
158
168
  :user_extensions_url => "testing")
159
169
  browser_data = JSON.parse(config.to_browser_string)
160
170
  browser_data.should == {'name' => 'Unnamed Ruby job',
@@ -163,6 +173,7 @@ describe Sauce::Config do
163
173
  'username' => 'test_user',
164
174
  'browser-version' => '3.',
165
175
  'browser' => 'firefox',
176
+ 'build' => 'test opt build',
166
177
  'user-extensions-url' => 'testing'}
167
178
  end
168
179
 
@@ -9,10 +9,6 @@ module Sauce::Capybara
9
9
  include Sauce::Capybara::Cucumber
10
10
  include Sauce::Cucumber::SpecHelper
11
11
 
12
- before :each do
13
- Sauce::Utilities::Connect.stub!(:start) {}
14
- end
15
-
16
12
  describe '#use_sauce_driver' do
17
13
  before :each do
18
14
  ::Capybara.current_driver = :test
@@ -113,53 +109,6 @@ module Sauce::Capybara
113
109
 
114
110
  end
115
111
 
116
- context "when using sauce/connect" do
117
- let(:feature) do
118
- """
119
- Feature: A dummy feature
120
- @selenium
121
- Scenario: A dummy scenario
122
- Given a scenario
123
- When I raise no exceptions
124
- """
125
- end
126
-
127
- before :each do
128
- Sauce::Utilities::Connect.rspec_reset
129
-
130
- Sauce.config do |c|
131
- c[:start_tunnel] = true
132
- end
133
- $ran_scenario = nil
134
- end
135
-
136
- after :all do
137
- Sauce::Utilities::Connect.stub!(:start) {}
138
- end
139
-
140
- it 'should have set up a tunnel' do
141
- define_steps do
142
- Given /^a scenario$/ do
143
- end
144
- When /^I raise no exceptions$/ do
145
- $ran_scenario = true
146
- end
147
- # Set up and invoke our defined Around hook
148
- Around('@selenium') do |scenario, block|
149
- # We need to fully reference the module function here due to a
150
- # change in scoping that will happen to this block courtesy of
151
- # define_steps
152
- Sauce::Capybara::Cucumber.around_hook(scenario, block)
153
- end
154
- end
155
-
156
- # Make sure we actually configure ourselves
157
- Sauce::Utilities::Connect.should_receive(:start).and_return {true}
158
- run_defined_feature feature
159
- $ran_scenario.should be true
160
- end
161
- end
162
-
163
112
  context 'with a correct scenario' do
164
113
  let(:feature) do
165
114
  """
@@ -13,7 +13,7 @@ describe Sauce::Jasmine::Driver do
13
13
  end
14
14
 
15
15
  it 'should initialize a Sauce driver' do
16
- Sauce::Selenium2.should_receive(:new).with(hash_including(:browser => browser)).and_return(true)
16
+ Sauce::Selenium2.should_receive(:new).with(anything).and_return(true)
17
17
  d = Sauce::Jasmine::Driver.new(browser, address)
18
18
  d.should_not be_nil
19
19
  end
@@ -0,0 +1,43 @@
1
+ require "rspec"
2
+ require "sauce/parallel/test_broker"
3
+
4
+ describe Sauce::TestBroker do
5
+
6
+ describe "#next_environment" do
7
+
8
+ before :all do
9
+ Sauce.config do |c|
10
+ c.browsers = [
11
+ ["Windows 7", "Opera", "10"],
12
+ ["Linux", "Firefox", "19"]
13
+ ]
14
+ end
15
+ end
16
+
17
+ it "returns the first environment for new entries" do
18
+ first_environment = Sauce::TestBroker.next_environment "spec/a_spec"
19
+ first_environment.should eq({
20
+ :SAUCE_OS => "'Windows 7'",
21
+ :SAUCE_BROWSER => "'Opera'",
22
+ :SAUCE_BROWSER_VERSION => "'10'"
23
+ })
24
+ end
25
+
26
+ it "should only return an environment once" do
27
+ Sauce::TestBroker.next_environment "spec/b_spec"
28
+ second_environment = Sauce::TestBroker.next_environment "spec/b_spec"
29
+
30
+ second_environment.should eq({
31
+ :SAUCE_OS => "'Linux'",
32
+ :SAUCE_BROWSER => "'Firefox'",
33
+ :SAUCE_BROWSER_VERSION => "'19'"
34
+ })
35
+ end
36
+ end
37
+
38
+ describe "#test_platforms" do
39
+ it "should report the same groups as configured in Sauce.config" do
40
+ Sauce::TestBroker.test_platforms.should eq Sauce.get_config.browsers
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ require "sauce"
2
+
3
+ Sauce.config do |c|
4
+ c[:browsers] = [
5
+ ["Windows 7", "Opera", 10],
6
+ ["Linux", "Firefox", 19]
7
+ ]
8
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "rspec"
2
1
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
3
2
 
4
3
  ['sauce-jasmine', 'sauce-cucumber', 'sauce-connect'].each do |gem|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sauce
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 3.0.0.beta.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Lacey
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-06-04 00:00:00.000000000 Z
16
+ date: 2013-06-02 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: capybara
@@ -29,20 +29,6 @@ dependencies:
29
29
  - - ~>
30
30
  - !ruby/object:Gem::Version
31
31
  version: 2.1.0
32
- - !ruby/object:Gem::Dependency
33
- name: rspec
34
- requirement: !ruby/object:Gem::Requirement
35
- requirements:
36
- - - ~>
37
- - !ruby/object:Gem::Version
38
- version: '2.0'
39
- type: :development
40
- prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: '2.0'
46
32
  - !ruby/object:Gem::Dependency
47
33
  name: net-http-persistent
48
34
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +155,20 @@ dependencies:
169
155
  - - ! '>='
170
156
  - !ruby/object:Gem::Version
171
157
  version: 1.5.0
158
+ - !ruby/object:Gem::Dependency
159
+ name: parallel_tests
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - '='
163
+ - !ruby/object:Gem::Version
164
+ version: 0.12.4
165
+ type: :runtime
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - '='
170
+ - !ruby/object:Gem::Version
171
+ version: 0.12.4
172
172
  - !ruby/object:Gem::Dependency
173
173
  name: sauce_whisk
174
174
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +193,8 @@ extra_rdoc_files: []
193
193
  files:
194
194
  - lib/childprocess/process.rb
195
195
  - lib/generators/sauce/install/install_generator.rb
196
+ - lib/parallel_tests/cli_patch.rb
197
+ - lib/parallel_tests/saucerspec/runner.rb
196
198
  - lib/sauce/capybara.rb
197
199
  - lib/sauce/client.rb
198
200
  - lib/sauce/config.rb
@@ -200,13 +202,18 @@ files:
200
202
  - lib/sauce/heroku.rb
201
203
  - lib/sauce/integrations.rb
202
204
  - lib/sauce/job.rb
205
+ - lib/sauce/parallel/test_broker.rb
206
+ - lib/sauce/parallel/test_group.rb
203
207
  - lib/sauce/parallel.rb
204
208
  - lib/sauce/raketasks.rb
205
209
  - lib/sauce/selenium.rb
206
210
  - lib/sauce/utilities.rb
207
211
  - lib/sauce/version.rb
208
212
  - lib/sauce.rb
213
+ - lib/tasks/parallel_testing.rb
209
214
  - spec/cucumber_helper.rb
215
+ - spec/integration/connect/spec/spec_helper.rb
216
+ - spec/integration/connect/spec/start_tunnel_spec.rb
210
217
  - spec/integration/connect_integration_spec.rb
211
218
  - spec/integration/rspec/spec/integration_spec.rb
212
219
  - spec/integration/rspec/spec/selenium/selenium_directory_spec.rb
@@ -215,14 +222,15 @@ files:
215
222
  - spec/integration/rspec/spec/tagging/selenium_tagging_spec.rb
216
223
  - spec/integration/testunit/test/capybara_integration_test.rb
217
224
  - spec/integration/testunit/test/integration_test.rb
225
+ - spec/parallel_tests/sauce_rspec_runner_spec.rb
218
226
  - spec/sauce/capybara_spec.rb
219
227
  - spec/sauce/config_spec.rb
220
228
  - spec/sauce/cucumber_spec.rb
221
229
  - spec/sauce/driver_pool_spec.rb
222
230
  - spec/sauce/jasmine_spec.rb
231
+ - spec/sauce/parallel/test_broker_spec.rb
223
232
  - spec/sauce/selenium_spec.rb
224
- - spec/sauce/test_unit_spec.rb
225
- - spec/sauce/utilities_spec.rb
233
+ - spec/sauce_helper.rb
226
234
  - spec/spec_helper.rb
227
235
  - bin/sauce
228
236
  homepage: http://github.com/sauce-labs/sauce_ruby
@@ -239,9 +247,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
239
247
  version: '0'
240
248
  required_rubygems_version: !ruby/object:Gem::Requirement
241
249
  requirements:
242
- - - ! '>='
250
+ - - ! '>'
243
251
  - !ruby/object:Gem::Version
244
- version: '0'
252
+ version: 1.3.1
245
253
  requirements: []
246
254
  rubyforge_project:
247
255
  rubygems_version: 2.0.3
@@ -250,6 +258,8 @@ specification_version: 4
250
258
  summary: A Ruby helper for running tests in Sauce Labs
251
259
  test_files:
252
260
  - spec/cucumber_helper.rb
261
+ - spec/integration/connect/spec/spec_helper.rb
262
+ - spec/integration/connect/spec/start_tunnel_spec.rb
253
263
  - spec/integration/connect_integration_spec.rb
254
264
  - spec/integration/rspec/spec/integration_spec.rb
255
265
  - spec/integration/rspec/spec/selenium/selenium_directory_spec.rb
@@ -258,12 +268,13 @@ test_files:
258
268
  - spec/integration/rspec/spec/tagging/selenium_tagging_spec.rb
259
269
  - spec/integration/testunit/test/capybara_integration_test.rb
260
270
  - spec/integration/testunit/test/integration_test.rb
271
+ - spec/parallel_tests/sauce_rspec_runner_spec.rb
261
272
  - spec/sauce/capybara_spec.rb
262
273
  - spec/sauce/config_spec.rb
263
274
  - spec/sauce/cucumber_spec.rb
264
275
  - spec/sauce/driver_pool_spec.rb
265
276
  - spec/sauce/jasmine_spec.rb
277
+ - spec/sauce/parallel/test_broker_spec.rb
266
278
  - spec/sauce/selenium_spec.rb
267
- - spec/sauce/test_unit_spec.rb
268
- - spec/sauce/utilities_spec.rb
279
+ - spec/sauce_helper.rb
269
280
  - spec/spec_helper.rb
@@ -1,8 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Sauce::Test::Unit" do
4
-
5
- it "should add a driver to the pool" do
6
-
7
- end
8
- end
@@ -1,82 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Sauce::Utilities::Connect" do
4
-
5
- before :each do
6
- @mock_tunnel = double(Sauce::Connect.new)
7
- end
8
-
9
- after :each do
10
- Sauce::Utilities::Connect.instance_variable_set(:@tunnel, nil)
11
- end
12
- describe "##start" do
13
- it "should call Sauce Connect when included" do
14
- @mock_tunnel.stub(:connect).and_return true
15
- @mock_tunnel.stub(:wait_until_ready).and_return true
16
- Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
17
- Sauce::Utilities::Connect.start
18
- end
19
-
20
- it "should throw an exception when Sauce Connect is not included" do
21
- Object.should_receive(:require).with("sauce/connect").and_raise LoadError
22
-
23
- lambda {Sauce::Utilities::Connect.start}.should raise_error SystemExit
24
- end
25
-
26
- it "should connect the new tunnel" do
27
- Sauce::Connect.rspec_reset
28
- @mock_tunnel.should_receive(:connect).with().and_return(true)
29
- @mock_tunnel.should_receive(:wait_until_ready).and_return(true)
30
-
31
- Sauce::Connect.stub!(:new).with(anything).and_return @mock_tunnel
32
-
33
- Sauce::Utilities::Connect.start
34
- end
35
-
36
- it "should return the tunnel when done" do
37
- @mock_tunnel.stub(:connect).and_return true
38
- @mock_tunnel.stub(:wait_until_ready).and_return true
39
- Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
40
- tunnel = Sauce::Utilities::Connect.start
41
- tunnel.should be @mock_tunnel
42
- end
43
-
44
- it "only opens one tunnel" do
45
- @mock_tunnel.stub(:connect).and_return true
46
- @mock_tunnel.stub(:wait_until_ready).and_return true
47
- Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
48
- tunnel = Sauce::Utilities::Connect.start
49
-
50
- tunnel_2 = Sauce::Utilities::Connect.start
51
-
52
- tunnel.should be tunnel_2
53
- end
54
- end
55
-
56
- describe "#close" do
57
- it "makes the tunnel nil when terminated" do
58
- @mock_tunnel.stub(:connect).and_return true
59
- @mock_tunnel.stub(:wait_until_ready).and_return true
60
- @mock_tunnel.should_receive(:disconnect).and_return true
61
- Sauce::Connect.stub(:new).with(anything) {@mock_tunnel}
62
- Sauce::Utilities::Connect.start
63
-
64
- Sauce::Utilities::Connect.close
65
- Sauce::Utilities::Connect.instance_variable_get(:@tunnel).should be nil
66
- end
67
-
68
- it "calls disconnect" do
69
- @mock_tunnel.stub(:connect).and_return true
70
- @mock_tunnel.stub(:wait_until_ready).and_return true
71
- @mock_tunnel.should_receive(:disconnect).and_return true
72
- Sauce::Connect.stub(:new).with(anything) {@mock_tunnel}
73
- tunnel = Sauce::Utilities::Connect.start
74
-
75
- Sauce::Utilities::Connect.close
76
- end
77
-
78
- it "does not error if no tunnel exists" do
79
- Sauce::Utilities::Connect.close
80
- end
81
- end
82
- end