cloud_test 1.0.7
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 +9 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +38 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +83 -0
- data/LICENSE.txt +21 -0
- data/README.md +184 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cloud_test.gemspec +48 -0
- data/config/cloudtest.config.bak.yml +19 -0
- data/exe/cloud_test +5 -0
- data/lib/cloud_test.rb +34 -0
- data/lib/cloud_test/browserstack.rb +77 -0
- data/lib/cloud_test/cli.rb +150 -0
- data/lib/cloud_test/core.rb +180 -0
- data/lib/cloud_test/cross_browser_testing.rb +71 -0
- data/lib/cloud_test/generators/cloud_test_env.rb +21 -0
- data/lib/cloud_test/generators/config.rb +21 -0
- data/lib/cloud_test/generators/configs/sample.cloud_test.browserstack.yml +20 -0
- data/lib/cloud_test/generators/configs/sample.cloud_test.crossbrowsertesting.yml +31 -0
- data/lib/cloud_test/generators/configs/sample.cloud_test.lambdatest.yml +22 -0
- data/lib/cloud_test/generators/configs/sample.cloud_test.rb +16 -0
- data/lib/cloud_test/generators/configs/sample.cloud_test.saucelabs.yml +14 -0
- data/lib/cloud_test/lambdatest.rb +62 -0
- data/lib/cloud_test/saucelabs.rb +58 -0
- data/lib/cloud_test/version.rb +3 -0
- metadata +191 -0
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "cloud_test"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/cloud_test.gemspec
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "cloud_test/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "cloud_test"
|
7
|
+
spec.version = CloudTest::VERSION
|
8
|
+
spec.authors = ["Philipp Häusele"]
|
9
|
+
spec.email = ["philipp.haeusele@makandra.de"]
|
10
|
+
|
11
|
+
spec.summary = %q{Enables automated Cloud-Testing with various providers. }
|
12
|
+
spec.description = %q{Enables cross-browser-testing with by the integration of the following providers Browserstack, Crossbrowsertesting, Saucelabs and lambdatest. Based on cucumber and capybara}
|
13
|
+
spec.homepage = "https://github.com/makandra/cloud_test"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
# spec.metadata["allowed_push_host"] = "RubyGems.org"
|
20
|
+
|
21
|
+
spec.metadata["homepage_uri"] = "https://github.com/makandra/cloud_test"
|
22
|
+
spec.metadata["source_code_uri"] = "https://github.com/makandra/cloud_test"
|
23
|
+
spec.metadata["changelog_uri"] = "https://github.com/makandra/cloud_test/CHANGELOG.md"
|
24
|
+
else
|
25
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
26
|
+
"public gem pushes."
|
27
|
+
end
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
spec.bindir = "exe"
|
35
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ["lib"]
|
37
|
+
|
38
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
39
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
40
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
41
|
+
|
42
|
+
spec.add_development_dependency "aruba"
|
43
|
+
|
44
|
+
spec.add_dependency "thor"
|
45
|
+
spec.add_dependency 'capybara'
|
46
|
+
spec.add_dependency "cucumber"
|
47
|
+
spec.add_development_dependency "selenium-webdriver"
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
server: "hub-cloud.browserstack.com"
|
2
|
+
user: "philipp127"
|
3
|
+
key: "vJwJsjXGMKeQw6vDus5x"
|
4
|
+
|
5
|
+
common_caps:
|
6
|
+
"browserstack.local": true
|
7
|
+
"browserstack.debug": true # Visual log
|
8
|
+
"acceptSslCerts": true # allow self signed certificates
|
9
|
+
"name": "Bstack-[Capybara] Local Test"
|
10
|
+
|
11
|
+
browser_caps:
|
12
|
+
IE:
|
13
|
+
"browser": "IE"
|
14
|
+
"browser_version": "11.0"
|
15
|
+
"os": "Windows"
|
16
|
+
"os_version": "7"
|
17
|
+
|
18
|
+
#
|
19
|
+
#curl -u "philipp127:vJwJsjXGMKeQw6vDus5x" -X PUT -H "Content-Type: application/json" -d "{\"status\":\"<new-status>\", \"reason\":\"<reason text>\"}" https://api.browserstack.com/automate/sessions/<session-id>.json
|
data/exe/cloud_test
ADDED
data/lib/cloud_test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "cloud_test/version"
|
2
|
+
require "cloud_test/core"
|
3
|
+
|
4
|
+
|
5
|
+
module CloudTest
|
6
|
+
class Error < StandardError; end
|
7
|
+
def self.enabled?
|
8
|
+
ENV.has_key?('CLOUD_TEST')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.upload_status_to_provider(success:, session_id:, reason: "Unknown")
|
12
|
+
begin
|
13
|
+
Core.upload_status success: success, session_id: session_id, reason: reason
|
14
|
+
rescue StandardError => e
|
15
|
+
puts e.message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
if enabled?
|
19
|
+
config = Core.load_config
|
20
|
+
CloudTest::Core.get_provider_class(config).init config
|
21
|
+
end
|
22
|
+
|
23
|
+
at_exit do # is this better in here or in the cloud_test.rb file with the Before tag?
|
24
|
+
if enabled?
|
25
|
+
if $!.nil? || $!.is_a?(SystemExit) && $!.success? # if test was successful
|
26
|
+
Core.list_dashboard_link
|
27
|
+
else
|
28
|
+
code = $!.is_a?(SystemExit) ? $!.status : 1 #if test was not successful, keep exit code
|
29
|
+
Core.list_dashboard_link
|
30
|
+
exit code
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative 'core'
|
2
|
+
|
3
|
+
module CloudTest
|
4
|
+
class Browserstack < Core
|
5
|
+
# do anything browserstack specific
|
6
|
+
SERVER = "hub-cloud.browserstack.com/wd/hub"
|
7
|
+
ENV_USER ='BROWSERSTACK_USERNAME'
|
8
|
+
ENV_PWD = 'BROWSERSTACK_ACCESS_KEY'
|
9
|
+
DASHBOARD_LINK = "https://automate.browserstack.com/dashboard"
|
10
|
+
REST_STATUS_SERVER = "https://api.browserstack.com/automate/sessions/"
|
11
|
+
|
12
|
+
def self.init(config=nil)
|
13
|
+
@config = config || Core.load_config(ENV_USER, ENV_PWD)
|
14
|
+
@caps = Core.get_default_caps
|
15
|
+
|
16
|
+
@caps["browserstack.local"] = true
|
17
|
+
@caps["browserstack.debug"] = true # Visual log
|
18
|
+
@caps['os_version'] = '10'
|
19
|
+
@caps['os'] = 'WINDOWS'
|
20
|
+
@caps['browser'] = 'CHROME'
|
21
|
+
|
22
|
+
@caps = Core.merge_caps(@caps, @config, 'browserstack')
|
23
|
+
Capybara.app_host = "http://127.0.0.1:38946"
|
24
|
+
Capybara.server_port = 38946
|
25
|
+
if !config.nil?
|
26
|
+
start()
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.start
|
31
|
+
puts '> Running features on browserstack.com'
|
32
|
+
begin
|
33
|
+
require 'browserstack/local'
|
34
|
+
rescue LoadError
|
35
|
+
puts 'Please add gem "browserstack-local" to your gemfile!'
|
36
|
+
raise LoadError
|
37
|
+
end
|
38
|
+
# Code to start browserstack local (tunnel) before start of test
|
39
|
+
@bs_local = BrowserStack::Local.new
|
40
|
+
bs_local_args = {"key" => "#{@config['key']}", "logfile" => "log/browserstack-local-logs.log"}
|
41
|
+
@bs_local.start(bs_local_args)
|
42
|
+
register_driver(@caps, @config['user'], @config['key'], SERVER)
|
43
|
+
# Code to stop browserstack local after end of test
|
44
|
+
at_exit do
|
45
|
+
@bs_local.stop unless @bs_local.nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.list_caps # defaults
|
50
|
+
Core.list_caps
|
51
|
+
puts "Browserstack specific defaults:"
|
52
|
+
puts "\tbrowserstack.local: true"
|
53
|
+
puts "\tbrowserstack.debug: true "
|
54
|
+
puts 'you can generate capabilities here https://www.browserstack.com/automate/capabilities?tag=selenium-2-3'
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.get_all_caps # dry run
|
58
|
+
@caps.kind_of?(Hash) || init()
|
59
|
+
puts "Capabilities: "
|
60
|
+
Core.list_these_caps(@caps)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.get_status_msg(failed, reason)
|
64
|
+
{
|
65
|
+
"status" => failed ? "passed" : "failed",
|
66
|
+
"reason" => reason
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.check_session_id(session_id)
|
71
|
+
unless session_id =~ Regexp.new('^[0-9a-z]{40}$')
|
72
|
+
puts session_id << "length: " << session_id.length
|
73
|
+
raise "session_id is invalid!"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'cloud_test/generators/config'
|
3
|
+
require 'cloud_test/generators/cloud_test_env'
|
4
|
+
require_relative 'browserstack'
|
5
|
+
require_relative 'lambdatest'
|
6
|
+
require_relative 'cross_browser_testing'
|
7
|
+
require_relative 'saucelabs'
|
8
|
+
|
9
|
+
|
10
|
+
module CloudTest
|
11
|
+
class CLI < Thor
|
12
|
+
desc "list-caps PROVIDER", "Shows the currently applied capabilities of that provider"
|
13
|
+
def list_caps(provider)
|
14
|
+
hash = {"provider" => provider}
|
15
|
+
Core.get_provider_class(hash).get_all_caps
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "list-default-caps PROVIDER", "Shows the default capabilities for that provider"
|
19
|
+
def list_default_caps(provider)
|
20
|
+
hash = {"provider" => provider}
|
21
|
+
Core.get_provider_class(hash).list_caps
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "generate config", "Puts a sample config yml file into /config directory"
|
25
|
+
def generate_config(config)
|
26
|
+
CloudTest::Generators::Config.start([config])
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "generate", "Puts a sample config yml file into /config directory, and additionally put a cloud_test.rb in features/support"
|
30
|
+
option :provider, :aliases => '-p', :default => 'browserstack'
|
31
|
+
def generate()
|
32
|
+
case options[:provider].to_s.downcase
|
33
|
+
when 'lambdatest', 'lt', 'l'
|
34
|
+
provider = 'lambdatest'
|
35
|
+
when 'crossbrowsertesting', 'cbs', 'ct', 'cbt', 'c'
|
36
|
+
provider = 'crossbrowsertesting'
|
37
|
+
when 'saucelabs', 'sauce', 'sc', 'sl', 's'
|
38
|
+
provider = 'saucelabs'
|
39
|
+
else
|
40
|
+
provider = 'browserstack'
|
41
|
+
end
|
42
|
+
CloudTest::Generators::Config.start([provider])
|
43
|
+
CloudTest::Generators::Support.start()
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "cucumber", "Runs bundle exec cucumber sequentially for all defined browsers. Uses the cucumber tag. With -q hide output."
|
47
|
+
option :q
|
48
|
+
def start()
|
49
|
+
require 'open3'
|
50
|
+
config = Core.load_config
|
51
|
+
config['browsers'].keys.each { |browser_config_name|
|
52
|
+
Open3.popen2e({'CLOUD_TEST' =>browser_config_name.to_s}, "bundle" ,"exec", "cucumber", "-t","#{config['cucumber_tag'].to_s}") do |stdin, stdout_err, wait_thr|
|
53
|
+
unless options[:q]
|
54
|
+
while line = stdout_err.gets
|
55
|
+
puts line
|
56
|
+
end
|
57
|
+
end
|
58
|
+
exit_status = wait_thr.value
|
59
|
+
if exit_status == 0
|
60
|
+
puts "Test on browser: #{browser_config_name} was successful!"
|
61
|
+
else
|
62
|
+
puts "Test on browser: #{browser_config_name} was not successful!"
|
63
|
+
puts stdout_err
|
64
|
+
raise "did not work"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "each COMMANDS", "Runs the COMMAND sequentially for all defined browsers. With -q hide output."
|
71
|
+
option :q
|
72
|
+
def each(*commands)
|
73
|
+
require 'open3'
|
74
|
+
config = Core.load_config
|
75
|
+
config['browsers'].keys.each { |browser_config_name|
|
76
|
+
Open3.popen2e({'CLOUD_TEST' =>browser_config_name.to_s}, commands.join(" ")) do |stdin, stdout_err, wait_thr|
|
77
|
+
unless options[:q]
|
78
|
+
while line = stdout_err.gets
|
79
|
+
puts line
|
80
|
+
end
|
81
|
+
end
|
82
|
+
exit_status = wait_thr.value
|
83
|
+
if exit_status == 0
|
84
|
+
puts "Test on browser: #{browser_config_name} was successful!"
|
85
|
+
else
|
86
|
+
puts "Error on browser: #{browser_config_name}!"
|
87
|
+
puts stdout_err.read
|
88
|
+
puts "Error on browser: #{browser_config_name}!"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "test-connection", "Test whether the provider and credentials work, by connectiong to the api"
|
95
|
+
def test_connection()
|
96
|
+
require 'net/http'
|
97
|
+
require 'uri'
|
98
|
+
config = CloudTest::Core.load_config
|
99
|
+
request, uri, request, server = Hash.new
|
100
|
+
if config.has_key?('provider') && config.has_key?('user') && config.has_key?('key')
|
101
|
+
case config.delete 'provider'.to_s.downcase
|
102
|
+
when 'browserstack', 'bs', 'b'
|
103
|
+
server = "https://www.browserstack.com/local/v1/list?auth_token=#{config['key']}&last=1"
|
104
|
+
when 'lambdatest', 'lt', 'l'
|
105
|
+
server = "https://api.lambdatest.com/automation/api/v1/tunnels"
|
106
|
+
uri = URI.parse(server)
|
107
|
+
request = Net::HTTP::Get.new(uri)
|
108
|
+
request.basic_auth(config['user'], config['key'])
|
109
|
+
when 'crossbrowsertesting', 'cbs', 'ct', 'cbt', 'c'
|
110
|
+
server = "https://crossbrowsertesting.com/api/v3/tunnels"
|
111
|
+
uri = URI.parse(server)
|
112
|
+
request = Net::HTTP::Get.new(uri)
|
113
|
+
request.basic_auth(config['user'].sub("@", "%40"), config['key'])
|
114
|
+
when 'saucelabs', 'sauce', 'sc', 'sl', 's'
|
115
|
+
server = "https://saucelabs.com/rest/v1/#{config['user']}/tunnels"
|
116
|
+
uri = URI.parse(server)
|
117
|
+
request = Net::HTTP::Get.new(uri)
|
118
|
+
request.basic_auth(config['user'], config['key'])
|
119
|
+
else
|
120
|
+
puts "Unknown provider!"
|
121
|
+
return
|
122
|
+
end
|
123
|
+
uri ||= URI.parse(server)
|
124
|
+
request ||= Net::HTTP::Get.new(uri)
|
125
|
+
request["Accept"] = "application/json"
|
126
|
+
req_options = {
|
127
|
+
use_ssl: uri.scheme == "https",
|
128
|
+
}
|
129
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
130
|
+
http.request(request)
|
131
|
+
end
|
132
|
+
if response.code == '200'
|
133
|
+
puts "Connection successful!"
|
134
|
+
else
|
135
|
+
puts "Connection was not successful! :("
|
136
|
+
puts response.code
|
137
|
+
end
|
138
|
+
else
|
139
|
+
puts "You have not all necessary keys in your config file. `provider`, `user`, `key` are necessary"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
desc 'version', 'Display version'
|
143
|
+
map %w[-v --version] => :version
|
144
|
+
|
145
|
+
def version
|
146
|
+
say "cloud_test version: #{CloudTest::VERSION}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'selenium/webdriver'
|
2
|
+
require 'capybara'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module CloudTest
|
6
|
+
class Core
|
7
|
+
CONFIG_NAME = 'cloud_test'
|
8
|
+
|
9
|
+
def self.get_default_caps
|
10
|
+
@caps = Hash.new
|
11
|
+
@caps['project'] = File.split(Dir.getwd)[-1] # folder name
|
12
|
+
@caps['build'] = `git rev-parse HEAD || echo buildname` # HEAD commit hash
|
13
|
+
@caps['name'] = `git log -1 --pretty=%B || echo testname` # HEAD commit message
|
14
|
+
return @caps
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.check_if_input_is_valid?(str)
|
18
|
+
#for all relevant config user input only allow an optional '@' for the cucumber_tag, then some letters, followed by
|
19
|
+
# optional digits
|
20
|
+
# this should enhance security
|
21
|
+
Regexp.new('^@?[A-z]+\d*$') =~ str
|
22
|
+
end
|
23
|
+
|
24
|
+
# the optional parameter could be deleted, or used if someone does not want to put there credentials in the config
|
25
|
+
def self.load_config(env_user='CLOUD_TEST_USER', env_pw='CLOUD_TEST_PW')
|
26
|
+
config = Hash.new
|
27
|
+
|
28
|
+
@caps = self.get_default_caps
|
29
|
+
path = `pwd`.to_s.gsub(/\s+/, "") + "/config/#{CONFIG_NAME}.yml" # complete path to the config file
|
30
|
+
begin
|
31
|
+
config = YAML.load_file(File.absolute_path path)
|
32
|
+
if ENV.has_key?(env_user) && ENV.has_key?(env_pw)
|
33
|
+
config['key'] = ENV[env_pw]
|
34
|
+
config['user'] = ENV[env_user]
|
35
|
+
end
|
36
|
+
rescue SystemCallError
|
37
|
+
puts 'Error: no config file found at: ' + path
|
38
|
+
puts 'Tip: You should run your tests from your main project directory'
|
39
|
+
puts 'Error: I need a config yml file, named ENV["CONFIG_NAME"] or "cloud_test.yml" which has at least a "user" and and "key" pair, thank you!'
|
40
|
+
else
|
41
|
+
if config.has_key?('user') && config.has_key?('key') && config.has_key?('provider') # check wether all the necessary keys exist
|
42
|
+
list_to_check_input = [config['browsers'].keys, (config['cucumber_tag'] if config.has_key?('cucumber_tag')), config['provider']].flatten
|
43
|
+
list_to_check_input.each do |str|
|
44
|
+
if !check_if_input_is_valid?(str)
|
45
|
+
raise "Invalid value: #{str}. Only characters followed by digits are allowed!"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return config
|
49
|
+
else
|
50
|
+
puts 'Error: I have a config yml file, but no user, key or provider value :('
|
51
|
+
puts "Keys: " + config.keys.to_s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.register_driver(capsArray, user, key, server)
|
57
|
+
# some debugging options
|
58
|
+
url = "https://#{user.sub("@", "%40")}:#{key}@#{server}"
|
59
|
+
if capsArray.has_key?('cloud_test_debug') and capsArray['cloud_test_debug']
|
60
|
+
puts "Capybara.app_host = #{Capybara.app_host}"
|
61
|
+
puts "Hub url: #{url}"
|
62
|
+
list_these_caps capsArray
|
63
|
+
end
|
64
|
+
Capybara.register_driver :cloud_test do |app|
|
65
|
+
Capybara::Selenium::Driver.new(app,
|
66
|
+
:browser => :remote,
|
67
|
+
:url => url,
|
68
|
+
:desired_capabilities => capsArray
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.list_caps # print defaults
|
74
|
+
# this output could be reformatted
|
75
|
+
puts 'These are the defaults:' + """
|
76
|
+
PROJECT : # name of the folder
|
77
|
+
BUILD : # HEAD commit hash
|
78
|
+
NAME : # HEAD commit message
|
79
|
+
OS : '10'
|
80
|
+
PLATFORM : 'WINDOWS'
|
81
|
+
BROWSER : 'CHROME'"""
|
82
|
+
puts 'Please add additional capabilities in the cloud_test.yml file'
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.list_these_caps(caps)
|
86
|
+
if caps.kind_of?(Enumerable)
|
87
|
+
caps.each do |key, value|
|
88
|
+
puts "|#{key.to_s.ljust(25)}|#{value.to_s.ljust(44)}|\n" # make a nice table like layout
|
89
|
+
end
|
90
|
+
else
|
91
|
+
puts "Error: No caps"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.copy_keys(caps, config, keys=config.keys) # a small helper method, to copy keys
|
96
|
+
keys.each do |key|
|
97
|
+
caps[key] = config[key]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.merge_caps(caps, config, provider=nil, browser=ENV['CLOUD_TEST']) # config overwrites in case of conflict
|
102
|
+
if !config.kind_of?(Hash)
|
103
|
+
return caps
|
104
|
+
end
|
105
|
+
keys = config.keys - ['common_caps', 'browsers'] # handle those seperatly
|
106
|
+
copy_keys caps, config, keys
|
107
|
+
if provider && config.has_key?(provider) && config[provider].class.included_modules.include?(Enumerable)
|
108
|
+
copy_keys caps, config[provider]
|
109
|
+
end
|
110
|
+
if config.has_key?('common_caps')
|
111
|
+
caps = caps.merge(config['common_caps'])
|
112
|
+
end
|
113
|
+
if config.has_key?('browsers')
|
114
|
+
if config['browsers'].kind_of?(Hash)
|
115
|
+
if !browser.nil? && config['browsers'][browser].nil?
|
116
|
+
puts "There is no browser with the key:#{browser} in your config file!"
|
117
|
+
raise "No matching browser key found!"
|
118
|
+
end
|
119
|
+
caps = caps.merge(config['browsers'][browser || config['browsers'].keys[0]])
|
120
|
+
else
|
121
|
+
caps = caps.merge(config['browsers'])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
return caps
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.get_provider_class(config=load_config)
|
128
|
+
case config.delete('provider').to_s.downcase
|
129
|
+
when 'browserstack', 'bs', 'b'
|
130
|
+
require 'cloud_test/browserstack'
|
131
|
+
return Browserstack
|
132
|
+
when 'lambdatest', 'lt', 'l'
|
133
|
+
require 'cloud_test/lambdatest'
|
134
|
+
return Lambdatest
|
135
|
+
when 'crossbrowsertesting', 'cbs', 'ct', 'cbt', 'c'
|
136
|
+
require 'cloud_test/cross_browser_testing'
|
137
|
+
return CrossBrowserTesting
|
138
|
+
when 'saucelabs', 'sauce', 'sc', 'sl', 's'
|
139
|
+
require 'cloud_test/saucelabs'
|
140
|
+
return Saucelabs
|
141
|
+
else
|
142
|
+
puts "Error: Please add a valid provider to your config file!"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.list_dashboard_link
|
147
|
+
puts "link to the dashboard: #{get_provider_class::DASHBOARD_LINK}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.upload_status(success:, session_id:, reason: "Unknown")
|
151
|
+
config = load_config
|
152
|
+
provider = get_provider_class config
|
153
|
+
provider.check_session_id session_id
|
154
|
+
puts session_id
|
155
|
+
unless provider::REST_STATUS_SERVER.present?
|
156
|
+
puts "skipping upload, not implementet for your provider yet."
|
157
|
+
return
|
158
|
+
end
|
159
|
+
require 'net/http'
|
160
|
+
require 'uri'
|
161
|
+
require 'json'
|
162
|
+
uri = URI.parse(provider::REST_STATUS_SERVER + session_id )
|
163
|
+
request = Net::HTTP::Put.new(uri)
|
164
|
+
request.basic_auth(config['user'], config['key'])
|
165
|
+
request.content_type = "application/json"
|
166
|
+
request.body = JSON.dump(provider.get_status_msg(success, reason))
|
167
|
+
req_options = {
|
168
|
+
use_ssl: uri.scheme == "https",
|
169
|
+
}
|
170
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
171
|
+
http.request(request)
|
172
|
+
end
|
173
|
+
if response.code != '200'
|
174
|
+
puts "Response Code: #{response.code}"
|
175
|
+
puts "Status upload error!"
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|