sauce 3.0.0.beta.2 → 3.0.0

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
- MWU4Y2I5MTU4YTZmNGYyODc2OTFjZjFjM2U5NTI4M2VlZjgxZTlmMw==
4
+ NTM3Y2Y1ZDY0MjBjZWUxYjU4YWExNTBjNDI3M2NjNjA5OWVmNjJlZA==
5
5
  data.tar.gz: !binary |-
6
- ZDExNzRjOWJhZTIzZDczYjdiZDg4ZTc3YzZkZmVhZDQ1OGZkMWU5Yw==
6
+ Yzg4ZmE2NjcyYTcyYTdmMGRlYTViYzk0YjRkMjY1ZjQ4MzZjMzMxMQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzQ0OWE1MTYyZjQzMThlMTBhMjAxZjBiZDNmYzI3Zjc3MDY3NDAxNTAwMGJm
10
- MGYwN2RkMmYyN2RiOTRlOWMzMzI1NTBkYTAzNjBkYjY4YWVlOTkzMzdhNGYw
11
- NzBmN2JhNWZhYWYxNjFlNTA2MDlmNWYwNzgwNzgyM2NmMTQxOGY=
9
+ YjZhNGY0MzA3NTU2MjI3NWFjMDMxYjBhY2ZjOWMxNDQ3M2ViNDAzZjI5YTc3
10
+ ZTNmNDJmNTg4OWQ5NWI4OTUwNGU0MTZkZmNkYjIzNDFkNzExYjVkMWQyZWFk
11
+ N2Y3NDVlNzdjOWI2NTMyMzdjNTMxNzUwOWRhNDEwMzNlZWM4NDg=
12
12
  data.tar.gz: !binary |-
13
- Njk2NWFhNmJmYzA2ZDRkNWNhMTg2MDUzMGI1NzM5MjBkODBjMDg3NzRiZjA0
14
- OTQxM2FiMGYyNTE4MTUxNWZhMzc2MzU4NTM4ZjhiZTRjMmQ3OTAyYzUyOGI2
15
- N2VhY2U4Y2UxYTAzNTQ3OWEyNGJmNWQxNzQwZGY1ODdlNjkxYzU=
13
+ MmY4MDVmODIwNDBhZjU3MzQxY2ZhODU1M2IwNDY0ZmNhZjg2MTBjZTBkZTU0
14
+ M2RlMjRlMTRjMjZjMWM1NWNiNWQ5NGE4NmNhM2I1NzdmZWQ2MmI2MGE5ZGVm
15
+ NjQ1YjA0NDdiNjIxYzlkZmU4ZTAwOWFlYWQxZDM4MWIzMzcwZTE=
@@ -0,0 +1,44 @@
1
+ require "parallel_tests/cucumber/runner"
2
+
3
+ module ParallelTests
4
+ module Saucecucumber
5
+ class Runner < ParallelTests::Cucumber::Runner
6
+
7
+ def self.run_tests(test_files, process_number, num_processes, options)
8
+ options = options.dup
9
+ sanitized_test_files = test_files.map { |val| Shellwords.escape(val) }
10
+ env = Sauce::TestBroker.next_environment(test_files)
11
+ env.merge!({"AUTOTEST" => "1"}) if $stdout.tty? # display color when we are in a terminal
12
+ options.merge!({:env => env})
13
+ runtime_logging = " --format ParallelTests::Cucumber::RuntimeLogger --out #{runtime_log}"
14
+ cmd = [
15
+ executable,
16
+ (runtime_logging if File.directory?(File.dirname(runtime_log))),
17
+ cucumber_opts(options[:test_options]),
18
+ *sanitized_test_files
19
+ ].compact.join(" ")
20
+ execute_command(cmd, process_number, num_processes, options)
21
+ end
22
+
23
+ def self.tests_in_groups(tests, num_groups, options={})
24
+ originals = (options[:group_by] == :steps) ? Grouper.by_steps(find_tests(tests, options), num_groups, options) : super
25
+ all_tests = originals.flatten * Sauce::TestBroker.test_platforms.length
26
+ base_group_size = all_tests.length / num_groups
27
+ num_full_groups = all_tests.length - (base_group_size * num_groups)
28
+
29
+ curpos = 0
30
+ groups = []
31
+ num_groups.times do |i|
32
+ group_size = base_group_size
33
+ if i < num_full_groups
34
+ group_size += 1
35
+ end
36
+ groups << all_tests.slice(curpos, group_size)
37
+ curpos += group_size
38
+ end
39
+
40
+ groups
41
+ end
42
+ end
43
+ end
44
+ end
@@ -6,13 +6,14 @@ module ParallelTests
6
6
  class Runner < ParallelTests::RSpec::Runner
7
7
 
8
8
  def self.run_tests(test_files, process_number, num_processes, options)
9
+ our_options = options.dup
9
10
  exe = executable # expensive, so we cache
10
11
  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
+ cmd = [exe, our_options[:test_options], (rspec_2_color if version == 2), spec_opts, *test_files].compact.join(" ")
12
13
  env = Sauce::TestBroker.next_environment(test_files)
13
14
  env << " #{rspec_1_color}" if version == 1
