saucer 0.2.0
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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +91 -0
- data/Rakefile +6 -0
- data/lib/saucer/annotations.rb +44 -0
- data/lib/saucer/api.rb +59 -0
- data/lib/saucer/config/common.rb +22 -0
- data/lib/saucer/config/sauce.rb +58 -0
- data/lib/saucer/config/selenium.rb +37 -0
- data/lib/saucer/driver.rb +39 -0
- data/lib/saucer/parallel.rb +57 -0
- data/lib/saucer/platform_configuration.rb +23 -0
- data/lib/saucer/version.rb +3 -0
- data/lib/saucer.rb +5 -0
- data/saucer.gemspec +43 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 55a94b5cde4a3bf98c9a3e8975f623f42b72d01c
|
4
|
+
data.tar.gz: 3b792a0629f64db6eb9af000d830e3edb7d01143
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7ce5b1cfefb461d8e2d6202ab06b86bf29795d642a077c221eefb5e079a3deb61aafcc060f6ad9852155133da58881a37426cf5a0524ebfd0401fd2325b35bf6
|
7
|
+
data.tar.gz: 71830226607e765638ecfe360f0a902b59b528bb888a229c62c211eaf723513a1bfd15543d1954d3f5a03fb97c4a41ca7ced3ac07b036a0d032e486428405e4b
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Titus Fortner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Saucer
|
2
|
+
|
3
|
+
Convenience methods for running your Ruby tests on Sauce Labs
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'saucer'
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
#### Configuration
|
16
|
+
|
17
|
+
Can optionally pass in a `Config::Selenium` instance with any of the
|
18
|
+
[supported Test Configuration Options](https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options)
|
19
|
+
Note that Ruby syntax is a `Symbol` with snake_case and not `String` with camelCase
|
20
|
+
```ruby
|
21
|
+
config_selenium = Config::Selenium.new(version: '53', browser_name: :firefox)
|
22
|
+
@driver = Driver.new(config_selenium)
|
23
|
+
```
|
24
|
+
|
25
|
+
#### Cucumber
|
26
|
+
RSpec doesn't need to be concerned with this, but Cucumber needs an extra step in `env.rb`:
|
27
|
+
```ruby
|
28
|
+
Before do |scenario|
|
29
|
+
Saucer::Config::Sauce.scenario = scenario
|
30
|
+
@driver = Saucer::Driver.new
|
31
|
+
end
|
32
|
+
|
33
|
+
After do |scenario|
|
34
|
+
Saucer::Config::Sauce.scenario = scenario
|
35
|
+
@driver.quit
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
#### Parallel
|
40
|
+
The most basic usage for parallel execution is to define the following Rake task, which
|
41
|
+
will every spec in the spec directory in 4 processes on the default Sauce platform (Linux with Chrome v48)
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
Saucer::Parallel.new.run
|
45
|
+
```
|
46
|
+
|
47
|
+
To Specify basic number of processes, a specific subdirectory (Cucumber or RSpec), and
|
48
|
+
reporting output file:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Saucer::Parallel.new(number: 7,
|
52
|
+
path: 'features/foo',
|
53
|
+
output: 'foo').run
|
54
|
+
```
|
55
|
+
|
56
|
+
|
57
|
+
To specify Sauce configurations, create a Rake Task that takes parameters like this:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
task :parallel_sauce do
|
61
|
+
configs = [{os: :mac_10_10, browser: :chrome, browser_version: 38},
|
62
|
+
{os: :mac_10_11, browser: :firefox, browser_version: 46},
|
63
|
+
{os: :mac_10_8, browser: :chrome, browser_version: 42}]
|
64
|
+
|
65
|
+
platforms = configs.map { |c| Saucer::PlatformConfiguration.new(c) }
|
66
|
+
|
67
|
+
Saucer::Parallel.new(platforms: platforms).run
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
or you can use the default rake task and define your configurations in
|
72
|
+
`configs/platform_configs.yml` like this:
|
73
|
+
```yaml
|
74
|
+
- :os: :mac_10_10
|
75
|
+
:browser: :chrome
|
76
|
+
:browser_version: 38
|
77
|
+
- :os: :mac_10_11
|
78
|
+
:browser: :firefox
|
79
|
+
:browser_version: 46
|
80
|
+
- :os: :mac_10_8
|
81
|
+
:browser: :chrome
|
82
|
+
:browser_version: 42
|
83
|
+
```
|
84
|
+
|
85
|
+
## Contributing
|
86
|
+
|
87
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/saucer.
|
88
|
+
|
89
|
+
## License
|
90
|
+
|
91
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Saucer
|
2
|
+
module Annotations
|
3
|
+
|
4
|
+
def comment(comment)
|
5
|
+
driver.execute_script("sauce:context=#{comment}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def job_result(result)
|
9
|
+
raise ArgumentError, "invalid value for result" unless ['passed', 'failed', true, false].include?(result)
|
10
|
+
driver.execute_script("sauce:job-result=#{result}")
|
11
|
+
end
|
12
|
+
|
13
|
+
def job_name(name)
|
14
|
+
driver.execute_script("sauce:job-name=#{name}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def job_tags(tags)
|
18
|
+
tags = tags.join(',') if tags.is_a?(Array)
|
19
|
+
driver.execute_script("sauce:job-tags=#{tags}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def job_info(info)
|
23
|
+
raise ArgumentError, "job info must be JSON" unless info.is_a? JSON
|
24
|
+
driver.execute_script("sauce:job-info=#{info}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_name(name)
|
28
|
+
driver.execute_script("sauce:job-build=#{name}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop_vm
|
32
|
+
driver.execute_script("sauce: stop network")
|
33
|
+
end
|
34
|
+
|
35
|
+
def start_vm
|
36
|
+
driver.execute_script("sauce: start network")
|
37
|
+
end
|
38
|
+
|
39
|
+
def breakpoint
|
40
|
+
driver.execute_script("sauce: break")
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/saucer/api.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'sauce_whisk'
|
2
|
+
|
3
|
+
module Saucer
|
4
|
+
class API
|
5
|
+
|
6
|
+
def initialize(driver, config)
|
7
|
+
@driver = driver
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def jobs
|
12
|
+
SauceWhisk::Jobs
|
13
|
+
end
|
14
|
+
|
15
|
+
def assets
|
16
|
+
SauceWhisk::Assets
|
17
|
+
end
|
18
|
+
|
19
|
+
def accounts
|
20
|
+
SauceWhisk::Accounts
|
21
|
+
end
|
22
|
+
|
23
|
+
def tunnels
|
24
|
+
SauceWhisk::Tunnels.all
|
25
|
+
end
|
26
|
+
|
27
|
+
def job
|
28
|
+
jobs.fetch(@driver.session_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def account
|
32
|
+
accounts.fetch(@config.username)
|
33
|
+
end
|
34
|
+
|
35
|
+
def concurrency
|
36
|
+
accounts.concurrency_for(@config.username)
|
37
|
+
end
|
38
|
+
|
39
|
+
def tunnel(id)
|
40
|
+
tunnels.fetch(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def platforms
|
44
|
+
SauceWhisk::Sauce.platforms
|
45
|
+
end
|
46
|
+
|
47
|
+
def storage
|
48
|
+
@storage ||= SauceWhisk::Storage.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def service_status
|
52
|
+
SauceWhisk::Sauce.service_status
|
53
|
+
end
|
54
|
+
|
55
|
+
def total_job_count
|
56
|
+
SauceWhisk::Sauce.total_job_count
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Saucer
|
2
|
+
module Config
|
3
|
+
class Common
|
4
|
+
|
5
|
+
CONFIG_PARAMS = %i(auto_accept_alerts name build tags custom_data max_duration
|
6
|
+
command_timeout idle_timeout prerun executable args background
|
7
|
+
timeout tunnel_identifier parent_tunnel screen_resolution timezone
|
8
|
+
avoid_proxy public record_video video_upload_on_pass record_screenshots
|
9
|
+
record_logs capture_html priority webdriver_remote_quiet_exceptions).freeze
|
10
|
+
|
11
|
+
attr_reader :config_params, :username, :access_key
|
12
|
+
|
13
|
+
def initialize(opts = {})
|
14
|
+
@username = opts.delete(:username) || ENV['SAUCE_USERNAME']
|
15
|
+
@access_key = opts.delete(:access_key) || ENV['SAUCE_ACCESS_KEY']
|
16
|
+
|
17
|
+
@opts = opts
|
18
|
+
@config_params = CONFIG_PARAMS
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Saucer
|
2
|
+
module Config
|
3
|
+
class Sauce
|
4
|
+
|
5
|
+
def self.scenario=(scenario)
|
6
|
+
@@scenario = scenario
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.scenario
|
10
|
+
@@scenario
|
11
|
+
end
|
12
|
+
|
13
|
+
DATA_PARAMS = %i(name build language host_os version ci ip gems framework page_object harness).freeze
|
14
|
+
|
15
|
+
FRAMEWORKS = %w(capybara watir).freeze
|
16
|
+
PAGE_OBJECTS = %w(site_prism page-object watirsome watir_drops).freeze
|
17
|
+
|
18
|
+
def initialize(opt = {})
|
19
|
+
@gems = {}
|
20
|
+
Bundler.definition.dependencies.map(&:name).each do |gem_name|
|
21
|
+
@gems[gem_name] = Bundler.environment.specs.to_hash[gem_name].first.version.version
|
22
|
+
end
|
23
|
+
|
24
|
+
frameworks = @gems.select { |gem| FRAMEWORKS.include? gem }
|
25
|
+
@framework = frameworks.first if frameworks.size == 1
|
26
|
+
|
27
|
+
page_objects = @gems.select { |gem| PAGE_OBJECTS.include? gem }
|
28
|
+
@page_object = page_objects.first if page_objects.size == 1
|
29
|
+
|
30
|
+
@name = opt[:name] if opt.key? :name
|
31
|
+
@build = opt[:build] if opt.key? :build
|
32
|
+
|
33
|
+
if RSpec.respond_to?(:current_example) && !RSpec.current_example.nil?
|
34
|
+
@name ||= RSpec.current_example.full_description
|
35
|
+
@location = RSpec.current_example.location
|
36
|
+
@harness = ["rspec", @gems["rspec"]]
|
37
|
+
elsif @@scenario
|
38
|
+
@name ||= @@scenario.source.map(&:name).join(" ")
|
39
|
+
@location = @@scenario.location.to_s
|
40
|
+
@harness = ["cucumber", @gems["cucumber"]]
|
41
|
+
end
|
42
|
+
|
43
|
+
@language = 'Ruby'
|
44
|
+
@host_os = ::Selenium::WebDriver::Platform.os
|
45
|
+
@version = ::Selenium::WebDriver::Platform.ruby_version
|
46
|
+
@ci = ::Selenium::WebDriver::Platform.ci
|
47
|
+
@ip = ::Selenium::WebDriver::Platform.ip
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_hash
|
51
|
+
DATA_PARAMS.each_with_object({}) do |name, hash|
|
52
|
+
var = eval("@#{name}")
|
53
|
+
hash[name] = var if var
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Saucer
|
2
|
+
module Config
|
3
|
+
class Selenium < Common
|
4
|
+
|
5
|
+
CONFIG_PARAMS = %i(browser_name version platform selenium_version
|
6
|
+
chromedriver_version iedriver_version).freeze
|
7
|
+
|
8
|
+
def initialize(opt = {})
|
9
|
+
super
|
10
|
+
@config_params += CONFIG_PARAMS
|
11
|
+
end
|
12
|
+
|
13
|
+
def url
|
14
|
+
"https://#{@username}:#{@access_key}@ondemand.saucelabs.com:443/wd/hub"
|
15
|
+
end
|
16
|
+
|
17
|
+
def opts
|
18
|
+
{url: url, desired_capabilities: capabilities}
|
19
|
+
end
|
20
|
+
|
21
|
+
def capabilities
|
22
|
+
caps = @config_params.each_with_object({}) do |param, hash|
|
23
|
+
hash[param] = @opts[param] if @opts.key?(param)
|
24
|
+
hash[param] ||= ENV[param.to_s] if ENV[param.to_s]
|
25
|
+
end
|
26
|
+
sauce = Sauce.new.to_hash
|
27
|
+
caps[:name] = sauce.delete(:name)
|
28
|
+
caps[:build] = sauce.delete(:build)
|
29
|
+
|
30
|
+
caps[:"sauce:data"] = sauce.to_hash
|
31
|
+
browser_name = @opts[:browser_name] || :chrome
|
32
|
+
::Selenium::WebDriver::Remote::Capabilities.send(browser_name, caps)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Saucer
|
2
|
+
class Driver < Selenium::WebDriver::Driver
|
3
|
+
|
4
|
+
include Annotations
|
5
|
+
|
6
|
+
attr_reader :driver, :config
|
7
|
+
|
8
|
+
def initialize(config = nil)
|
9
|
+
@config = config || Config::Selenium.new
|
10
|
+
@driver = super Selenium::WebDriver::Remote::Bridge.new(@config.opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def sauce
|
14
|
+
@api ||= API.new(self, @config)
|
15
|
+
end
|
16
|
+
|
17
|
+
def quit(data = nil)
|
18
|
+
if data.is_a?(TrueClass) || data.is_a?(FalseClass)
|
19
|
+
result = data
|
20
|
+
elsif RSpec.current_example
|
21
|
+
exception = RSpec.current_example.exception
|
22
|
+
result = exception.nil?
|
23
|
+
elsif Saucer::Config::Sauce.scenario
|
24
|
+
exception = Saucer::Config::Sauce.scenario.exception
|
25
|
+
result = Saucer::Config::Sauce.scenario.passed?
|
26
|
+
end
|
27
|
+
|
28
|
+
if exception
|
29
|
+
@driver.comment "Error: #{exception.inspect}"
|
30
|
+
@driver.comment "Error Location: #{exception.backtrace.first}"
|
31
|
+
end
|
32
|
+
|
33
|
+
@driver.job_result(result) unless result.nil?
|
34
|
+
|
35
|
+
super(*[])
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'sauce_platforms'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Saucer
|
5
|
+
class Parallel
|
6
|
+
|
7
|
+
attr_accessor :number, :path, :output
|
8
|
+
|
9
|
+
def initialize(opt = {})
|
10
|
+
@number = opt[:number] || ENV['PARALLEL_PROCESSES']
|
11
|
+
@path = opt[:path] || ENV['TEST_PATH'] || "spec"
|
12
|
+
@output = opt[:output] || ENV['REPORT_OUTPUT'] || 'output'
|
13
|
+
@platforms = opt[:platforms] || []
|
14
|
+
if File.exist?('configs/platform_configs.yml')
|
15
|
+
yaml = YAML.load_file('configs/platform_configs.yml')
|
16
|
+
@platforms ||= yaml.map { |c| Saucer::PlatformConfiguration.new(c) }
|
17
|
+
end
|
18
|
+
@success = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
if @platforms.empty?
|
23
|
+
raise StandardError, "Tests failed!" unless execute_test
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
@platforms.each do |platform|
|
28
|
+
Rake::Task.define_task(platform.name) {
|
29
|
+
ENV['platform'] = platform.to_hash[:platform]
|
30
|
+
ENV['browser_name'] = platform.to_hash[:browserName]
|
31
|
+
ENV['version'] = platform.to_hash[:version]
|
32
|
+
|
33
|
+
begin
|
34
|
+
@result = execute_test
|
35
|
+
ensure
|
36
|
+
@success &= @result
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
Rake::MultiTask.define_task(sauce_tests: @platforms.map(&:name)) {
|
42
|
+
raise StandardError, "Tests failed!" unless @success
|
43
|
+
}.invoke
|
44
|
+
end
|
45
|
+
|
46
|
+
def execute_test
|
47
|
+
if path.include?('spec')
|
48
|
+
ENV['PARALLEL_SPLIT_TEST_PROCESSES'] = number.to_s if number
|
49
|
+
system "parallel_split_test #{path} --out #{@output}.xml"
|
50
|
+
elsif path.include?('features')
|
51
|
+
system "parallel_cucumber #{path} -o \"--format junit --out #{@output} --format pretty\" -n #{number.to_s}"
|
52
|
+
else
|
53
|
+
raise ArgumentError, "Unable to determine if using rspec or cucumber"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sauce_platforms'
|
2
|
+
|
3
|
+
module Saucer
|
4
|
+
class PlatformConfiguration
|
5
|
+
attr_accessor :browser, :os, :browser_version
|
6
|
+
|
7
|
+
def initialize(opt = {})
|
8
|
+
@browser = opt[:browser]
|
9
|
+
@os = opt[:os] || opt['os'].downcase.tr(' ', '_').tr(',', '_')
|
10
|
+
@browser_version = opt[:browser_version] || opt['short_version']
|
11
|
+
end
|
12
|
+
|
13
|
+
# TODO update for defaults
|
14
|
+
def to_hash
|
15
|
+
Platform.send(@os).send(@browser).send("v#{@browser_version}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def name
|
19
|
+
"#{@os}_#{@browser}_#{@browser_version}".to_sym
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/saucer.rb
ADDED
data/saucer.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "saucer/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "saucer"
|
8
|
+
spec.version = Saucer::VERSION
|
9
|
+
spec.authors = ["Titus Fortner"]
|
10
|
+
spec.email = ["titusfortner@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A Ruby helper for running tests in Sauce Labs}
|
13
|
+
spec.description = %q{A Ruby helper for running tests in Sauce Labs}
|
14
|
+
spec.homepage = "http://github.com/titusfortner/saucer"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
"public gem pushes."
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
+
|
37
|
+
spec.add_dependency 'parallel_split_test'
|
38
|
+
spec.add_dependency 'require_all'
|
39
|
+
spec.add_dependency 'selenium-webdriver'
|
40
|
+
spec.add_dependency 'sauce_whisk'
|
41
|
+
spec.add_dependency 'sauce_platforms'
|
42
|
+
spec.add_dependency 'json'
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saucer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Titus Fortner
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: parallel_split_test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
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
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: selenium-webdriver
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sauce_whisk
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sauce_platforms
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: json
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: A Ruby helper for running tests in Sauce Labs
|
140
|
+
email:
|
141
|
+
- titusfortner@gmail.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".rspec"
|
148
|
+
- ".travis.yml"
|
149
|
+
- Gemfile
|
150
|
+
- LICENSE.txt
|
151
|
+
- README.md
|
152
|
+
- Rakefile
|
153
|
+
- lib/saucer.rb
|
154
|
+
- lib/saucer/annotations.rb
|
155
|
+
- lib/saucer/api.rb
|
156
|
+
- lib/saucer/config/common.rb
|
157
|
+
- lib/saucer/config/sauce.rb
|
158
|
+
- lib/saucer/config/selenium.rb
|
159
|
+
- lib/saucer/driver.rb
|
160
|
+
- lib/saucer/parallel.rb
|
161
|
+
- lib/saucer/platform_configuration.rb
|
162
|
+
- lib/saucer/version.rb
|
163
|
+
- saucer.gemspec
|
164
|
+
homepage: http://github.com/titusfortner/saucer
|
165
|
+
licenses:
|
166
|
+
- MIT
|
167
|
+
metadata:
|
168
|
+
allowed_push_host: https://rubygems.org
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.5.2
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: A Ruby helper for running tests in Sauce Labs
|
189
|
+
test_files: []
|