sauce_ruby 3.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/sauce +103 -0
- data/lib/childprocess/process.rb +34 -0
- data/lib/generators/sauce/install/install_generator.rb +54 -0
- data/lib/parallel_tests/cli_patch.rb +23 -0
- data/lib/parallel_tests/saucecucumber/runner.rb +43 -0
- data/lib/parallel_tests/saucerspec/runner.rb +40 -0
- data/lib/sauce.rb +33 -0
- data/lib/sauce/capybara.rb +189 -0
- data/lib/sauce/client.rb +40 -0
- data/lib/sauce/config.rb +434 -0
- data/lib/sauce/driver_pool.rb +5 -0
- data/lib/sauce/heroku.rb +18 -0
- data/lib/sauce/job.rb +159 -0
- data/lib/sauce/parallel.rb +16 -0
- data/lib/sauce/parallel/test_broker.rb +110 -0
- data/lib/sauce/parallel/test_group.rb +24 -0
- data/lib/sauce/railtie.rb +11 -0
- data/lib/sauce/raketasks.rb +83 -0
- data/lib/sauce/rspec/rspec.rb +186 -0
- data/lib/sauce/rspec/rspec_formatter.rb +20 -0
- data/lib/sauce/rspec/rspec_one_support.rb +66 -0
- data/lib/sauce/selenium.rb +95 -0
- data/lib/sauce/test_base.rb +21 -0
- data/lib/sauce/test_unit.rb +111 -0
- data/lib/sauce/utilities.rb +80 -0
- data/lib/sauce/utilities/connect.rb +45 -0
- data/lib/sauce/utilities/rails_server.rb +95 -0
- data/lib/sauce/utilities/rake.rb +32 -0
- data/lib/sauce/version.rb +9 -0
- data/lib/sauce/webmock.rb +16 -0
- data/lib/tasks/parallel_testing.rb +148 -0
- data/spec/cucumber_helper.rb +42 -0
- data/spec/integration/connect/spec/spec_helper.rb +21 -0
- data/spec/integration/connect/spec/start_tunnel_spec.rb +9 -0
- data/spec/integration/connect/spec/with_capybara_spec.rb +10 -0
- data/spec/integration/connect_integration_spec.rb +99 -0
- data/spec/integration/rspec-capybara/spec/capybara_required_last_spec.rb +18 -0
- data/spec/integration/rspec-capybara/spec/integration_spec.rb +17 -0
- data/spec/integration/rspec-capybara/spec/sauce_config_spec.rb +13 -0
- data/spec/integration/rspec-capybara/spec/sauce_required_last_spec.rb +21 -0
- data/spec/integration/rspec-capybara/spec/selenium/selenium_with_capybara.rb +12 -0
- data/spec/integration/rspec-capybara/spec/spec_helper.rb +37 -0
- data/spec/integration/rspec/spec/integration_spec.rb +13 -0
- data/spec/integration/rspec/spec/selenium/selenium_directory_spec.rb +20 -0
- data/spec/integration/rspec/spec/spec_helper.rb +52 -0
- data/spec/integration/rspec/spec/tagging/selenium_tagging_spec.rb +29 -0
- data/spec/integration/testunit/test/capybara_integration_test.rb +37 -0
- data/spec/integration/testunit/test/integration_test.rb +21 -0
- data/spec/integration/testunit/test/test_helper.rb +13 -0
- data/spec/parallel_tests/sauce_rspec_runner_spec.rb +23 -0
- data/spec/sauce/capybara_spec.rb +386 -0
- data/spec/sauce/config/browser_spec.rb +73 -0
- data/spec/sauce/config/config_spec.rb +400 -0
- data/spec/sauce/config/default_browsers_spec.rb +46 -0
- data/spec/sauce/config/environment_config_spec.rb +106 -0
- data/spec/sauce/config/load_defaults_spec.rb +50 -0
- data/spec/sauce/config/perfile_browser_spec.rb +105 -0
- data/spec/sauce/connect_spec.rb +21 -0
- data/spec/sauce/cucumber_spec.rb +212 -0
- data/spec/sauce/driver_pool_spec.rb +8 -0
- data/spec/sauce/file_detector_spec.rb +15 -0
- data/spec/sauce/jasmine_spec.rb +30 -0
- data/spec/sauce/parallel/test_broker_spec.rb +77 -0
- data/spec/sauce/selenium_spec.rb +60 -0
- data/spec/sauce/tasks_spec.rb +180 -0
- data/spec/sauce/utilities/rails_server_spec.rb +109 -0
- data/spec/sauce/utilities/rake_spec.rb +46 -0
- data/spec/sauce/utilities/utilities_spec.rb +137 -0
- data/spec/sauce_helper.rb +8 -0
- data/spec/spec_helper.rb +27 -0
- metadata +390 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0e0aad8cbfd23b54304b3b5190e3af87159e509
|
4
|
+
data.tar.gz: 35a9bc2da5f12d59c72f17a06836d9c57d3310fa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c27dc8ae6d754fdb7ae798b26f1cb02f234cf42937c3217ae585c484225cd3860f7b8ba929d9ecb0c2f9cc67f7ae8e449523ef35f1762723dcc5c89372278185
|
7
|
+
data.tar.gz: 6667deae41d668ac3c819ac9756ee9d92520ca97304921ff94b3f53dcccc88e3ff1a26439300590f2cd0a26fa308ef1454b588255a0982e277750ea786d9adcf
|
data/bin/sauce
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'cmdparse'
|
4
|
+
require 'yaml'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'json'
|
7
|
+
require 'highline/import'
|
8
|
+
|
9
|
+
sauce_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
10
|
+
$LOAD_PATH.unshift(sauce_dir) unless $LOAD_PATH.include?(sauce_dir)
|
11
|
+
|
12
|
+
require 'sauce'
|
13
|
+
|
14
|
+
cmd = CmdParse::CommandParser.new(true, true)
|
15
|
+
cmd.program_name = "sauce "
|
16
|
+
cmd.program_version = [0, 1, 0]
|
17
|
+
|
18
|
+
cmd.add_command(CmdParse::HelpCommand.new)
|
19
|
+
|
20
|
+
class ConnectCommand < CmdParse::Command
|
21
|
+
def usage
|
22
|
+
"Usage: #{commandparser.program_name}connect"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
connect = ConnectCommand.new('connect', false)
|
26
|
+
connect.short_desc = 'Connect a Sauce Connect tunnel'
|
27
|
+
connect.set_execution_block do |args|
|
28
|
+
begin
|
29
|
+
require 'sauce/connect'
|
30
|
+
rescue LoadError
|
31
|
+
puts "Please install the sauce-connect gem (`gem install sauce-connect`) in order to use Sauce Connect"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
require 'sauce/config'
|
35
|
+
config = Sauce::Config.new
|
36
|
+
command = "#{Sauce::Connect.connect_command} #{config.username} #{config.access_key} #{ARGV[1 .. -1]}"
|
37
|
+
exec(command)
|
38
|
+
end
|
39
|
+
cmd.add_command(connect)
|
40
|
+
|
41
|
+
|
42
|
+
# configure
|
43
|
+
class ConfigureCommand < CmdParse::Command
|
44
|
+
def usage
|
45
|
+
"Usage: #{commandparser.program_name}configure USERNAME ACCESS_KEY"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
configure = ConfigureCommand.new('configure', false)
|
49
|
+
configure.short_desc = "Configure Sauce Labs credentials"
|
50
|
+
configure.set_execution_block do |args|
|
51
|
+
if args.length < 2
|
52
|
+
puts configure.usage
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
username = args[0]
|
56
|
+
access_key = args[1]
|
57
|
+
dir = File.join(File.expand_path("~"), ".sauce")
|
58
|
+
FileUtils.mkdir(dir) unless File.directory?(dir)
|
59
|
+
|
60
|
+
out = File.new(File.join(dir, "ondemand.yml"), 'w')
|
61
|
+
out.write(YAML.dump({"username" => username, "access_key" => access_key}))
|
62
|
+
out.close()
|
63
|
+
end
|
64
|
+
cmd.add_command(configure)
|
65
|
+
|
66
|
+
#create
|
67
|
+
create = CmdParse::Command.new('create', false)
|
68
|
+
create.short_desc = "Create a new Sauce Labs account"
|
69
|
+
create.set_execution_block do |args|
|
70
|
+
puts "Let's create a new account!"
|
71
|
+
username = ask("Username: ")
|
72
|
+
password = ask("Password: ") { |q| q.echo = "*" }
|
73
|
+
email = ask("Email: ")
|
74
|
+
name = ask("Full name: ")
|
75
|
+
|
76
|
+
body = {
|
77
|
+
:username => username,
|
78
|
+
:password => password,
|
79
|
+
:email => email,
|
80
|
+
:name => name,
|
81
|
+
:token => "c8eb3e2645005bcbbce7e2c208c6b7a71555d908"
|
82
|
+
}.to_json
|
83
|
+
|
84
|
+
begin
|
85
|
+
result = RestClient.post("http://saucelabs.com/rest/v1/users",
|
86
|
+
body, :content_type => :json, :accept => :json)
|
87
|
+
rescue => e
|
88
|
+
begin
|
89
|
+
puts "ERROR: #{JSON.load(e.response)['errors']}"
|
90
|
+
rescue
|
91
|
+
puts "ERROR: #{e.response}"
|
92
|
+
end
|
93
|
+
else
|
94
|
+
result = JSON.load(result)
|
95
|
+
|
96
|
+
puts "Account #{username} created successfully."
|
97
|
+
puts "Your access key is: #{result['access_key']}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
cmd.add_command(create)
|
102
|
+
|
103
|
+
cmd.parse
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ChildProcess
|
2
|
+
module Unix
|
3
|
+
class Process < AbstractProcess
|
4
|
+
|
5
|
+
def return_unless_timeout
|
6
|
+
lambda do |timeout|
|
7
|
+
begin
|
8
|
+
return poll_for_exit timeout
|
9
|
+
rescue TimeoutError
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def stop(timeout = 3, signal=nil)
|
15
|
+
assert_started
|
16
|
+
|
17
|
+
unless signal.nil?
|
18
|
+
send_signal signal
|
19
|
+
return_unless_timeout.call(timeout)
|
20
|
+
end
|
21
|
+
|
22
|
+
send_term
|
23
|
+
return_unless_timeout.call(timeout)
|
24
|
+
|
25
|
+
send_kill
|
26
|
+
wait
|
27
|
+
rescue Errno::ECHILD, Errno::ESRCH
|
28
|
+
# handle race condition where process dies between timeout
|
29
|
+
# and send_kill
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Sauce
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
5
|
+
|
6
|
+
desc "Prep application for Sauce OnDemand Selenium tests"
|
7
|
+
|
8
|
+
argument :username, :type => :string, :required => false
|
9
|
+
argument :api_key, :type => :string, :required => false
|
10
|
+
|
11
|
+
def copy_rake_tasks
|
12
|
+
copy_file "sauce.rake", "lib/tasks/sauce.rake"
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure_credentials
|
16
|
+
if username
|
17
|
+
system("sauce config #{username} #{api_key}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_spec
|
22
|
+
if File.directory? 'spec'
|
23
|
+
empty_directory "spec/selenium"
|
24
|
+
append_file "spec/spec_helper.rb", generate_config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup_test
|
29
|
+
if File.directory? 'test'
|
30
|
+
empty_directory "test/selenium"
|
31
|
+
append_file "test/test_helper.rb", generate_config
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def generate_config
|
38
|
+
return <<-CONFIG
|
39
|
+
|
40
|
+
require 'sauce'
|
41
|
+
|
42
|
+
Sauce.config do |conf|
|
43
|
+
conf[:browsers] = [
|
44
|
+
["Windows 2003", "firefox", "3.6."]
|
45
|
+
]
|
46
|
+
conf[:application_host] = "127.0.0.1"
|
47
|
+
conf[:application_port] = "3001"
|
48
|
+
conf[:browser_url] = "http://localhost:3001/"
|
49
|
+
end
|
50
|
+
CONFIG
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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
|
+
non_empty_groups = groups.reject {|group| group.empty?}
|
9
|
+
Sauce::TestBroker.test_groups = non_empty_groups
|
10
|
+
|
11
|
+
report_number_of_tests(non_empty_groups)
|
12
|
+
|
13
|
+
test_results = execute_in_parallel(non_empty_groups, non_empty_groups.size, options) do |group|
|
14
|
+
run_tests(group, Sauce::TestBroker.group_index(group), num_processes, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
report_results(test_results)
|
18
|
+
end
|
19
|
+
|
20
|
+
abort final_fail_message if any_test_failed?(test_results)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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
|
+
cmd = [
|
14
|
+
executable,
|
15
|
+
(runtime_logging if File.directory?(File.dirname(runtime_log))),
|
16
|
+
cucumber_opts(options[:test_options]),
|
17
|
+
*sanitized_test_files
|
18
|
+
].compact.join(" ")
|
19
|
+
execute_command(cmd, process_number, num_processes, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.tests_in_groups(tests, num_groups, options={})
|
23
|
+
originals = (options[:group_by] == :steps) ? Grouper.by_steps(find_tests(tests, options), num_groups, options) : super
|
24
|
+
all_tests = originals.flatten * Sauce::TestBroker.test_platforms(:cucumber).length
|
25
|
+
base_group_size = all_tests.length / num_groups
|
26
|
+
num_full_groups = all_tests.length - (base_group_size * num_groups)
|
27
|
+
|
28
|
+
curpos = 0
|
29
|
+
groups = []
|
30
|
+
num_groups.times do |i|
|
31
|
+
group_size = base_group_size
|
32
|
+
if i < num_full_groups
|
33
|
+
group_size += 1
|
34
|
+
end
|
35
|
+
groups << all_tests.slice(curpos, group_size)
|
36
|
+
curpos += group_size
|
37
|
+
end
|
38
|
+
|
39
|
+
groups
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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
|
+
our_options = options.dup
|
10
|
+
exe = executable # expensive, so we cache
|
11
|
+
version = (exe =~ /\brspec\b/ ? 2 : 1)
|
12
|
+
cmd = [exe, our_options[:test_options], (rspec_2_color if version == 2), spec_opts, *test_files].compact.join(" ")
|
13
|
+
env = Sauce::TestBroker.next_environment(test_files)
|
14
|
+
env << " #{rspec_1_color}" if version == 1
|
15
|
+
our_options.merge!(:env => env)
|
16
|
+
execute_command(cmd, process_number, num_processes, our_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def self.tests_in_groups(tests, num_groups, options={})
|
21
|
+
all_tests = super.flatten * Sauce::TestBroker.test_platforms(:rspec).length
|
22
|
+
base_group_size = all_tests.length / num_groups
|
23
|
+
num_full_groups = all_tests.length - (base_group_size * num_groups)
|
24
|
+
|
25
|
+
curpos = 0
|
26
|
+
groups = []
|
27
|
+
num_groups.times do |i|
|
28
|
+
group_size = base_group_size
|
29
|
+
if i < num_full_groups
|
30
|
+
group_size += 1
|
31
|
+
end
|
32
|
+
groups << all_tests.slice(curpos, group_size)
|
33
|
+
curpos += group_size
|
34
|
+
end
|
35
|
+
|
36
|
+
groups
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/sauce.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
if defined?(Rails)
|
2
|
+
require "sauce/railtie"
|
3
|
+
else
|
4
|
+
require 'tasks/parallel_testing'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'sauce/version'
|
8
|
+
require 'sauce/utilities'
|
9
|
+
require 'sauce/utilities/rake'
|
10
|
+
require 'sauce/job'
|
11
|
+
require 'sauce/client'
|
12
|
+
require 'sauce/config'
|
13
|
+
require 'sauce/selenium'
|
14
|
+
require 'sauce/test_base'
|
15
|
+
require 'sauce/rspec/rspec'
|
16
|
+
require 'sauce/test_unit'
|
17
|
+
require 'parallel_tests/saucerspec/runner'
|
18
|
+
require 'parallel_tests/saucecucumber/runner'
|
19
|
+
|
20
|
+
|
21
|
+
# Ruby before 1.9.3-p382 does not handle exit codes correctly when nested
|
22
|
+
if RUBY_VERSION == "1.9.3" && RUBY_PATCHLEVEL < 392
|
23
|
+
module Kernel
|
24
|
+
alias :existing_at_exit :at_exit
|
25
|
+
def at_exit(&block)
|
26
|
+
existing_at_exit do
|
27
|
+
exit_status = $!.status if $!.is_a?(SystemExit)
|
28
|
+
block.call
|
29
|
+
exit exit_status if exit_status
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
require 'sauce/config'
|
3
|
+
require 'sauce/selenium'
|
4
|
+
require 'sauce/version'
|
5
|
+
|
6
|
+
|
7
|
+
$sauce_tunnel = nil
|
8
|
+
|
9
|
+
module Sauce
|
10
|
+
module Capybara
|
11
|
+
class Driver < ::Capybara::Selenium::Driver
|
12
|
+
RETRY_ON = [::Selenium::WebDriver::Error::UnhandledError,
|
13
|
+
::Selenium::WebDriver::Error::UnknownError]
|
14
|
+
MAX_RETRIES = 3
|
15
|
+
|
16
|
+
def handle_retry(method, *args, &block)
|
17
|
+
retries = 0
|
18
|
+
|
19
|
+
# Disable retries only when we really really want to, this will remain
|
20
|
+
# an undocomented hack for the time being
|
21
|
+
if ENV['SAUCE_DISABLE_RETRY']
|
22
|
+
retries = MAX_RETRIES
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
send("base_#{method}".to_sym, *args, &block)
|
27
|
+
rescue *RETRY_ON => e
|
28
|
+
if retries < MAX_RETRIES
|
29
|
+
puts "Received an exception (#{e}), retrying"
|
30
|
+
retries = retries + 1
|
31
|
+
retry
|
32
|
+
else
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
alias :base_visit :visit
|
39
|
+
alias :base_current_url :current_url
|
40
|
+
alias :base_within_frame :within_frame
|
41
|
+
alias :base_within_window :within_window
|
42
|
+
alias :base_find_window :find_window
|
43
|
+
alias :base_execute_script :execute_script
|
44
|
+
alias :base_evaluate_script :evaluate_script
|
45
|
+
|
46
|
+
@methods_to_retry = [:visit, :current_url,
|
47
|
+
:within_frame, :within_window, :find_window, :source,
|
48
|
+
:execute_script, :evaluate_script
|
49
|
+
]
|
50
|
+
|
51
|
+
if method_defined? :find
|
52
|
+
alias :base_find :find
|
53
|
+
@methods_to_retry += [:find]
|
54
|
+
else
|
55
|
+
alias :base_find_css :find_css
|
56
|
+
alias :base_find_xpath :find_xpath
|
57
|
+
@methods_to_retry += [:find_css, :find_xpath]
|
58
|
+
end
|
59
|
+
|
60
|
+
if Gem::Version.new(::Capybara::VERSION) < Gem::Version.new(2)
|
61
|
+
alias :base_body :body
|
62
|
+
alias :base_source :source
|
63
|
+
|
64
|
+
@methods_to_retry + [:body, :source]
|
65
|
+
else
|
66
|
+
alias :base_html :html
|
67
|
+
@methods_to_retry + [:html]
|
68
|
+
end
|
69
|
+
|
70
|
+
@methods_to_retry.each do |method|
|
71
|
+
define_method(method) do |*args, &block|
|
72
|
+
handle_retry(method, *args, &block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Oh gods why didn't I comment these when I wrote them?
|
77
|
+
# These are what I think I'm doing.
|
78
|
+
#
|
79
|
+
# Returns the browser currently being used or fetches a new
|
80
|
+
# browser, either from the RSpec integration or by creating
|
81
|
+
# one.
|
82
|
+
def browser
|
83
|
+
# Return the existing browser if we have it
|
84
|
+
unless existing_browser?
|
85
|
+
# Try to get a driver from the driver pool
|
86
|
+
@browser = rspec_browser
|
87
|
+
unless @browser
|
88
|
+
@browser = Sauce::Selenium2.new
|
89
|
+
at_exit do
|
90
|
+
finish!
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@browser
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the rspec created browser if it exists
|
98
|
+
def rspec_browser
|
99
|
+
if browser = Sauce.driver_pool[Thread.current.object_id]
|
100
|
+
@using_rspec_browser = true
|
101
|
+
else
|
102
|
+
@using_rspec_browser = false
|
103
|
+
end
|
104
|
+
browser
|
105
|
+
end
|
106
|
+
|
107
|
+
# If a browser has been created OR RSpec has put one in the diriver pool
|
108
|
+
# and we're using that browser, returns true.
|
109
|
+
def existing_browser?
|
110
|
+
if @using_rspec_browser
|
111
|
+
@browser == Sauce.driver_pool[Thread.current.object_id]
|
112
|
+
else
|
113
|
+
@browser
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def finish!
|
118
|
+
@browser.quit if existing_browser?
|
119
|
+
@browser = nil
|
120
|
+
|
121
|
+
# Rethink how to do this. RSpec still references the driver pool.
|
122
|
+
Sauce.driver_pool[Thread.current.object_id] = nil
|
123
|
+
@using_rspec_browser = nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def render(path)
|
127
|
+
browser.save_screenshot path
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.configure_capybara
|
132
|
+
::Capybara.configure do |config|
|
133
|
+
if Sauce::Config.new[:start_local_application]
|
134
|
+
config.server_port = Sauce::Config.get_application_port
|
135
|
+
end
|
136
|
+
begin
|
137
|
+
#config.always_include_port = true
|
138
|
+
rescue
|
139
|
+
# This option is only in Capybara 2+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.configure_capybara_for_rspec
|
145
|
+
begin
|
146
|
+
require "rspec/core"
|
147
|
+
::RSpec.configure do |config|
|
148
|
+
config.before :suite do
|
149
|
+
::Capybara.configure do |capy_config|
|
150
|
+
sauce_config = Sauce::Config.new
|
151
|
+
if capy_config.app_host.nil?
|
152
|
+
if sauce_config[:start_local_application]
|
153
|
+
host = sauce_config[:application_host] || "127.0.0.1"
|
154
|
+
port = sauce_config[:application_port]
|
155
|
+
capy_config.app_host = "http://#{host}:#{port}"
|
156
|
+
capy_config.run_server = false
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
rescue LoadError => e
|
163
|
+
# User is not using RSpec
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
Capybara.register_driver :sauce do |app|
|
170
|
+
driver = Sauce::Capybara::Driver.new(app)
|
171
|
+
end
|
172
|
+
|
173
|
+
Sauce::Capybara.configure_capybara
|
174
|
+
|
175
|
+
# Monkeypatch Capybara to not use :selenium driver
|
176
|
+
require 'capybara/dsl'
|
177
|
+
module Capybara
|
178
|
+
def self.javascript_driver
|
179
|
+
@javascript_driver || :sauce
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
module Sauce
|
184
|
+
module RSpec
|
185
|
+
module SeleniumExampleGroup
|
186
|
+
Sauce::Capybara.configure_capybara_for_rspec
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|