14
- options = options.merge(:env => env)
15
- execute_command(cmd, process_number, num_processes, options)
15
+ our_options.merge!(:env => env)
16
+ execute_command(cmd, process_number, num_processes, our_options)
16
17
  end
17
18
 
18
19
 
data/lib/sauce.rb CHANGED
@@ -7,6 +7,7 @@ require 'sauce/selenium'
7
7
  require 'sauce/integrations'
8
8
  require 'tasks/parallel_testing'
9
9
  require 'parallel_tests/saucerspec/runner'
10
+ require 'parallel_tests/saucecucumber/runner'
10
11
 
11
12
  # Ruby before 1.9.3-p382 does not handle exit codes correctly when nested
12
13
  if RUBY_VERSION == "1.9.3" && RUBY_PATCHLEVEL < 392
@@ -9,24 +9,6 @@ $sauce_tunnel = nil
9
9
 
10
10
  module Sauce
11
11
  module Capybara
12
- def connect_tunnel(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
27
- end
28
- module_function :connect_tunnel
29
-
30
12
  class Driver < ::Capybara::Selenium::Driver
31
13
  RETRY_ON = [::Selenium::WebDriver::Error::UnhandledError,
32
14
  ::Selenium::WebDriver::Error::UnknownError]
@@ -99,11 +81,9 @@ module Sauce
99
81
  unless @browser
100
82
 
101
83
  @browser = Sauce::Selenium2.new
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
84
+ at_exit do
85
+ finish!
86
+ end
107
87
  end
108
88
  end
109
89
  @browser
data/lib/sauce/config.rb CHANGED
@@ -74,6 +74,10 @@ module Sauce
74
74
  @opts[key] = value
75
75
  end
76
76
 
77
+ def has_key?(key)
78
+ @opts.has_key? key
79
+ end
80
+
77
81
  def silence_warnings
78
82
  false
79
83
  end
@@ -130,6 +134,16 @@ module Sauce
130
134
  return [[os, browser, browser_version]]
131
135
  end
132
136
 
137
+ def browsers_for_file(file)
138
+ if @opts[:perfile_browsers]
139
+ @opts[:perfile_browsers][file].map do |h|
140
+ [h['os'], h['browser'], h['version']]
141
+ end
142
+ else
143
+ browsers
144
+ end
145
+ end
146
+
133
147
  def browser
134
148
  if @undefaulted_opts[:browser]
135
149
  return @undefaulted_opts[:browser]
@@ -264,39 +278,38 @@ module Sauce
264
278
 
265
279
  def extract_options_from_hash(env)
266
280
  opts = {}
267
- opts[:host] = env['SAUCE_HOST']
268
- opts[:port] = env['SAUCE_PORT']
269
- opts[:browser_url] = env['SAUCE_BROWSER_URL']
270
281
 
271
- opts[:username] = env['SAUCE_USERNAME'] || env['SAUCE_USER_NAME']
272
- opts[:access_key] = env['SAUCE_ACCESS_KEY'] || env['SAUCE_API_KEY']
282
+ on_demand = env.delete "SAUCE_ONDEMAND_BROWSERS"
283
+ env_browsers = env.delete "SAUCE_BROWSERS"
273
284
 
274
- opts[:os] = env['SAUCE_OS']
275
- opts[:browser] = env['SAUCE_BROWSER']
276
- opts[:browser_version] = env['SAUCE_BROWSER_VERSION']
285
+ env.select {|k,v| k.start_with? "SAUCE_"}.each do |k,v|
286
+ opts[k.downcase.sub("sauce_", "").to_sym] = v
287
+ end
277
288
 
278
289
  opts[:job_name] = env['SAUCE_JOB_NAME'] || env['JOB_NAME']
279
- opts[:build] = (env['BUILD_NUMBER'] ||
290
+ opts[:build] = (env['BUILD_TAG'] ||
291
+ env['BUILD_NUMBER'] ||
280
292
  env['TRAVIS_BUILD_NUMBER'] ||
281
293
  env['CIRCLE_BUILD_NUM'])
282
294
 
283
- opts[:firefox_profile_url] = env['SAUCE_FIREFOX_PROFILE_URL']
284
- opts[:user_extensions_url] = env['SAUCE_USER_EXTENSIONS_URL']
285
-
286
295
  if env.include? 'URL'
287
296
  opts['SAUCE_BROWSER_URL'] = "http://#{env['URL']}/"
288
297
  end
289
298
 
290
- if env.include? 'SAUCE_ONDEMAND_BROWSERS'
291
- browsers = JSON.parse(env['SAUCE_ONDEMAND_BROWSERS'])
299
+ if on_demand
300
+ browsers = JSON.parse(on_demand)
292
301
  opts[:browsers] = browsers.map { |x| [x['os'], x['browser'], x['browser-version']] }
293
302
  end
294
303
 
295
- if env.include? 'SAUCE_BROWSERS'
296
- browsers = JSON.parse(env['SAUCE_BROWSERS'])
304
+ if env_browsers
305
+ browsers = JSON.parse(env_browsers)
297
306
  opts[:browsers] = browsers.map { |x| [x['os'], x['browser'], x['version']] }
298
307
  end
299
308
 
309
+ if env.include? 'SAUCE_PERFILE_BROWSERS'
310
+ opts[:perfile_browsers] = JSON.parse(env['SAUCE_PERFILE_BROWSERS'])
311
+ end
312
+
300
313
  return opts.delete_if {|key, value| value.nil?}
301
314
  end
302
315
  end
@@ -19,9 +19,7 @@ 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)
23
- @@tunnel.connect
24
- @@tunnel.wait_until_ready
22
+ Sauce::Utilities::Connect.start(:host => config[:application_host], :port => config[:application_port] || 80)
25
23
  end
26
24
  if config[:start_local_application] &&
27
25
  Sauce::Utilities::RailsServer.is_rails_app?
@@ -32,7 +30,7 @@ begin
32
30
  end
33
31
 
34
32
  after :suite do
35
- @@tunnel.disconnect if defined? @@tunnel
33
+ Sauce::Utilities::Connect.close
36
34
  @@server.stop if defined? @@server
37
35
  end
38
36
 
@@ -75,7 +73,8 @@ begin
75
73
  othermod.around do |the_test|
76
74
  config = Sauce::Config.new
77
75
  description = the_test.metadata[:full_description]
78
- config.browsers.each do |os, browser, version|
76
+ file = the_test.metadata[:file_path]
77
+ config.browsers_for_file(file).each do |os, browser, version|
79
78
  @selenium = Sauce::Selenium2.new({:os => os,
80
79
  :browser => browser,
81
80
  :browser_version => version,
@@ -102,9 +101,7 @@ begin
102
101
 
103
102
  config = Sauce::Config.new
104
103
  if config[:application_host]
105
- @@tunnel ||= Sauce::Connect.new(:host => config[:application_host], :port => config[:application_port] || 80)
106
- @@tunnel.connect
107
- @@tunnel.wait_until_ready
104
+ Sauce::Utilities::Connect.start(:host => config[:application_host], :port => config[:application_port] || 80)
108
105
  end
109
106
 
110
107
  if config[:start_local_application] &&
@@ -127,9 +124,7 @@ begin
127
124
  end
128
125
 
129
126
  if need_tunnel || config[:start_tunnel]
130
- @@tunnel ||= Sauce::Connect.new(:host => config[:application_host], :port => config[:application_port] || 80)
131
- @@tunnel.connect
132
- @@tunnel.wait_until_ready
127
+ Sauce::Utilities::Connect.start(:host => config[:application_host], :port => config[:application_port] || 80)
133
128
  end
134
129
 
135
130
  if config[:start_local_application] &&
@@ -142,7 +137,7 @@ begin
142
137
  end
143
138
  end
144
139
  ::RSpec.configuration.after :suite do
145
- @@tunnel.disconnect if defined? @@tunnel
140
+ Sauce::Utilities::Connect.close
146
141
  @@server.stop if defined? @@server
147
142
  end
148
143
  end
@@ -2,16 +2,34 @@ require "rest-client"
2
2
  require "json"
3
3
  require "yaml"
4
4
  require "sauce/parallel/test_group"
5
+ require "thread"
5
6
 
6
7
  module Sauce
7
8
  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)
9
+
10
+ def self.reset
11
+ if defined? @@platforms
12
+ remove_class_variable(:@@platforms)
12
13
  end
14
+ @groups = {}
15
+ end
13
16
 
14
- test_groups[group].next_platform
17
+ def self.environment_mutex
18
+ @@m ||= Mutex.new
19
+ end
20
+
21
+ def self.next_environment(group)
22
+ environment_mutex.synchronize do
23
+ browsers = {}
24
+ group.each do |file|
25
+ file = "./" + file
26
+ test_groups[file] ||= TestGroup.new(self.test_platforms)
27
+ browsers[file] ||= []
28
+ browsers[file] << test_groups[file].next_platform
29
+ end
30
+
31
+ return {:SAUCE_PERFILE_BROWSERS => "'" + JSON.generate(browsers) + "'"}
32
+ end
15
33
  end
16
34
 
17
35
  def self.test_groups
@@ -37,8 +55,7 @@ module Sauce
37
55
  def self.test_platforms
38
56
  unless defined? @@platforms
39
57
  load_sauce_config
40
- brokers = Sauce.get_config
41
- @@platforms ||= brokers[:browsers]
58
+ @@platforms ||= Sauce.get_config[:browsers]
42
59
  end
43
60
  @@platforms
44
61
  end
@@ -53,11 +70,25 @@ module Sauce
53
70
  end
54
71
 
55
72
  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"
73
+ begin
74
+ if File.exists? "./spec/sauce_helper.rb"
75
+ require "./spec/sauce_helper"
76
+ else
77
+ require "./spec/spec_helper"
78
+ end
79
+ rescue LoadError => e
80
+ # Gross, but maybe theyre using Cuke
81
+ begin
82
+ if File.exists? "./features/support/sauce_helper.rb"
83
+ require "./features/support/sauce_helper"
84
+ else
85
+ raise LoadError "Can't find sauce_helper, please add it in ./features/support/sauce_helper.rb"
86
+ end
87
+ rescue LoadError => e
88
+ #WHO KNOWS
89
+ end
60
90
  end
91
+
61
92
  end
62
93
 
63
94
  SAUCE_USERNAME = ENV["SAUCE_USERNAME"]
@@ -7,12 +7,12 @@ module Sauce
7
7
 
8
8
  def next_platform
9
9
  platform = @platforms[@index]
10
+ @index += 1
10
11
  begin
11
- @index = @index + 1
12
12
  {
13
- :SAUCE_OS => "'#{platform[0]}'",
14
- :SAUCE_BROWSER => "'#{platform[1]}'",
15
- :SAUCE_BROWSER_VERSION => "'#{platform[2]}'"
13
+ 'os' => platform[0],
14
+ 'browser' => platform[1],
15
+ 'version' => platform[2]
16
16
  }
17
17
  rescue NoMethodError => e
18
18
  puts "I don't have any config"
@@ -3,6 +3,7 @@ require 'socket'
3
3
  require 'childprocess'
4
4
  require 'net/http'
5
5
  require 'childprocess/process'
6
+ require 'sauce/parallel'
6
7
 
7
8
  module Sauce
8
9
  module Utilities
@@ -31,6 +32,40 @@ module Sauce
31
32
  end
32
33
  end
33
34
 
35
+ class Connect
36
+ def self.start(options={})
37
+ begin
38
+ require "sauce/connect"
39
+ rescue LoadError => e
40
+ STDERR.puts 'Please install the `sauce-connect` gem if you intend on using Sauce Connect with your tests!'
41
+ exit(1)
42
+ end
43
+
44
+ if ParallelTests.first_process?
45
+ unless @tunnel
46
+ @tunnel = Sauce::Connect.new options
47
+ @tunnel.connect
48
+ @tunnel.wait_until_ready
49
+ end
50
+ @tunnel
51
+ else
52
+ while not File.exist? "sauce_connect.ready"
53
+ sleep 0.5
54
+ end
55
+ end
56
+ end
57
+
58
+ def self.close
59
+ if @tunnel
60
+ if ParallelTests.first_process?
61
+ ParallelTests.wait_for_other_processes_to_finish
62
+ @tunnel.disconnect
63
+ @tunnel = nil
64
+ end
65
+ end
66
+ end
67
+ end
68
+
34
69
  class RailsServer
35
70
  include Sauce::Utilities
36
71
 
data/lib/sauce/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Sauce
2
2
  MAJOR_VERSION = '3.0'
3
- PATCH_VERSION = '0.beta.2'
3
+ PATCH_VERSION = '0'
4
4
 
5
5
  def version
6
6
  "#{MAJOR_VERSION}.#{PATCH_VERSION}"
@@ -4,59 +4,85 @@ require "parallel_tests/tasks"
4
4
  require "parallel_tests/cli_patch"
5
5
 
6
6
  namespace :sauce do
7
- task :spec, :arg1 do |t, args|
8
-
7
+ task :spec, :files, :concurrencies do |t, args|
9
8
  ::RSpec::Core::Runner.disable_autorun!
10
9
 
11
- args.with_defaults(:arg1 => [Sauce::TestBroker.concurrencies, 20].min)
12
- concurrency = args[:arg1]
10
+ args.with_defaults({
11
+ :concurrencies => [Sauce::TestBroker.concurrencies, 20].min,
12
+ :files => "spec"
13
+ })
13
14
  ParallelTests::CLI.new.run(["--type", "saucerspec",
14
- "-n", "#{concurrency}",
15
- "spec"])
15
+ "-n", "#{args[:concurrencies]}",
16
+ "#{args[:files]}"])
16
17
  end
