sauce_ruby 3.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/bin/sauce +103 -0
  3. data/lib/childprocess/process.rb +34 -0
  4. data/lib/generators/sauce/install/install_generator.rb +54 -0
  5. data/lib/parallel_tests/cli_patch.rb +23 -0
  6. data/lib/parallel_tests/saucecucumber/runner.rb +43 -0
  7. data/lib/parallel_tests/saucerspec/runner.rb +40 -0
  8. data/lib/sauce.rb +33 -0
  9. data/lib/sauce/capybara.rb +189 -0
  10. data/lib/sauce/client.rb +40 -0
  11. data/lib/sauce/config.rb +434 -0
  12. data/lib/sauce/driver_pool.rb +5 -0
  13. data/lib/sauce/heroku.rb +18 -0
  14. data/lib/sauce/job.rb +159 -0
  15. data/lib/sauce/parallel.rb +16 -0
  16. data/lib/sauce/parallel/test_broker.rb +110 -0
  17. data/lib/sauce/parallel/test_group.rb +24 -0
  18. data/lib/sauce/railtie.rb +11 -0
  19. data/lib/sauce/raketasks.rb +83 -0
  20. data/lib/sauce/rspec/rspec.rb +186 -0
  21. data/lib/sauce/rspec/rspec_formatter.rb +20 -0
  22. data/lib/sauce/rspec/rspec_one_support.rb +66 -0
  23. data/lib/sauce/selenium.rb +95 -0
  24. data/lib/sauce/test_base.rb +21 -0
  25. data/lib/sauce/test_unit.rb +111 -0
  26. data/lib/sauce/utilities.rb +80 -0
  27. data/lib/sauce/utilities/connect.rb +45 -0
  28. data/lib/sauce/utilities/rails_server.rb +95 -0
  29. data/lib/sauce/utilities/rake.rb +32 -0
  30. data/lib/sauce/version.rb +9 -0
  31. data/lib/sauce/webmock.rb +16 -0
  32. data/lib/tasks/parallel_testing.rb +148 -0
  33. data/spec/cucumber_helper.rb +42 -0
  34. data/spec/integration/connect/spec/spec_helper.rb +21 -0
  35. data/spec/integration/connect/spec/start_tunnel_spec.rb +9 -0
  36. data/spec/integration/connect/spec/with_capybara_spec.rb +10 -0
  37. data/spec/integration/connect_integration_spec.rb +99 -0
  38. data/spec/integration/rspec-capybara/spec/capybara_required_last_spec.rb +18 -0
  39. data/spec/integration/rspec-capybara/spec/integration_spec.rb +17 -0
  40. data/spec/integration/rspec-capybara/spec/sauce_config_spec.rb +13 -0
  41. data/spec/integration/rspec-capybara/spec/sauce_required_last_spec.rb +21 -0
  42. data/spec/integration/rspec-capybara/spec/selenium/selenium_with_capybara.rb +12 -0
  43. data/spec/integration/rspec-capybara/spec/spec_helper.rb +37 -0
  44. data/spec/integration/rspec/spec/integration_spec.rb +13 -0
  45. data/spec/integration/rspec/spec/selenium/selenium_directory_spec.rb +20 -0
  46. data/spec/integration/rspec/spec/spec_helper.rb +52 -0
  47. data/spec/integration/rspec/spec/tagging/selenium_tagging_spec.rb +29 -0
  48. data/spec/integration/testunit/test/capybara_integration_test.rb +37 -0
  49. data/spec/integration/testunit/test/integration_test.rb +21 -0
  50. data/spec/integration/testunit/test/test_helper.rb +13 -0
  51. data/spec/parallel_tests/sauce_rspec_runner_spec.rb +23 -0
  52. data/spec/sauce/capybara_spec.rb +386 -0
  53. data/spec/sauce/config/browser_spec.rb +73 -0
  54. data/spec/sauce/config/config_spec.rb +400 -0
  55. data/spec/sauce/config/default_browsers_spec.rb +46 -0
  56. data/spec/sauce/config/environment_config_spec.rb +106 -0
  57. data/spec/sauce/config/load_defaults_spec.rb +50 -0
  58. data/spec/sauce/config/perfile_browser_spec.rb +105 -0
  59. data/spec/sauce/connect_spec.rb +21 -0
  60. data/spec/sauce/cucumber_spec.rb +212 -0
  61. data/spec/sauce/driver_pool_spec.rb +8 -0
  62. data/spec/sauce/file_detector_spec.rb +15 -0
  63. data/spec/sauce/jasmine_spec.rb +30 -0
  64. data/spec/sauce/parallel/test_broker_spec.rb +77 -0
  65. data/spec/sauce/selenium_spec.rb +60 -0
  66. data/spec/sauce/tasks_spec.rb +180 -0
  67. data/spec/sauce/utilities/rails_server_spec.rb +109 -0
  68. data/spec/sauce/utilities/rake_spec.rb +46 -0
  69. data/spec/sauce/utilities/utilities_spec.rb +137 -0
  70. data/spec/sauce_helper.rb +8 -0
  71. data/spec/spec_helper.rb +27 -0
  72. metadata +390 -0
