saucer 0.6.5 → 1.0.0.alpha
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -1
- data/LICENSE.txt +1 -1
- data/README.md +70 -59
- data/Rakefile +5 -3
- data/lib/saucer.rb +17 -4
- data/lib/saucer/asset_management.rb +113 -0
- data/lib/saucer/custom_commands.rb +21 -0
- data/lib/saucer/data_collection.rb +47 -0
- data/lib/saucer/job_update.rb +26 -0
- data/lib/saucer/options.rb +85 -0
- data/lib/saucer/runners.rb +5 -0
- data/lib/saucer/runners/cucumber.rb +23 -0
- data/lib/saucer/runners/rspec.rb +23 -0
- data/lib/saucer/runners/unknown.rb +23 -0
- data/lib/saucer/session.rb +134 -0
- data/lib/saucer/version.rb +3 -1
- data/saucer.gemspec +25 -25
- metadata +38 -57
- data/lib/saucer/annotations.rb +0 -44
- data/lib/saucer/api.rb +0 -57
- data/lib/saucer/config/common.rb +0 -23
- data/lib/saucer/config/sauce.rb +0 -67
- data/lib/saucer/config/selenium.rb +0 -39
- data/lib/saucer/driver.rb +0 -48
- data/lib/saucer/parallel.rb +0 -57
- data/lib/saucer/patches/sauce_whisk.rb +0 -7
- data/lib/saucer/platform_configuration.rb +0 -22
- data/lib/saucer/sauce.rb +0 -20
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Saucer
|
4
|
+
class Options
|
5
|
+
W3C = %i[browser_name browser_version platform_name accept_insecure_certs page_load_strategy proxy set_window_rect
|
6
|
+
timeouts strict_file_interactability unhandled_prompt_behavior].freeze
|
7
|
+
|
8
|
+
SAUCE = %i[access_key appium_version avoid_proxy build capture_html chromedriver_version command_timeout
|
9
|
+
crmuxdriver_version custom_data disable_popup_handler extended_debugging firefox_adapter_version
|
10
|
+
firefox_profile_url idle_timeout iedriver_version max_duration name parent_tunnel passed prerun
|
11
|
+
prevent_Requeue priority proxy_host public record_logs record_screenshots record_video
|
12
|
+
restricted_public_info screen_resolution selenium_version source tags time_zone tunnel_identifier
|
13
|
+
username video_upload_on_pass].freeze
|
14
|
+
|
15
|
+
VALID = W3C + SAUCE
|
16
|
+
|
17
|
+
attr_accessor :url, :scenario
|
18
|
+
attr_reader :data_center
|
19
|
+
|
20
|
+
def initialize(**opts)
|
21
|
+
VALID.each do |option|
|
22
|
+
self.class.__send__(:attr_accessor, option)
|
23
|
+
next unless opts.key?(option)
|
24
|
+
|
25
|
+
instance_variable_set("@#{option}", opts.delete(option))
|
26
|
+
end
|
27
|
+
|
28
|
+
validate_credentials
|
29
|
+
@browser_name ||= 'firefox'
|
30
|
+
@platform_name ||= 'Windows 10'
|
31
|
+
@browser_version ||= 'latest'
|
32
|
+
@selenium_version ||= '3.141.59'
|
33
|
+
|
34
|
+
opts.key?(:url) ? @url = opts[:url] : self.data_center = :US_WEST
|
35
|
+
@scenario = opts[:scenario] if opts.key?(:scenario)
|
36
|
+
end
|
37
|
+
|
38
|
+
def capabilities
|
39
|
+
w3c = W3C.each_with_object({}) do |option, hash|
|
40
|
+
value = instance_variable_get("@#{option}")
|
41
|
+
next if value.nil?
|
42
|
+
|
43
|
+
hash[option] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
sauce = SAUCE.each_with_object({}) do |option, hash|
|
47
|
+
value = instance_variable_get("@#{option}")
|
48
|
+
next if value.nil?
|
49
|
+
|
50
|
+
hash[option] = value
|
51
|
+
end
|
52
|
+
|
53
|
+
w3c.merge('sauce:options' => sauce)
|
54
|
+
end
|
55
|
+
alias to_h capabilities
|
56
|
+
|
57
|
+
def data_center=(data_center)
|
58
|
+
@url = case data_center
|
59
|
+
when :US_WEST
|
60
|
+
'https://ondemand.saucelabs.com:443/wd/hub'
|
61
|
+
when :US_EAST
|
62
|
+
'https://us-east-1.saucelabs.com:443/wd/hub'
|
63
|
+
when :EU_VDC
|
64
|
+
'https://ondemand.eu-central-1.saucelabs.com:443/wd/hub'
|
65
|
+
else
|
66
|
+
raise ::ArgumentError, "#{data_center} is an invalid data center; specify :US_WEST, :US_EAST or :EU_VDC"
|
67
|
+
end
|
68
|
+
@data_center = data_center
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def validate_credentials
|
74
|
+
@username ||= ENV['SAUCE_USERNAME']
|
75
|
+
msg = "No valid username found; either pass the value into `Options#new` or set with ENV['SAUCE_USERNAME']"
|
76
|
+
raise AuthenticationError, msg if @username.nil?
|
77
|
+
|
78
|
+
@access_key ||= ENV['SAUCE_ACCESS_KEY']
|
79
|
+
return unless @access_key.nil?
|
80
|
+
|
81
|
+
msg = "No valid access key found; either pass the value into `Options#new` or set with ENV['SAUCE_ACCESS_KEY']"
|
82
|
+
raise AuthenticationError, msg
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Saucer
|
4
|
+
class Cucumber
|
5
|
+
class << self
|
6
|
+
def test_name
|
7
|
+
scenario.source.map(&:name).join(' ')
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
:cucumber
|
12
|
+
end
|
13
|
+
|
14
|
+
def result
|
15
|
+
scenario.passed?
|
16
|
+
end
|
17
|
+
|
18
|
+
def exception
|
19
|
+
scenario.exception
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Saucer
|
4
|
+
class Rspec
|
5
|
+
class << self
|
6
|
+
def test_name
|
7
|
+
RSpec.current_example.full_description
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
:rspec
|
12
|
+
end
|
13
|
+
|
14
|
+
def result
|
15
|
+
RSpec.current_example.exception.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def exception
|
19
|
+
RSpec.current_example.exception
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sauce_whisk'
|
4
|
+
|
5
|
+
module Saucer
|
6
|
+
class Session
|
7
|
+
class << self
|
8
|
+
def runner
|
9
|
+
if RSpec.respond_to?(:current_example) && !RSpec.current_example.nil?
|
10
|
+
Rspec
|
11
|
+
elsif @scenario
|
12
|
+
Cucumber
|
13
|
+
else
|
14
|
+
Unknown
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def begin(options = nil, scenario: nil)
|
19
|
+
options ||= Options.new(scenario: scenario)
|
20
|
+
options.name ||= test_name if test_name
|
21
|
+
options.build ||= build_name
|
22
|
+
|
23
|
+
driver = Selenium::WebDriver.for :remote, url: options.url, desired_capabilities: options.capabilities
|
24
|
+
new(driver, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_name
|
28
|
+
runner.test_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_name
|
32
|
+
if ENV['BUILD_NAME']
|
33
|
+
ENV['BUILD_NAME']
|
34
|
+
elsif ENV['BUILD_TAG']
|
35
|
+
ENV['BUILD_TAG']
|
36
|
+
elsif ENV['TRAVIS_JOB_NUMBER']
|
37
|
+
"#{ENV['TRAVIS_REPO_SLUG'][%r{[^/]+$}]}: #{ENV['TRAVIS_JOB_NUMBER']}"
|
38
|
+
elsif ENV['SAUCE_BAMBOO_BUILDNUMBER']
|
39
|
+
ENV['SAUCE_BAMBOO_BUILDNUMBER']
|
40
|
+
elsif ENV['CIRCLE_BUILD_NUM']
|
41
|
+
"#{ENV['CIRCLE_JOB']}: #{ENV['CIRCLE_BUILD_NUM']}"
|
42
|
+
else
|
43
|
+
"Local Execution - #{Time.now.to_i}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_accessor :tags, :data
|
49
|
+
attr_reader :driver, :options, :job_id, :scenario, :runner
|
50
|
+
|
51
|
+
include CustomCommands
|
52
|
+
include JobUpdate
|
53
|
+
include AssetManagement
|
54
|
+
|
55
|
+
def initialize(driver, options)
|
56
|
+
@driver = driver
|
57
|
+
@options = options
|
58
|
+
@job_id = driver.session_id
|
59
|
+
@tags = []
|
60
|
+
@scenario = options.scenario
|
61
|
+
@runner = self.class.runner
|
62
|
+
@data = generate_data
|
63
|
+
|
64
|
+
SauceWhisk.data_center = options.data_center
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_data
|
68
|
+
data_collection = DataCollection.new
|
69
|
+
|
70
|
+
opt = {selenium_version: data_collection.selenium_version,
|
71
|
+
test_library: data_collection.test_library,
|
72
|
+
page_objects: data_collection.page_objects,
|
73
|
+
test_runner: data_collection.test_runner(runner),
|
74
|
+
language: "Ruby v#{Selenium::WebDriver::Platform.ruby_version}",
|
75
|
+
operating_system: Selenium::WebDriver::Platform.os}
|
76
|
+
opt[:ci_tool] = Selenium::WebDriver::Platform.ci if Selenium::WebDriver::Platform.ci
|
77
|
+
opt
|
78
|
+
end
|
79
|
+
|
80
|
+
def end
|
81
|
+
self.result = runner.result unless runner.result.nil?
|
82
|
+
|
83
|
+
if runner.exception
|
84
|
+
data[:error] = runner.exception.inspect
|
85
|
+
data[:stacktrace] = runner.exception.backtrace
|
86
|
+
end
|
87
|
+
|
88
|
+
save
|
89
|
+
driver.quit
|
90
|
+
|
91
|
+
wait_until_finished
|
92
|
+
end
|
93
|
+
|
94
|
+
def wait_until_finished
|
95
|
+
start_time = Time.now
|
96
|
+
loop do
|
97
|
+
break if finished? || Time.now - start_time > 10
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def finished?
|
102
|
+
details.end_time
|
103
|
+
end
|
104
|
+
|
105
|
+
def result=(res)
|
106
|
+
SauceWhisk::Jobs.change_status(@job_id, res)
|
107
|
+
end
|
108
|
+
|
109
|
+
def stop
|
110
|
+
SauceWhisk::Jobs.stop(@job_id)
|
111
|
+
end
|
112
|
+
|
113
|
+
def delete
|
114
|
+
start_time = Time.now
|
115
|
+
begin
|
116
|
+
response = JSON.parse SauceWhisk::Jobs.delete_job(@job_id).body
|
117
|
+
raise APIError, "Can not delete job: #{response['error']}" if response.key?('error')
|
118
|
+
rescue APIError
|
119
|
+
retry if Time.now - start_time < 5
|
120
|
+
raise
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def details
|
125
|
+
SauceWhisk::Jobs.fetch(@job_id)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def job
|
131
|
+
@job ||= SauceWhisk::Jobs.fetch(@job_id)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/saucer/version.rb
CHANGED
data/saucer.gemspec
CHANGED
@@ -1,43 +1,43 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'saucer/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'saucer'
|
8
9
|
spec.version = Saucer::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Titus Fortner']
|
11
|
+
spec.email = ['titusfortner@gmail.com']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'A Ruby helper for running tests in Sauce Labs'
|
14
|
+
spec.description = 'A Ruby helper for running tests in Sauce Labs'
|
15
|
+
spec.homepage = 'http://github.com/titusfortner/saucer'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
20
|
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata[
|
21
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
22
|
else
|
22
|
-
raise
|
23
|
-
|
23
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
24
|
+
'public gem pushes.'
|
24
25
|
end
|
25
26
|
|
26
|
-
spec.files
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
28
|
f.match(%r{^(test|spec|features)/})
|
28
29
|
end
|
29
|
-
spec.bindir =
|
30
|
+
spec.bindir = 'exe'
|
30
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
-
spec.require_paths = [
|
32
|
+
spec.require_paths = ['lib']
|
32
33
|
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
34
|
+
spec.add_development_dependency 'rake'
|
35
|
+
spec.add_development_dependency 'rspec'
|
36
|
+
spec.add_development_dependency 'rubocop', '~>0.66'
|
37
|
+
spec.add_development_dependency 'rubocop-performance'
|
38
|
+
spec.add_development_dependency 'rubocop-rspec', '~>1.32'
|
36
39
|
|
37
|
-
spec.
|
38
|
-
spec.
|
39
|
-
spec.
|
40
|
-
spec.add_dependency 'sauce_whisk'
|
41
|
-
spec.add_dependency 'sauce_platforms'
|
42
|
-
spec.add_dependency 'json'
|
40
|
+
spec.add_runtime_dependency 'json'
|
41
|
+
spec.add_runtime_dependency 'sauce_whisk'
|
42
|
+
spec.add_runtime_dependency 'selenium-webdriver'
|
43
43
|
end
|
metadata
CHANGED
@@ -1,79 +1,65 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Titus Fortner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubocop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0.66'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0.66'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rubocop-performance
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
type: :
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: require_all
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
62
|
+
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
@@ -81,27 +67,21 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: rubocop-rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: 3.4.4
|
93
|
-
type: :runtime
|
75
|
+
version: '1.32'
|
76
|
+
type: :development
|
94
77
|
prerelease: false
|
95
78
|
version_requirements: !ruby/object:Gem::Requirement
|
96
79
|
requirements:
|
97
80
|
- - "~>"
|
98
81
|
- !ruby/object:Gem::Version
|
99
|
-
version: '
|
100
|
-
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 3.4.4
|
82
|
+
version: '1.32'
|
103
83
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
84
|
+
name: json
|
105
85
|
requirement: !ruby/object:Gem::Requirement
|
106
86
|
requirements:
|
107
87
|
- - ">="
|
@@ -115,7 +95,7 @@ dependencies:
|
|
115
95
|
- !ruby/object:Gem::Version
|
116
96
|
version: '0'
|
117
97
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
98
|
+
name: sauce_whisk
|
119
99
|
requirement: !ruby/object:Gem::Requirement
|
120
100
|
requirements:
|
121
101
|
- - ">="
|
@@ -129,7 +109,7 @@ dependencies:
|
|
129
109
|
- !ruby/object:Gem::Version
|
130
110
|
version: '0'
|
131
111
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
112
|
+
name: selenium-webdriver
|
133
113
|
requirement: !ruby/object:Gem::Requirement
|
134
114
|
requirements:
|
135
115
|
- - ">="
|
@@ -152,21 +132,22 @@ files:
|
|
152
132
|
- ".gitignore"
|
153
133
|
- ".rspec"
|
154
134
|
- ".travis.yml"
|
135
|
+
- CHANGELOG.md
|
155
136
|
- Gemfile
|
156
137
|
- LICENSE.txt
|
157
138
|
- README.md
|
158
139
|
- Rakefile
|
159
140
|
- lib/saucer.rb
|
160
|
-
- lib/saucer/
|
161
|
-
- lib/saucer/
|
162
|
-
- lib/saucer/
|
163
|
-
- lib/saucer/
|
164
|
-
- lib/saucer/
|
165
|
-
- lib/saucer/
|
166
|
-
- lib/saucer/
|
167
|
-
- lib/saucer/
|
168
|
-
- lib/saucer/
|
169
|
-
- lib/saucer/
|
141
|
+
- lib/saucer/asset_management.rb
|
142
|
+
- lib/saucer/custom_commands.rb
|
143
|
+
- lib/saucer/data_collection.rb
|
144
|
+
- lib/saucer/job_update.rb
|
145
|
+
- lib/saucer/options.rb
|
146
|
+
- lib/saucer/runners.rb
|
147
|
+
- lib/saucer/runners/cucumber.rb
|
148
|
+
- lib/saucer/runners/rspec.rb
|
149
|
+
- lib/saucer/runners/unknown.rb
|
150
|
+
- lib/saucer/session.rb
|
170
151
|
- lib/saucer/version.rb
|
171
152
|
- saucer.gemspec
|
172
153
|
homepage: http://github.com/titusfortner/saucer
|
@@ -185,12 +166,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
185
166
|
version: '0'
|
186
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
168
|
requirements:
|
188
|
-
- - "
|
169
|
+
- - ">"
|
189
170
|
- !ruby/object:Gem::Version
|
190
|
-
version:
|
171
|
+
version: 1.3.1
|
191
172
|
requirements: []
|
192
173
|
rubyforge_project:
|
193
|
-
rubygems_version: 2.5.2
|
174
|
+
rubygems_version: 2.5.2.3
|
194
175
|
signing_key:
|
195
176
|
specification_version: 4
|
196
177
|
summary: A Ruby helper for running tests in Sauce Labs
|