17
18
 
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"
19
+ task :features, :files, :concurrency do |t, args|
20
+ args.with_defaults({
21
+ :concurrency => [Sauce::TestBroker.concurrencies, 20].min,
22
+ :files => "features"
23
+ })
24
+ ParallelTests::CLI.new.run(["--type", "saucecucumber", args[:files],
25
+ "-n", args[:concurrency].to_s])
26
+ end
27
+
28
+ namespace :install do
29
+ task :features do
30
+ Rake::Task["sauce:install:create_helper"].execute(:helper_type => :features)
31
+ puts <<-ENDLINE
32
+ The Sauce gem is now installed!
33
+
34
+ Next steps:
35
+
36
+ 1. Edit features/support/sauce_helper.rb with your required platforms
37
+ 2. Set the SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables
38
+ 3. Run your tests with 'rake sauce:features'
39
+
40
+ ENDLINE
26
41
  end
27
- puts <<-ENDLINE
28
- The Sauce gem is now installed!
42
+ task :spec do
43
+ Rake::Task["sauce:install:create_helper"].execute(:helper_type => :spec)
44
+ spec_helper_path = "spec/spec_helper.rb"
45
+ unless File.open(spec_helper_path) { |f| f.read.match "require \"sauce_helper\""}
46
+ File.open("spec/spec_helper.rb", "a") do |f|
47
+ f.write "require \"sauce_helper\""
48
+ end
49
+ else
50
+ puts "WARNING - The Sauce gem is already integrated into your rspec setup"
51
+ end
52
+ puts <<-ENDLINE
53
+ The Sauce gem is now installed!
29
54
 