@@ -0,0 +1,5 @@
1
+ module Sauce
2
+ def self.driver_pool
3
+ @@driver_pool ||= {}
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ module Sauce
2
+ if ENV['SAUCE_ONDEMAND_HEROKU_URL'] and ENV['URL']
3
+
4
+ # Heroku Configuation
5
+ config = JSON.parse RestClient.get(ENV['SAUCE_ONDEMAND_HEROKU_URL']).body
6
+ Sauce::Selenium_browsers = JSON.parse config["SAUCE_ONDEMAND_BROWSERS"]
7
+ Sauce::Selenium_url = "#{config['SAUCE_ONDEMAND_PROTOCOL']}#{ENV['URL']}"
8
+ Sauce::Selenium_host = config["SAUCE_ONDEMAND_SERVER" ]
9
+ Sauce::Selenium_port = config["SAUCE_ONDEMAND_PORT" ]
10
+ else
11
+
12
+ # Local Configuration
13
+ Sauce::Selenium_url = ENV['SELENIUM_URL'] || "http://localhost:3000"
14
+ Sauce::Selenium_host = ENV['SELENIUM_HOST'] || "localhost"
15
+ Sauce::Selenium_port = ENV['SELENIUM_PORT'] || "4444"
16
+ Sauce::Selenium_browsers = ENV['SELENIUM_BROWSER'] || ["*firefox"]
17
+ end
18
+ end
data/lib/sauce/job.rb ADDED
@@ -0,0 +1,159 @@
1
+ require 'sauce/client'
2
+
3
+ module Sauce
4
+ # Interact with a Sauce Labs selenium jobs as if it were a ruby object
5
+ class Job
6
+
7
+ class CannotDeleteJobError < StandardError; end #:nodoc
8
+
9
+ attr_accessor :id, :owner, :status, :error
10
+ attr_accessor :name, :browser, :browser_version, :os
11
+ attr_accessor :creation_time, :start_time, :end_time
12
+ attr_accessor :public, :video_url, :log_url, :tags
13
+ attr_accessor :passed, :custom_data
14
+
15
+ # Get the class @@client.
16
+ # TODO: Consider metaprogramming this away
17
+ def self.client
18
+ @@client
19
+ end
20
+
21
+ # Set the class @@client.
22
+ # TODO: Consider metaprogramming this away
23
+ def self.client=(client)
24
+ @@client = client
25
+ end
26
+
27
+ # Get the class @@client.
28
+ # TODO: Consider metaprogramming this away
29
+ def self.account
30
+ @@account
31
+ end
32
+
33
+ # Set the class @@client.
34
+ # TODO: Consider metaprogramming this away
35
+ def self.account=(account)
36
+ @@account = account
37
+ end
38
+
39
+ def self.first
40
+ self.all.first
41
+ end
42
+
43
+ def self.last
44
+ self.all.last
45
+ end
46
+
47
+ # Misnomer: Gets the most recent 100 jobs
48
+ # TODO: Allow/automate paging
49
+ def self.all(options={})
50
+ url = "jobs"
51
+ url += "?full=true" if options[:full] #unless options[:id_only]
52
+ responses = @@client[url].get
53
+ responses = JSON.parse responses.to_s
54
+ return responses.collect{|response| Sauce::Job.new(response)}
55
+ end
56
+
57
+ def self.destroy
58
+ self.all.each { |tunnel| tunnel.destroy }
59
+ end
60
+
61
+ def self.find(options={})
62
+ if options.class == String
63
+ id = options
64
+ elsif options.class == Hash
65
+ id = options[:id]
66
+ end
67
+
68
+ @@client ||= Sauce::Client.new
69
+
70
+ #puts "GET-URL: #{@@client.url}jobs/#{id}"
71
+ response = @@client["jobs/#{id}"].get
72
+
73
+ # TODO: Return nil if bad response
74
+ Sauce::Job.new JSON.parse(response.to_s)
75
+ end
76
+
77
+ # Creates an instance representing a job.
78
+ def initialize(options)
79
+ build!(options)
80
+ @client = Sauce::Client.new
81
+ end
82
+
83
+ # Retrieves the latest information on this job from the Sauce Labs' server
84
+ def refresh!
85
+ response = JSON.parse @@client["jobs/#{@id}"].get.body
86
+ #puts "\tjob refresh with: #{response}"
87
+ build! response
88
+ self
89
+ end
90
+
91
+ # Save/update the current information for the job
92
+ def save
93
+ #puts "Saving job:\n -X PUT #{@@client['jobs']}/#{@id} -H 'Content-Type: application/json' -d '#{self.to_json}'"
94
+ response = @client["jobs/#{@id}"].put(self.to_json,
95
+ {:content_type => :json,
96
+ :accept => :json}).body
97
+ JSON.parse(response)
98
+ end
99
+
100
+ def to_json(options={})
101
+ json = {
102
+ :id => @id,
103
+ :'custom-data' => @custom_data,
104
+ :owner => @owner,
105
+ :status => @status,
106
+ :error => @error,
107
+ :name => @name,
108
+ :browser => @browser,
109
+ :browser_version => @browser_version,
110
+ :os => @os,
111
+ :creation_time => @creation_time,
112
+ :start_time => @start_time,
113
+ :end_time => @end_time,
114
+ :video_url => @video_url,
115
+ :log_url => @log_url,
116
+ :public => @public,
117
+ :tags => @tags,
118
+ :passed => @passed
119
+ }
120
+
121
+ options[:except].each { |key| json.delete(key) } if options[:except]
122
+ json = json.select { |key,value| options[:only].include? key } if options[:only]
123
+
124
+ return json.to_json
125
+ end
126
+
127
+ def delete
128
+ raise CannonDeleteJobError("Cannot delete jobs via Sauce Labs' REST API currently")
129
+ end
130
+
131
+ protected
132
+
133
+ # Sets all internal variables from a hash
134
+ def build!(options)
135
+ # Massage JSON
136
+ options.each { |key,value| options[key] = false if options[key] == "false" }
137
+
138
+ @id = options["id"]
139
+ @owner = options["owner"]
140
+ @status = options["status"]
141
+ @error = options["error"]
142
+ @name = options["name"]
143
+ @browser = options["browser"]
144
+ @browser_version = options["browser_version"]
145
+ @os = options["os"]
146
+ @creation_time = options["creation_time"].to_i
147
+ @start_time = options["start_time"].to_i
148
+ @end_time = options["end_time"].to_i
149
+ @video_url = options["video_url"]
150
+ @log_url = options["log_url"]
151
+ @public = options["public"]
152
+ @tags = options["tags"]
153
+ @passed = options["passed"]
154
+ @custom_data = options['custom-data']
155
+
156
+ raise NoIDError if @id.nil? or @id.empty?
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,16 @@
1
+ require 'parallel_tests'
2
+
3
+ def start_tunnel_for_parallel_tests(c)
4
+ c[:start_tunnel] = ParallelTests.first_process?
5
+ if ParallelTests.first_process?
6
+ at_exit do
7
+ if ParallelTests.first_process?
8
+ ParallelTests.wait_for_other_processes_to_finish
9
+ end
10
+ end
11
+ else
12
+ while not File.exist? "sauce_connect.ready"
13
+ sleep 0.5
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,110 @@
1
+ require "rest-client"
2
+ require "json"
3
+ require "yaml"
4
+ require "sauce/parallel/test_group"
5
+ require "thread"
6
+
7
+ module Sauce
8
+ class TestBroker
9
+ CUCUMBER_CONFIG_FILES = ["./features/support/sauce_helper.rb"]
10
+ RSPEC_CONFIG_FILES = ["./spec/sauce_helper.rb", "./spec/spec_helper.rb"]
11
+
12
+ def self.reset
13
+ if defined? @@platforms
14
+ remove_class_variable(:@@platforms)
15
+ end
16
+ @groups = {}
17
+ end
18
+
19
+ def self.environment_mutex
20
+ @@m ||= Mutex.new
21
+ end
22
+
23
+ def self.next_environment(group)
24
+ environment_mutex.synchronize do
25
+ browsers = {}
26
+ group.each do |file|
27
+ file = "./" + file
28
+ test_groups[file] ||= TestGroup.new(self.test_platforms)
29
+ browsers[file] ||= []
30
+ browsers[file] << test_groups[file].next_platform
31
+ end
32
+
33
+ on_windows = RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/
34
+ format_string = on_windows ? "%s" : "'%s'"
35
+ perfile_browsers = format_string % [JSON.generate(browsers)]
36
+
37
+ return {:SAUCE_PERFILE_BROWSERS => perfile_browsers}
38
+ end
39
+ end
40
+
41
+ def self.test_groups
42
+ @groups ||= {}
43
+ end
44
+
45
+ def self.test_groups=(groups)
46
+ @groups = groups.reduce({}) do |hash, g|
47
+ hash[g] = TestGroup.new(self.test_platforms)
48
+ hash
49
+ end
50
+
51
+ @group_indexes = groups.uniq.reduce({}) do |rh, g|
52
+ rh[g] =(groups.each_index.select {|i| groups[i] == g})
53
+ rh
54
+ end
55
+ end
56
+
57
+ def self.group_index(group)
58
+ @group_indexes[group].shift
59
+ end
60
+
61
+ def self.test_platforms(tool=:rspec)
62
+ unless defined? @@platforms
63
+ load_sauce_config(tool)
64
+ @@platforms ||= Sauce.get_config[:browsers]
65
+ end
66
+ @@platforms
67
+ end
68
+
69
+ def self.concurrency
70
+ response = RestClient.get "#{rest_jobs_url}/#{SAUCE_USERNAME}/limits"
71
+ res = JSON.parse(response)["concurrency"]
72
+ end
73
+
74
+ def self.rest_jobs_url
75
+ "https://#{AUTH_DETAILS}@saucelabs.com/rest/v1"
76
+ end
77
+
78
+ def self.load_sauce_config(tool=:rspec)
79
+ case tool
80
+ when :rspec
81
+ primary_files = RSPEC_CONFIG_FILES
82
+ secondary_files = CUCUMBER_CONFIG_FILES
83
+ when :cucumber
84
+ primary_files = CUCUMBER_CONFIG_FILES
85
+ secondary_files = RSPEC_CONFIG_FILES
86
+ end
87
+
88
+ configuration_file = self.find_config_file(primary_files, secondary_files)
89
+ unless configuration_file
90
+ possible_config_files = primary_files + secondary_files
91
+ error_message = "Could not find Sauce configuration. Please make sure one of the following files exists:\n"
92
+ error_message << possible_config_files.map { |file_path| " - #{file_path}" }.join("\n")
93
+ raise error_message
94
+ end
95
+ require configuration_file
96
+ end
97
+
98
+ def self.find_config_file(primary_files, secondary_files)
99
+ find_in_file_list(primary_files) || find_in_file_list(secondary_files)
100
+ end
101
+
102
+ def self.find_in_file_list(list)
103
+ list.find { |file_path| File.exists?(file_path) }
104
+ end
105
+
106
+ SAUCE_USERNAME = ENV["SAUCE_USERNAME"]
107
+ SAUCE_ACCESS_KEY = ENV["SAUCE_ACCESS_KEY"]
108
+ AUTH_DETAILS = "#{SAUCE_USERNAME}:#{SAUCE_ACCESS_KEY}"
109
+ end
110
+ end
@@ -0,0 +1,24 @@
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
+ @index += 1
11
+ begin
12
+ caps ={
13
+ 'os' => platform[0],
14
+ 'browser' => platform[1],
15
+ 'version' => platform[2]
16
+ }
17
+ caps.merge!({:caps => platform[3]}) if platform[3]
18
+ caps
19
+ rescue NoMethodError => e
20
+ puts "I don't have any config"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'sauce'
2
+ require 'rails'
3
+ module Sauce
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ require 'sauce/version'
7
+ require 'sauce/utilities/rake'
8
+ require 'tasks/parallel_testing'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,83 @@
1
+ require 'sauce'
2
+
3
+ spec_prereq = File.exist?(File.join(::Rails.root.to_s, 'config', 'database.yml')) ? "db:test:prepare" : :noop
4
+ task :noop do
5
+ end
6
+
7
+ class Rake::Task
8
+ def abandon
9
+ @actions.clear
10
+ end
11
+ end
12
+
13
+ include Sauce::Utilities
14
+
15
+ if defined?(Spec::Rake::SpecTask)
16
+ namespace :spec do
17
+ namespace :selenium do
18
+ desc "Run the Selenium acceptance tests in spec/selenium using Sauce OnDemand"
19
+ task :sauce => spec_prereq do
20
+ Rake::Task["spec:selenium:runtests"].invoke
21
+ end
22
+
23
+ desc "" # Hide it from rake -T
24
+ Spec::Rake::SpecTask.new :runtests do |t|
25
+ t.spec_opts = ['--options', "\"#{Rails.root.join('spec', 'spec.opts')}\""]
26
+ spec_glob = ENV["SAUCE_SPEC_GLOB"] || "spec/selenium/**/*_spec.rb"
27
+ t.spec_files = FileList[spec_glob]
28
+ end
29
+ end
30
+
31
+ task :selenium => "selenium:sauce"
32
+ end
33
+
34
+ Rake::Task[:spec].abandon
35
+ desc "Run all specs in spec directory (excluding plugin specs)"
36
+ Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t|
37
+ t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
38
+ t.spec_files = FileList['spec/**/*_spec.rb'].exclude('spec/selenium/*')
39
+ end
40
+ end
41
+
42
+ if defined?(RSpec::Core::RakeTask)
43
+ namespace :spec do
44
+ namespace :selenium do
45
+ desc "Run the Selenium acceptance tests in spec/selenium using Sauce OnDemand"
46
+ task :sauce => spec_prereq do
47
+ Rake::Task["spec:selenium:runtests"].invoke
48
+ end
49
+
50
+ desc "" # Hide it from rake -T
51
+ RSpec::Core::RakeTask.new :runtests do |t|
52
+ spec_glob = ENV["SAUCE_SPEC_GLOB"] || "spec/selenium/**/*_spec.rb"
53
+ t.pattern = spec_glob
54
+ end
55
+ end
56
+
57
+ task :selenium => "selenium:sauce"
58
+ end
59
+ end
60
+
61
+ if defined?(Rake::TestTask)
62
+ namespace :test do
63
+ namespace :selenium do
64
+ desc "Run the Selenium acceptance tests in test/selenium using Sauce OnDemand"
65
+ task :sauce do
66
+ Rake::Task["test:selenium:runtests"].invoke
67
+ end
68
+
69
+ Rake::TestTask.new(:runtests) do |t|
70
+ t.libs << "test"
71
+ test_glob = ENV["SAUCE_TEST_GLOB"] || "test/selenium/**/*_test.rb"
72
+ t.pattern = test_glob
73
+ t.verbose = true
74
+ end
75
+ # Hide it from rake -T
76
+ Rake::Task['test:selenium:runtests'].instance_variable_set(:@full_comment, nil)
77
+ Rake::Task['test:selenium:runtests'].instance_variable_set(:@comment, nil)
78
+ Rake::Task['test:selenium:runtests'].enhance(["db:test:prepare"])
79
+ end
80
+
81
+ task :selenium => "selenium:sauce"
82
+ end
83
+ end
@@ -0,0 +1,186 @@
1
+ require 'sauce/utilities'
2
+ require 'sauce_whisk'
3
+ require 'sauce/rspec/rspec_one_support'
4
+ require 'sauce/rspec/rspec_formatter'
5
+
6
+ begin
7
+ require 'rspec/core'
8
+ module Sauce
9
+ module RSpec
10
+ @@server = nil
11
+
12
+ def self.server
13
+ return @@server
14
+ end
15
+
16
+ def self.server=(s)
17
+ @@server = s
18
+ end
19
+
20
+ def self.setup_environment
21
+ ::RSpec.configuration.before(:all, :sauce => true) do
22
+ Sauce::RSpec.start_tools_for_sauce_tag
23
+ end
24
+
25
+ ::RSpec.configuration.before :all do
26
+ Sauce::RSpec.start_tools_for_selenium_directory
27
+ Sauce::RSpec.register_default_hook
28
+ Sauce::RSpec.register_jenkins_hook if ENV['JENKINS_SERVER_COOKIE']
29
+ end
30
+
31
+ ::RSpec.configuration.after :suite do
32
+ Sauce::RSpec.stop_tools
33
+ end
34
+ end
35
+
36
+ def self.start_tools_for_sauce_tag
37
+ config = Sauce::Config.new
38
+ if config[:start_tunnel]
39
+ Sauce::Utilities::Connect.start_from_config(config)
40
+ end
41
+
42
+ unless self.server
43
+ self.server= Sauce::Utilities::RailsServer.start_if_required(config)
44
+ end
45
+ end
46
+
47
+ def self.start_tools_for_selenium_directory
48
+ config = Sauce::Config.new
49
+ # TODO: Check which rspec version this changed in -- If < 2, change.
50
+ files_to_run = ::RSpec.configuration.respond_to?(:files_to_run) ? ::RSpec.configuration.files_to_run :
51
+ ::RSpec.configuration.settings[:files_to_run]
52
+
53
+ running_selenium_specs = files_to_run.any? {|file| file =~ /spec\/selenium\//}
54
+ need_tunnel = running_selenium_specs && config[:application_host]
55
+
56
+ if need_tunnel && config[:start_tunnel]
57
+ Sauce::Utilities::Connect.start_from_config(config)
58
+ end
59
+
60
+ if running_selenium_specs
61
+ unless self.server
62
+ self.server= Sauce::Utilities::RailsServer.start_if_required(config)
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.register_default_hook
68
+ Sauce.config do |c|
69
+ c.after_job :rspec do |id, platform, name, success|
70
+ SauceWhisk::Jobs.change_status id, success
71
+ end
72
+ end
73
+ end
74
+
75
+ def self.register_jenkins_hook
76
+ Sauce.config do |c|
77
+ c.after_job :jenkins do |id, platform, name, success|
78
+ puts "SauceOnDemandSessionID=#{id} job-name=#{name}"
79
+ end
80
+ end
81
+ end
82
+
83
+ def self.stop_tools
84
+ Sauce::Utilities::Connect.close
85
+ server.stop if self.server
86
+ Sauce::Utilities.warn_if_suspect_misconfiguration
87
+ end
88
+
89
+ module SeleniumExampleGroup
90
+ include Sauce::TestBase
91
+ attr_reader :selenium
92
+ alias_method :s, :selenium
93
+
94
+ def self.rspec_current_example
95
+ lambda { |context| ::RSpec.current_example }
96
+ end
97
+
98
+ def self.context_example
99
+ lambda { |context| context.example }
100
+ end
101
+
102
+ def self.find_example_method
103
+ ::RSpec.respond_to?(:current_example) ? rspec_current_example : context_example
104
+ end
105
+
106
+ def self.current_example
107
+ @@current_example_fetcher ||= find_example_method
108
+ end
109
+
110
+ # TODO V4 -- Remove this entirely
111
+ def page
112
+ if self.class.included_modules.any? {|m| m.name == 'Capybara::DSL'}
113
+ ::Capybara.current_session
114
+ else
115
+ warn Sauce::Utilities.page_deprecation_message
116
+ @selenium
117
+ end
118
+ end
119
+
120
+ def self.included(othermod)
121
+ othermod.around do |the_test|
122
+ config = Sauce::Config.new
123
+ description = the_test.metadata[:full_description]
124
+ file = the_test.metadata[:file_path]
125
+ exceptions = {}
126
+ test_each config.caps_for_location(file), description do |selenium, caps|
127
+
128
+ example = SeleniumExampleGroup.current_example.call(self)
129
+ example.instance_variable_set(:@exception, nil)
130
+
131
+ @selenium = selenium
132
+ Sauce.driver_pool[Thread.current.object_id] = @selenium
133
+ example.metadata[:sauce_public_link] = SauceWhisk.public_link(@selenium.session_id)
134
+
135
+ begin
136
+ the_test.run
137
+ success = example.exception.nil?
138
+ ensure
139
+ @selenium.stop
140
+ begin
141
+ os = caps[:os]
142
+ browser = caps[:browser]
143
+ version = caps[:version]
144
+ unless success
145
+ exceptions["#{os} - #{browser} #{version}"] = example.exception
146
+ end
147
+ platform = {:os => os, :browser => browser, :version => version}
148
+ config.run_post_job_hooks(@selenium.session_id, platform, description, success)
149
+ rescue Exception => e
150
+ STDERR.puts "Error running post job hooks"
151
+ STDERR.puts e
152
+ end
153
+ Sauce.driver_pool.delete Thread.current.object_id
154
+ end
155
+ if (exceptions.length > 0)
156
+ example.instance_variable_set(:@exception, exceptions.first[1])
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ def self.inclusion_params
163
+ params = [self]
164
+ gem_version = Gem::Version.new ::RSpec::Core::Version::STRING
165
+ file_path_hash = {:file_path => Regexp.compile('spec[\\\/]selenium')}
166
+ if (gem_version >= Gem::Version.new('2.99.0'))
167
+ params = params + [file_path_hash]
168
+ else
169
+ params = params + [{:example_group => file_path_hash}]
170
+ end
171
+ params
172
+ end
173
+
174
+ ::RSpec.configuration.include(*self.inclusion_params)
175
+ ::RSpec.configuration.include(self, :sauce => true)
176
+
177
+ Sauce::RSpec.setup_environment
178
+ end
179
+ end
180
+ end
181
+ rescue LoadError, TypeError
182
+ # User doesn't have RSpec 2.x installed
183
+ rescue => e
184
+ STDERR.puts "Exception caught: #{e.to_s}"
185
+ exit 1
186
+ end