30
- Next steps:
55
+ Next steps:
31
56
 
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'
57
+ 1. Edit spec/sauce_helper.rb with your required platforms
58
+ 2. Make sure we've not mangled your spec/spec_helper.rb requiring sauce_helper
59
+ 3. Set the SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables
60
+ 3. Run your tests with 'rake sauce:spec'
36
61
 
37
- ENDLINE
38
- end
62
+ ENDLINE
63
+ end
64
+
65
+ task :create_helper, [:helper_type] do |t, args|
66
+ path = args[:helper_type].to_sym == :features ? "features/support/sauce_helper.rb" : "spec/sauce_helper.rb"
67
+ unless File.exists? path
68
+ File.open(path, "w") do |f|
69
+ f.write (<<-ENDFILE
70
+ # You should edit this file with the browsers you wish to use
71
+ # For options, check out http://saucelabs.com/platforms
72
+ require "sauce"
39
73
 
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
- )
74
+ Sauce.config do |config|
75
+ config[:browsers] = [
76
+ ["OS", "BROWSER", "VERSION"],
77
+ ["OS", "BROWSER", "VERSION"]
78
+ ]
79
+ end
80
+ ENDFILE
81
+ )
82
+ end
83
+ else
84
+ STDERR.puts "WARNING - sauce_helper has already been created."
57
85
  end
58
- else
59
- STDERR.puts "WARNING - sauce_helper has already been created."
60
86
  end
61
87
  end
62
- end
88
+ end
@@ -26,7 +26,7 @@ describe "Specs in the Selenium Directory" do
26
26
  end
27
27
 
28
28
  it "should be using Sauce Connect" do
29
- Sauce::RSpec::SeleniumExampleGroup.class_variable_defined?(:@@tunnel).should be_true
29
+ Sauce::Utilities::Connect.instance_variable_get(:@tunnel).should_not be_nil
30
30
  end
31
31
  end
32
32
 
@@ -25,7 +25,7 @@ describe "Specs with the @sauce tag", :sauce => true do
25
25
  end
26
26
 
27
27
  it "should be using Sauce Connect" do
28
- Sauce::RSpec::SeleniumExampleGroup.class_variable_defined?(:@@tunnel).should be_true
28
+ Sauce::Utilities::Connect.instance_variable_get(:@tunnel).should_not be_nil
29
29
  end
30
30
  end
31
31
 
@@ -3,38 +3,9 @@ require 'sauce/capybara'
3
3
  require 'sauce/connect'
4
4
 
5
5
  describe Sauce::Capybara do
6
- describe '#connect_tunnel' do
7
- before :each do
8
- $sauce_tunnel = nil
9
- end
10
-
11
- let(:connector) do
12
- connector = double()
13
- connector.should_receive(:connect)
14
- connector.should_receive(:wait_until_ready)
15
- connector
16
- end
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
-
23
- it 'should connect if the tunnel is not connected' do
24
- Sauce::Connect.should_receive(:new).and_return(connector)
25
6
 
26
- Sauce::Capybara.connect_tunnel
27
- end
28
-
29
- it 'should pass the quiet option to Sauce::Connect' do
30
- Sauce::Connect.should_receive(:new).with(
31
- hash_including(:quiet => true)).and_return(connector)
32
- Sauce::Capybara.connect_tunnel(:quiet => true)
33
- end
34
-
35
- after :each do
36
- $sauce_tunnel = nil
37
- end
7
+ after :each do
8
+ Sauce::Utilities::Connect.instance_variable_set(:@tunnel, false)
38
9
  end
39
10
 
40
11
  describe Sauce::Capybara::Driver do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
  require 'sauce/config'
3
3
 
4
4
  describe Sauce::Config do
@@ -92,7 +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
+ ENV['BUILD_TAG'] = 'test env build'
96
96
 
97
97
  config = Sauce::Config.new
98
98
  browser_data = JSON.parse(config.to_browser_string)
@@ -112,7 +112,7 @@ describe Sauce::Config do
112
112
  ENV['SAUCE_BROWSER'] = 'firefox'
113
113
  ENV['SAUCE_BROWSER_VERSION'] = '3.'
114
114
  ENV['SAUCE_JOB_NAME'] = 'Named Ruby Job'
115
- ENV['BUILD_NUMBER'] = 'test env build'
115
+ ENV['BUILD_TAG'] = 'test env build'
116
116
 
117
117
  config = Sauce::Config.new
118
118
  browser_data = JSON.parse(config.to_browser_string)
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'sauce/config'
3
+
4
+ describe "Sauce::Config" do
5
+ describe "#extract_options_from_hash" do
6
+ let(:test_options) {
7
+ {
8
+ "SAUCE_USERNAME" => "user",
9
+ "SAUCE_ACCESS_KEY" => "ac",
10
+ "SAUCE_APPLICATION_HOST" => "application_host"
11
+ }
12
+ }
13
+
14
+ let(:test_config) {Sauce::Config.new}
15
+
16
+ it "should set any options starting with SAUCE" do
17
+ test_config
18
+ opts = test_config.send(:extract_options_from_hash, test_options)
19
+
20
+ opts[:username].should eq "user"
21
+ opts[:application_host].should eq "application_host"
22
+ end
23
+
24
+ context "when passed build numbers" do
25
+ it "should accept BUILD_NUMBER" do
26
+ opts = test_config.send(:extract_options_from_hash, {"BUILD_NUMBER" => "build"})
27
+ opts[:build].should eq "build"
28
+ end
29
+
30
+ it "should accept TRAVIS_BUILD_NUMBER" do
31
+ opts = test_config.send(:extract_options_from_hash, {"TRAVIS_BUILD_NUMBER" => "build"})
32
+ opts[:build].should eq "build"
33
+ end
34
+
35
+ it "should accept CIRCLE_BUILD_NUM" do
36
+ opts = test_config.send(:extract_options_from_hash, {"CIRCLE_BUILD_NUM" => "build"})
37
+ opts[:build].should eq "build"
38
+ end
39
+ end
40
+
41
+ context "when passed browsers in a json array keyed to SAUCE_ONDEMAND_BROWSERS" do
42
+ let(:browsers) {
43
+ { "SAUCE_ONDEMAND_BROWSERS" => [
44
+ {:os => "os1", :browser => "ie1", "browser-version" => "version1"},
45
+ {:os => "os2", :browser => "ie2", "browser-version" => "version2"}
46
+ ].to_json,
47
+ "SAUCE_BROWSER" => "not_browser",
48
+ "SAUCE_BROWSER_VERSION" => "not_version",
49
+ "SAUCE_OS" => "not_os"
50
+ }
51
+ }
52
+
53
+ it "should extract the browsers" do
54
+ opts = test_config.send(:extract_options_from_hash, browsers)
55
+ opts[:browsers].should eq([
56
+ ["os1", "ie1", "version1"],
57
+ ["os2", "ie2", "version2"]
58
+ ])
59
+ end
60
+ end
61
+
62
+ context "when passed browsers in a json array keyed to SAUCE_BROWSERS" do
63
+ let(:browsers) {
64
+ { "SAUCE_BROWSERS" => [
65
+ {:os => "os1", :browser => "ie1", "version" => "version1"},
66
+ {:os => "os2", :browser => "ie2", "version" => "version2"}
67
+ ].to_json,
68
+ "SAUCE_BROWSER" => "not_browser",
69
+ "SAUCE_BROWSER_VERSION" => "not_version",
70
+ "SAUCE_OS" => "not_os"
71
+ }
72
+ }
73
+
74
+ it "should extract the browsers" do
75
+ opts = test_config.send(:extract_options_from_hash, browsers)
76
+ opts[:browsers].should eq([
77
+ ["os1", "ie1", "version1"],
78
+ ["os2", "ie2", "version2"]
79
+ ])
80
+ end
81
+ end
82
+ end
83
+ end
@@ -9,6 +9,10 @@ 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
+
12
16
  describe '#use_sauce_driver' do
13
17
  before :each do
14
18
  ::Capybara.current_driver = :test
@@ -66,6 +70,7 @@ module Sauce::Capybara
66
70
  # Need to create our nice mocked Capybara driver
67
71
  Capybara.stub_chain(:current_session, :driver).and_return(driver)
68
72
  Sauce::Job.stub(:new).and_return(nil)
73
+ Sauce::Selenium2.stub(:new).with(anything).and_return Object.new
69
74
  end
70
75
 
71
76
  context 'with a scenario outline' do
@@ -109,6 +114,53 @@ module Sauce::Capybara
109
114
 
110
115
  end
111
116
 
117
+ context "when using sauce/connect" do
118
+ let(:feature) do
119
+ """
120
+ Feature: A dummy feature
121
+ @selenium
122
+ Scenario: A dummy scenario
123
+ Given a scenario
124
+ When I raise no exceptions
125
+ """
126
+ end
127
+
128
+ before :each do
129
+ Sauce::Utilities::Connect.rspec_reset
130
+
131
+ Sauce.config do |c|
132
+ c[:start_tunnel] = true
133
+ end
134
+ $ran_scenario = nil
135
+ end
136
+
137
+ after :all do
138
+ Sauce::Utilities::Connect.stub!(:start) {}
139
+ end
140
+
141
+ it 'should have set up a tunnel' do
142
+ define_steps do
143
+ Given /^a scenario$/ do
144
+ end
145
+ When /^I raise no exceptions$/ do
146
+ $ran_scenario = true
147
+ end
148
+ # Set up and invoke our defined Around hook
149
+ Around('@selenium') do |scenario, block|
150
+ # We need to fully reference the module function here due to a
151
+ # change in scoping that will happen to this block courtesy of
152
+ # define_steps
153
+ Sauce::Capybara::Cucumber.around_hook(scenario, block)
154
+ end
155
+ end
156
+
157
+ # Make sure we actually configure ourselves
158
+ Sauce::Utilities::Connect.should_receive(:start).with(anything).and_return {true}
159
+ run_defined_feature feature
160
+ $ran_scenario.should be true
161
+ end
162
+ end
163
+
112
164
  context 'with a correct scenario' do
113
165
  let(:feature) do
114
166
  """
@@ -1,3 +1,4 @@
1
+ require "json"
1
2
  require "rspec"
2
3
  require "sauce/parallel/test_broker"
3
4
 
@@ -5,32 +6,65 @@ describe Sauce::TestBroker do
5
6
 
6
7
  describe "#next_environment" do
7
8
 
8
- before :all do
9
- Sauce.config do |c|
10
- c.browsers = [
11
- ["Windows 7", "Opera", "10"],
12
- ["Linux", "Firefox", "19"]
13
- ]
14
- end
9
+ before :each do
10
+ Sauce::TestBroker.reset
15
11
  end
16
12
 
17
- it "returns the first environment for new entries" do
18
- first_environment = Sauce::TestBroker.next_environment "spec/a_spec"
13
+ it "returns the first browser for new entries" do
14
+ first_environment = Sauce::TestBroker.next_environment ["spec/a_spec"]
19
15
  first_environment.should eq({
20
- :SAUCE_OS => "'Windows 7'",
21
- :SAUCE_BROWSER => "'Opera'",
22
- :SAUCE_BROWSER_VERSION => "'10'"
16
+ :SAUCE_PERFILE_BROWSERS => (
17
+ "'" +
18
+ JSON.generate({"./spec/a_spec" => [{"os" => "Windows 7",
19
+ "browser" => "Opera",
20
+ "version" => "10"}]}) +
21
+ "'")
23
22
  })
24
23
  end
25
24
 
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"
25
+ it "only returns a browser once for a given file" do
26
+ Sauce::TestBroker.next_environment ["spec/a_spec"]
27
+ second_environment = Sauce::TestBroker.next_environment ["spec/a_spec"]
29
28
 
30
29
  second_environment.should eq({
31
- :SAUCE_OS => "'Linux'",
32
- :SAUCE_BROWSER => "'Firefox'",
33
- :SAUCE_BROWSER_VERSION => "'19'"
30
+ :SAUCE_PERFILE_BROWSERS => (
31
+ "'" +
32
+ JSON.generate({"./spec/a_spec" => [{"os" => "Linux",
33
+ "browser" => "Firefox",
34
+ "version" => "19"}]}) +
35
+ "'")
36
+ })
37
+ end
38
+
39
+ it "returns multiple browsers for files given multiple times" do
40
+ first_environment = Sauce::TestBroker.next_environment ["spec/a_spec",
41
+ "spec/a_spec"]
42
+ first_environment.should eq({
43
+ :SAUCE_PERFILE_BROWSERS => (
44
+ "'" +
45
+ JSON.generate({"./spec/a_spec" => [{"os" => "Windows 7",
46
+ "browser" => "Opera",
47
+ "version" => "10"},
48
+ {"os" => "Linux",
49
+ "browser" => "Firefox",
50
+ "version" => "19"}]}) +
51
+ "'")
52
+ })
53
+ end
54
+
55
+ it "uses the first browser for each of multiple files" do
56
+ first_environment = Sauce::TestBroker.next_environment ["spec/a_spec",
57
+ "spec/b_spec"]
58
+ first_environment.should eq({
59
+ :SAUCE_PERFILE_BROWSERS => (
60
+ "'" +
61
+ JSON.generate({"./spec/a_spec" => [{"os" => "Windows 7",
62
+ "browser" => "Opera",
63
+ "version" => "10"}],
64
+ "./spec/b_spec" => [{"os" => "Windows 7",
65
+ "browser" => "Opera",
66
+ "version" => "10"}]}) +
67
+ "'")
34
68
  })
35
69
  end
36
70
  end
@@ -40,4 +74,4 @@ describe Sauce::TestBroker do
40
74
  Sauce::TestBroker.test_platforms.should eq Sauce.get_config.browsers
41
75
  end
42
76
  end
43
- end
77
+ end
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+ require "sauce/connect"
3
+
4
+ Sauce.config do |c|
5
+ c[:start_tunnel] = false
6
+ end
7
+
8
+ describe "Sauce::Utilities::Connect" do
9
+
10
+ before :each do
11
+ @mock_tunnel = double()
12
+ end
13
+
14
+ after :each do
15
+ Sauce::Utilities::Connect.instance_variable_set(:@tunnel, nil)
16
+ end
17
+ describe "##start" do
18
+ it "should call Sauce Connect when included" do
19
+ @mock_tunnel.stub(:connect).and_return true
20
+ @mock_tunnel.stub(:wait_until_ready).and_return true
21
+ Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
22
+ Sauce::Utilities::Connect.start
23
+ end
24
+
25
+ it "should throw an exception when Sauce Connect is not included" do
26
+ Object.should_receive(:require).with("sauce/connect").and_raise LoadError
27
+
28
+ lambda {Sauce::Utilities::Connect.start}.should raise_error SystemExit
29
+ end
30
+
31
+ it "should connect the new tunnel" do
32
+ Sauce::Connect.rspec_reset
33
+ @mock_tunnel.should_receive(:connect).with().and_return(true)
34
+ @mock_tunnel.should_receive(:wait_until_ready).and_return(true)
35
+
36
+ Sauce::Connect.stub!(:new).with(anything).and_return @mock_tunnel
37
+
38
+ Sauce::Utilities::Connect.start
39
+ end
40
+
41
+ it "should return the tunnel when done" do
42
+ @mock_tunnel.stub(:connect).and_return true
43
+ @mock_tunnel.stub(:wait_until_ready).and_return true
44
+ Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
45
+ tunnel = Sauce::Utilities::Connect.start
46
+ tunnel.should be @mock_tunnel
47
+ end
48
+
49
+ it "only opens one tunnel" do
50
+ @mock_tunnel.stub(:connect).and_return true
51
+ @mock_tunnel.stub(:wait_until_ready).and_return true
52
+ Sauce::Connect.should_receive(:new).with(anything) {@mock_tunnel}
53
+ tunnel = Sauce::Utilities::Connect.start
54
+
55
+ tunnel_2 = Sauce::Utilities::Connect.start
56
+
57
+ tunnel.should be tunnel_2
58
+ end
59
+ end
60
+
61
+ describe "#close" do
62
+ it "makes the tunnel nil when terminated" do
63
+ @mock_tunnel.stub(:connect).and_return true
64
+ @mock_tunnel.stub(:wait_until_ready).and_return true
65
+ @mock_tunnel.should_receive(:disconnect).and_return true
66
+ Sauce::Connect.stub(:new).with(anything) {@mock_tunnel}
67
+ Sauce::Utilities::Connect.start
68
+
69
+ Sauce::Utilities::Connect.close
70
+ Sauce::Utilities::Connect.instance_variable_get(:@tunnel).should be nil
71
+ end
72
+
73
+ it "calls disconnect" do
74
+ @mock_tunnel.stub(:connect).and_return true
75
+ @mock_tunnel.stub(:wait_until_ready).and_return true
76
+ @mock_tunnel.should_receive(:disconnect).and_return true
77
+ Sauce::Connect.stub(:new).with(anything) {@mock_tunnel}
78
+ tunnel = Sauce::Utilities::Connect.start
79
+
80
+ Sauce::Utilities::Connect.close
81
+ end
82
+
83
+ it "does not error if no tunnel exists" do
84
+ Sauce::Utilities::Connect.close
85
+ end
86
+ end
87
+ end
data/spec/sauce_helper.rb CHANGED
@@ -2,7 +2,7 @@ require "sauce"
2
2
 
3
3
  Sauce.config do |c|
4
4
  c[:browsers] = [
5
- ["Windows 7", "Opera", 10],
6
- ["Linux", "Firefox", 19]
5
+ ["Windows 7", "Opera", "10"],
6
+ ["Linux", "Firefox", "19"]
7
7
  ]
8
- end
8
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "rspec"
1
2
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
3
 
3
4
  ['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: 3.0.0.beta.2
4
+ version: 3.0.0
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-02 00:00:00.000000000 Z
16
+ date: 2013-06-07 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: capybara
@@ -29,6 +29,20 @@ 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'
32
46
  - !ruby/object:Gem::Dependency
33
47
  name: net-http-persistent
34
48
  requirement: !ruby/object:Gem::Requirement
@@ -194,6 +208,7 @@ files:
194
208
  - lib/childprocess/process.rb
195
209
  - lib/generators/sauce/install/install_generator.rb
196
210
  - lib/parallel_tests/cli_patch.rb
211
+ - lib/parallel_tests/saucecucumber/runner.rb
197
212
  - lib/parallel_tests/saucerspec/runner.rb
198
213
  - lib/sauce/capybara.rb
199
214
  - lib/sauce/client.rb
@@ -224,12 +239,14 @@ files:
224
239
  - spec/integration/testunit/test/integration_test.rb
225
240
  - spec/parallel_tests/sauce_rspec_runner_spec.rb
226
241
  - spec/sauce/capybara_spec.rb
227
- - spec/sauce/config_spec.rb
242
+ - spec/sauce/config/config_spec.rb
243
+ - spec/sauce/config/environment_config_spec.rb
228
244
  - spec/sauce/cucumber_spec.rb
229
245
  - spec/sauce/driver_pool_spec.rb
230
246
  - spec/sauce/jasmine_spec.rb
231
247
  - spec/sauce/parallel/test_broker_spec.rb
232
248
  - spec/sauce/selenium_spec.rb
249
+ - spec/sauce/utilities_spec.rb
233
250
  - spec/sauce_helper.rb
234
251
  - spec/spec_helper.rb
235
252
  - bin/sauce
@@ -247,9 +264,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
247
264
  version: '0'
248
265
  required_rubygems_version: !ruby/object:Gem::Requirement
249
266
  requirements:
250
- - - ! '>'
267
+ - - ! '>='
251
268
  - !ruby/object:Gem::Version
252
- version: 1.3.1
269
+ version: '0'
253
270
  requirements: []
254
271
  rubyforge_project:
255
272
  rubygems_version: 2.0.3
@@ -270,11 +287,13 @@ test_files:
270
287
  - spec/integration/testunit/test/integration_test.rb
271
288
  - spec/parallel_tests/sauce_rspec_runner_spec.rb
272
289
  - spec/sauce/capybara_spec.rb
273
- - spec/sauce/config_spec.rb
290
+ - spec/sauce/config/config_spec.rb
291
+ - spec/sauce/config/environment_config_spec.rb
274
292
  - spec/sauce/cucumber_spec.rb
275
293
  - spec/sauce/driver_pool_spec.rb
276
294
  - spec/sauce/jasmine_spec.rb
277
295
  - spec/sauce/parallel/test_broker_spec.rb
278
296
  - spec/sauce/selenium_spec.rb
297
+ - spec/sauce/utilities_spec.rb
279
298
  - spec/sauce_helper.rb
280
299
  - spec/spec_helper.rb