theotokos 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE +20 -0
- data/README.md +16 -0
- data/Rakefile +30 -0
- data/bin/theotokos +20 -0
- data/html/Chart.min.js +10 -0
- data/html/bootstrap-collapse.js +167 -0
- data/html/bootstrap.min.css +9 -0
- data/html/jquery.min.js +2 -0
- data/lib/assertion/test_assertion.rb +44 -0
- data/lib/config/app_config_params.rb +40 -0
- data/lib/config/app_logger.rb +48 -0
- data/lib/engine/execution_initializer.rb +115 -0
- data/lib/engine/executor.rb +128 -0
- data/lib/engine/parser.rb +39 -0
- data/lib/engine/soap_executor.rb +101 -0
- data/lib/helper/app_helper.rb +99 -0
- data/lib/helper/hook_helper.rb +49 -0
- data/lib/helper/html_helper.rb +633 -0
- data/lib/model/execution.rb +16 -0
- data/lib/model/test.rb +79 -0
- data/lib/model/test_app_result.rb +91 -0
- data/lib/model/test_result.rb +22 -0
- data/lib/model/test_status.rb +68 -0
- data/lib/model/test_suite.rb +80 -0
- data/lib/model/test_suite_result.rb +54 -0
- data/lib/model/text_operator.rb +34 -0
- data/lib/model/ws_config.rb +48 -0
- data/lib/net/soap_net.rb +58 -0
- data/lib/report/chart_factory.rb +68 -0
- data/lib/report/console.rb +94 -0
- data/lib/report/default_locale +64 -0
- data/lib/report/html.rb +55 -0
- data/lib/report/json.rb +19 -0
- data/lib/report/reporter.rb +76 -0
- data/lib/requires.rb +43 -0
- data/lib/theotokos.rb +56 -0
- data/lib/version.rb +8 -0
- data/test/app-cfg.yml +10 -0
- data/test/config/ws-config.yml +8 -0
- data/test/unit/assertion/test_test_assertion.rb +72 -0
- data/test/unit/config/test_app_config_params.rb +35 -0
- data/test/unit/engine/test_execution_initializer.rb +22 -0
- data/test/unit/engine/test_parser.rb +35 -0
- data/test/unit/model/test_execution.rb +29 -0
- data/test/unit/model/test_test.rb +42 -0
- data/test/unit/model/test_test_app_result.rb +115 -0
- data/test/unit/model/test_test_status.rb +66 -0
- data/test/unit/model/test_test_suite.rb +92 -0
- data/test/unit/model/test_test_suite_result.rb +77 -0
- data/test/unit/model/test_text_operator.rb +40 -0
- data/test/unit/model/test_ws_config.rb +31 -0
- data/test/unit/report/test_json.rb +42 -0
- data/test/ws-test-models/do_something.yml +9 -0
- data/test/ws-test-models/project1/look_for_stuff.yml +4 -0
- data/theotokos.gemspec +25 -0
- metadata +155 -0
data/lib/model/test.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class Test
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@error_expected = @skip = false
|
8
|
+
yield self if block_given?
|
9
|
+
|
10
|
+
@tags ||= []
|
11
|
+
@input ||= {}
|
12
|
+
@output ||= {}
|
13
|
+
@ws_security ||= {}
|
14
|
+
|
15
|
+
_config_tags @tags
|
16
|
+
_validation
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_accessor :name, :description, :tags, :input, :output, :ws_security, :error_expected, :error, :skip
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
{ :name => @name, :description => @description, :error_expected => @error_expected,
|
23
|
+
:tags => @tags, :input => @input, :output => @output, :ws_security => @ws_security, :skip => @skip }
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_tag?(tag)
|
27
|
+
@tags.each {|t| return true if tag == t }
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def _config_tags(t)
|
33
|
+
self.tags = if t.instance_of? String
|
34
|
+
t.split(/[,\s]/).select {|t| !t.empty? }
|
35
|
+
elsif t.instance_of? Array
|
36
|
+
t
|
37
|
+
else
|
38
|
+
[]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def _validation
|
43
|
+
_validate_input
|
44
|
+
_validate_output
|
45
|
+
_validate_ws_security
|
46
|
+
end
|
47
|
+
|
48
|
+
def _validate_input
|
49
|
+
raise 'Input of test model must be a Hash' unless @input.instance_of? Hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def _validate_output
|
53
|
+
raise 'Output of test model must be a Hash' unless @output.instance_of? Hash
|
54
|
+
if @output['file']
|
55
|
+
raise "test > output > file >> '#{@output['file']}' does not exist" unless File.exist? Helper.format_ws_output_path(@output['file'])
|
56
|
+
end
|
57
|
+
|
58
|
+
if @output['text']
|
59
|
+
raise 'test > output > text must be a Hash' unless @output['text'].instance_of? Hash
|
60
|
+
hash = @output['text']
|
61
|
+
unless (hash.has_key?('equals') || hash.has_key?('contains') || hash.has_key?('not_contains') || hash.has_key?('regex'))
|
62
|
+
raise 'test > output > text must have one o those keys [equals, contains, not_contains, regex]'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def _validate_ws_security
|
68
|
+
raise 'Ws-security of test model must be a Hash' unless @ws_security.instance_of? Hash
|
69
|
+
unless @ws_security.keys.empty?
|
70
|
+
unless (@ws_security.has_key?('login') && @ws_security.has_key?('password'))
|
71
|
+
raise 'test > output > ws-security must have configured login and password keys'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TestAppResult
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@success = false
|
8
|
+
@broken_suites = []
|
9
|
+
yield self if block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :suites, :date_report
|
13
|
+
attr_reader :total_failures, :total_success, :broken_suites
|
14
|
+
|
15
|
+
def calculate_totals
|
16
|
+
@total_failures = @total_success = 0
|
17
|
+
@broken_suites.clear
|
18
|
+
return if @suites.nil?
|
19
|
+
|
20
|
+
@suites.each do |suite|
|
21
|
+
suite.calculate_totals
|
22
|
+
if suite.error?
|
23
|
+
@total_failures += 1
|
24
|
+
@broken_suites << suite
|
25
|
+
end
|
26
|
+
@total_success += 1 if suite.success?
|
27
|
+
end
|
28
|
+
|
29
|
+
@success = @total_failures == 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def success?
|
33
|
+
@success
|
34
|
+
end
|
35
|
+
|
36
|
+
def error?
|
37
|
+
!success?
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_suites
|
41
|
+
(@suites.nil?) ? 0 : @suites.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def total_test_cases
|
45
|
+
return 0 if @suites.nil?
|
46
|
+
|
47
|
+
total = 0
|
48
|
+
@suites.each {|suite| total += suite.test_results.size }
|
49
|
+
total
|
50
|
+
end
|
51
|
+
|
52
|
+
def success_failures_stats
|
53
|
+
{
|
54
|
+
:success => { :total => @total_success, :stat => ((@total_success * 100 / @suites.size).to_f.round 2) },
|
55
|
+
:failures => { :total => @total_failures, :stat => ((@total_failures * 100 / @suites.size).to_f.round 2) }
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def tags_stats
|
60
|
+
tags = {}
|
61
|
+
@suites.each do |suite|
|
62
|
+
suite.test_results.each do |test|
|
63
|
+
test_tags = suite.model.tags | test.tags
|
64
|
+
if test_tags.empty?
|
65
|
+
tags[:none] = tags[:none].to_i + 1
|
66
|
+
next
|
67
|
+
end
|
68
|
+
|
69
|
+
test_tags.each {|tag| tags[tag.to_sym] = tags[tag.to_sym].to_i + 1 }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
total = self.total_test_cases.to_f
|
74
|
+
tags.each do |k, v|
|
75
|
+
stat = (v * 100 / total).to_f.round 2
|
76
|
+
tags[k] = { :total => v, :stat => stat }
|
77
|
+
end
|
78
|
+
|
79
|
+
tags
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_hash
|
83
|
+
{ :total_failures => @total_failures, :total_success => @total_success, :date_report => @date_report,
|
84
|
+
:broken_suites => ((@broken_suites) ? @broken_suites.map {|s| s.to_hash } : @broken_suites),
|
85
|
+
:suites => ((@suites) ? @suites.map {|s| s.to_hash } : @suites) }
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TestResult
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@error_expected = skip = false
|
8
|
+
yield self if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :name, :description, :tags, :status, :error, :test_expectation, :test_actual, :error_expected, :filter, :skip
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
{ :name => @name, :description => @description, :tags => @tags, :status => ((@status) ? @status.to_hash : @status),
|
15
|
+
:error => @error, :test_expectation => @test_expectation, :test_actual => @test_actual,
|
16
|
+
:error_expected => @error_expected, :filter => ((@filter) ? @filter.to_hash : @filter), :skip => @skip }
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TestStatus
|
5
|
+
|
6
|
+
def initialize(opt = {})
|
7
|
+
if block_given?
|
8
|
+
yield self
|
9
|
+
else
|
10
|
+
_load_properties opt
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :test_file_status, :test_text_status
|
15
|
+
attr_writer :error
|
16
|
+
|
17
|
+
def success?
|
18
|
+
return !@error unless @error.nil?
|
19
|
+
|
20
|
+
if (@test_file_status.nil? && @test_text_status.nil?)
|
21
|
+
nil
|
22
|
+
elsif (@test_file_status == true)
|
23
|
+
(@test_text_status.nil? || _validate_test_text_status == true)
|
24
|
+
elsif (_validate_test_text_status == true)
|
25
|
+
(@test_file_status == true || @test_file_status.nil?)
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def error?
|
32
|
+
return @error unless @error.nil?
|
33
|
+
|
34
|
+
ok = success?
|
35
|
+
ok.nil? ? nil : !ok
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"Model::TestStatus @error: #{@error}, @test_file_status: #{@test_file_status}, @test_text_status: #{@test_text_status}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_hash
|
43
|
+
{ :test_file_status => @test_file_status, :test_text_status => @test_text_status,
|
44
|
+
:error => @error }
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def _load_properties(opt)
|
49
|
+
@test_file_status = opt[:test_file_status]
|
50
|
+
@test_text_status = opt[:test_text_status]
|
51
|
+
@error = opt[:error]
|
52
|
+
end
|
53
|
+
|
54
|
+
def _validate_test_text_status
|
55
|
+
ok = false
|
56
|
+
return ok if @test_text_status.nil?
|
57
|
+
|
58
|
+
@test_text_status.each_value do |v|
|
59
|
+
ok = v
|
60
|
+
break if ok == false
|
61
|
+
end
|
62
|
+
ok
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TestSuite
|
5
|
+
|
6
|
+
def initialize(opt = {})
|
7
|
+
if block_given?
|
8
|
+
yield self
|
9
|
+
_config_tags @tags
|
10
|
+
else
|
11
|
+
_load_properties opt
|
12
|
+
end
|
13
|
+
@tests ||= Array.new
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :source, :wsdl, :service, :description, :tags, :tests
|
17
|
+
|
18
|
+
def validate_model!
|
19
|
+
raise Exception, 'WS test model must be provided.' if @source.nil? || @source.empty?
|
20
|
+
raise Exception, "WSDL's URL must be provided." if @wsdl.nil? || @wsdl.empty?
|
21
|
+
raise Exception, 'Service name (service to be tested) must be provided.' if @service.nil? || @service.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_tag?(tag)
|
25
|
+
(@tags + @tests.map {|t| t.tags }.flatten).each {|t| return true if t == tag }
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
regex = Regexp.new ENV['ws.test.models.path'].sub(/\/$/, '')
|
31
|
+
name =@source.sub regex, ''
|
32
|
+
name.sub! /^\//, ''
|
33
|
+
|
34
|
+
name.sub('.yml', '').split('/').join('_')
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
{ :source => @source, :wsdl => @wsdl, :service => @service, :descriptio => @description,
|
39
|
+
:tags => @tags, :tests => ((@tests) ? @tests.map {|t| t.to_hash } : @tests) }
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def _load_properties(opt)
|
44
|
+
self.source = opt[:source]
|
45
|
+
self.wsdl = opt[:wsdl]
|
46
|
+
self.service = opt[:service]
|
47
|
+
self.description = opt[:description]
|
48
|
+
|
49
|
+
_config_tags opt[:tags]
|
50
|
+
@tests = _load_tests opt[:tests]
|
51
|
+
end
|
52
|
+
|
53
|
+
def _config_tags(t)
|
54
|
+
self.tags = if t.instance_of? String
|
55
|
+
t.split(/[,\s]/).select {|t| !t.empty? }
|
56
|
+
elsif t.instance_of? Array
|
57
|
+
t
|
58
|
+
else
|
59
|
+
[]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def _load_tests(array)
|
64
|
+
array ||= []
|
65
|
+
data = []
|
66
|
+
array.each do |test|
|
67
|
+
data << Test.new do |t|
|
68
|
+
t.input = test['input']
|
69
|
+
t.output = test['output']
|
70
|
+
t.ws_security = test['ws-security']
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
data
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TestSuiteResult
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@success = false
|
8
|
+
@broken_tests = []
|
9
|
+
yield self if block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :model, :test_results
|
13
|
+
attr_reader :total_failures, :total_success, :broken_tests
|
14
|
+
|
15
|
+
def calculate_totals
|
16
|
+
@total_failures = @total_success = 0
|
17
|
+
@broken_tests.clear
|
18
|
+
return if @test_results.nil?
|
19
|
+
|
20
|
+
@test_results.each do |res|
|
21
|
+
next if res.status.nil?
|
22
|
+
if res.status.error?
|
23
|
+
@total_failures += 1
|
24
|
+
@broken_tests << res
|
25
|
+
end
|
26
|
+
@total_success += 1 if res.status.success?
|
27
|
+
end
|
28
|
+
|
29
|
+
@success = @total_failures == 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def success?
|
33
|
+
@success
|
34
|
+
end
|
35
|
+
|
36
|
+
def error?
|
37
|
+
!success?
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_tests
|
41
|
+
(@test_results.nil?) ? 0 : @test_results.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_hash
|
45
|
+
{ :model => ((@model) ? @model.to_hash : @model),
|
46
|
+
:test_results => ((@test_results) ? @test_results.map {|t| t.to_hash } : @test_results),
|
47
|
+
:total_failures => @total_failures, :total_success => @total_success,
|
48
|
+
:broken_tests => @broken_tests }
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class TextOperator
|
5
|
+
|
6
|
+
def initialize(opt = {})
|
7
|
+
if block_given?
|
8
|
+
yield self
|
9
|
+
else
|
10
|
+
_load_properties opt
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :contains, :not_contains, :equals, :regex
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
Hash.new({
|
18
|
+
:contains => @contains, :not_contains => @not_contains,
|
19
|
+
:equals => @equals, :regex => @regex
|
20
|
+
})
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def _load_properties(opt)
|
25
|
+
@contains = opt[:contains]
|
26
|
+
@not_contains = opt[:not_contains]
|
27
|
+
@equals = opt[:equals]
|
28
|
+
@regex = opt[:regex]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Theotokos
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class WsConfig
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
yield self if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :env_namespace, :namespaces, :ssl_verify_mode, :ssl_version,
|
11
|
+
:ssl_cert_file, :ssl_cert_key_file, :ssl_ca_cert_file, :ssl_cert_key_password
|
12
|
+
|
13
|
+
def self.ws_attributes
|
14
|
+
%W(env_namespace namespaces ssl_verify_mode ssl_version ssl_cert_file ssl_cert_key_file
|
15
|
+
ssl_ca_cert_file ssl_cert_key_password)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load_ws_config
|
19
|
+
return WsConfig.new unless File.exist? ENV['ws.config.path']
|
20
|
+
|
21
|
+
data = YAML.load_file ENV['ws.config.path']
|
22
|
+
profile = ((ENV['profile'] == 'default' || ENV['profile'].nil?) ? '' : "#{ENV['profile']}.")
|
23
|
+
|
24
|
+
WsConfig.new do |c|
|
25
|
+
c.env_namespace = data['request.env.namespace']
|
26
|
+
|
27
|
+
if data['request.namespaces']
|
28
|
+
namespaces = {}
|
29
|
+
data['request.namespaces'].to_s.split(',').each do |namespace|
|
30
|
+
tokens = namespace.split '='
|
31
|
+
namespaces[tokens[0].strip] = tokens[1].strip
|
32
|
+
end
|
33
|
+
c.namespaces = namespaces
|
34
|
+
end
|
35
|
+
|
36
|
+
c.ssl_verify_mode = data["#{profile}ssl.verify.mode"].to_sym if data["#{profile}ssl.verify.mode"]
|
37
|
+
c.ssl_version = data["#{profile}ssl.version"].to_sym if data["#{profile}ssl.version"]
|
38
|
+
c.ssl_cert_file = data["#{profile}ssl.cert.file"]
|
39
|
+
c.ssl_cert_key_file = data["#{profile}ssl.cert.key.file"]
|
40
|
+
c.ssl_ca_cert_file = data["#{profile}ssl.ca.cert.file"]
|
41
|
+
c.ssl_cert_key_password = data["#{profile}ssl.cert.key.password"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/net/soap_net.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Net
|
2
|
+
|
3
|
+
class SoapNet
|
4
|
+
|
5
|
+
def self.send_request(options)
|
6
|
+
logger = AppLogger.create_logger self
|
7
|
+
client = _savon_client options[:wsdl], options[:ws_config], options[:ws_security]
|
8
|
+
service = options[:service].to_s.gsub(/(.)([A-Z])/,'\1_\2').downcase # snake_case
|
9
|
+
xml = success = nil
|
10
|
+
|
11
|
+
begin
|
12
|
+
logger.debug "Send request to service '#{service}'"
|
13
|
+
response = client.call service.to_sym, :message => options[:params]
|
14
|
+
xml = Nokogiri::XML(response.xml, nil, "UTF-8").to_xml
|
15
|
+
success = true
|
16
|
+
rescue Exception => ex
|
17
|
+
return { :success => false, :xml => Nokogiri::XML(ex.http.body, nil, "UTF-8").to_xml } if ex.instance_of? Savon::SOAPFault
|
18
|
+
|
19
|
+
xml = Nokogiri::XML::Builder.new do |xml|
|
20
|
+
xml.error do
|
21
|
+
xml.message ex.to_s
|
22
|
+
xml.backtrace ex.backtrace.join("\n ")
|
23
|
+
end
|
24
|
+
end.to_xml
|
25
|
+
success = false
|
26
|
+
end
|
27
|
+
|
28
|
+
logger.debug "Success on request? #{success}"
|
29
|
+
{ :success => success, :xml => xml }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self._savon_client(wsdl_url, ws_config, ws_security)
|
33
|
+
logger = AppLogger.create_logger self
|
34
|
+
logger.debug "Prepare web service app client"
|
35
|
+
|
36
|
+
params = {}
|
37
|
+
params[:env_namespace] = ws_config.env_namespace if ws_config.env_namespace
|
38
|
+
params[:namespaces] = ws_config.namespaces if ws_config.namespaces
|
39
|
+
|
40
|
+
params[:ssl_verify_mode] = ws_config.ssl_verify_mode if ws_config.ssl_verify_mode
|
41
|
+
params[:ssl_version] = ws_config.ssl_version if ws_config.ssl_version
|
42
|
+
params[:ssl_cert_file] = ws_config.ssl_cert_file if ws_config.ssl_cert_file
|
43
|
+
params[:ssl_cert_key_file] = ws_config.ssl_cert_key_file if ws_config.ssl_cert_key_file
|
44
|
+
params[:ssl_ca_cert_file] = ws_config.ssl_ca_cert_file if ws_config.ssl_ca_cert_file
|
45
|
+
params[:ssl_cert_key_password] = ws_config.ssl_cert_key_password if ws_config.ssl_cert_key_password
|
46
|
+
|
47
|
+
logger.debug "Client config params for requesting service: #{params}"
|
48
|
+
logger.debug "WS-Security params: #{ws_security}" if (!ws_security.nil? && !ws_security.empty?)
|
49
|
+
|
50
|
+
Savon.client(params) do
|
51
|
+
wsdl wsdl_url
|
52
|
+
wsse_auth ws_security['login'], ws_security['password'], :digest if (!ws_security.nil? && !ws_security.empty?)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Report
|
2
|
+
|
3
|
+
class ChartFactory
|
4
|
+
|
5
|
+
def self.success_failure_chart(opt)
|
6
|
+
total = opt[:total_success].to_i + opt[:total_failures].to_f
|
7
|
+
success = ((opt[:total_success].to_i * 100) / total).to_f.round 2
|
8
|
+
failures = ((opt[:total_failures].to_i * 100) / total).to_f.round 2
|
9
|
+
|
10
|
+
str = "[{ value: #{success}, color: \"#1A0B9C\", highlight: \"#1E0CC0\", label: \"Success (%)\"},"
|
11
|
+
str << "{ value : #{failures}, color : \"#BF1717\", highlight: \"#D71515\", label: \"Failures (%)\"}]"
|
12
|
+
|
13
|
+
ChartFactory._template :id => opt[:id], :data => str, :type => :pie
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.totals_tags_chart(opt)
|
17
|
+
stats = opt[:stats]
|
18
|
+
str = <<-eos
|
19
|
+
{
|
20
|
+
labels: ["#{stats.keys.join('","')}"],
|
21
|
+
datasets: [{
|
22
|
+
fillColor: "rgba(151,187,205,0.5)",
|
23
|
+
strokeColor: "rgba(151,187,205,0.8)",
|
24
|
+
highlightFill: "rgba(151,187,205,0.75)",
|
25
|
+
highlightStroke: "rgba(151,187,205,1)",
|
26
|
+
data: [#{stats.map {|k, v| stats[k][:total] }.join(',')}]
|
27
|
+
}]
|
28
|
+
}
|
29
|
+
eos
|
30
|
+
ChartFactory._template :id => opt[:id], :data => str, :type => :bar
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.stats_tags_chart(opt)
|
34
|
+
stats = opt[:stats]
|
35
|
+
str = <<-eos
|
36
|
+
{
|
37
|
+
labels: ["#{stats.keys.join('","')}"],
|
38
|
+
datasets: [{
|
39
|
+
fillColor: "rgba(220,220,220,0.5)",
|
40
|
+
strokeColor: "rgba(220,220,220,0.8)",
|
41
|
+
highlightFill: "rgba(220,220,220,0.75)",
|
42
|
+
highlightStroke: "rgba(220,220,220,1)",
|
43
|
+
data: [#{stats.keys.map {|k| 100 }.join(',')}]
|
44
|
+
},
|
45
|
+
{
|
46
|
+
fillColor: "rgba(151,187,205,0.5)",
|
47
|
+
strokeColor: "rgba(151,187,205,0.8)",
|
48
|
+
highlightFill: "rgba(151,187,205,0.75)",
|
49
|
+
highlightStroke: "rgba(151,187,205,1)",
|
50
|
+
data: [#{stats.map {|k, v| stats[k][:stat] }.join(',')}]
|
51
|
+
}]
|
52
|
+
}
|
53
|
+
eos
|
54
|
+
ChartFactory._template :id => opt[:id], :data => str, :type => :bar
|
55
|
+
end
|
56
|
+
|
57
|
+
def self._template(opt)
|
58
|
+
<<-eos
|
59
|
+
var data = #{opt[:data]};
|
60
|
+
|
61
|
+
var chart = document.getElementById("#{opt[:id]}").getContext("2d");
|
62
|
+
new Chart(chart).#{opt[:type].to_s.capitalize}(data, {});
|
63
|
+
eos
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Report
|
2
|
+
|
3
|
+
class Console < Reporter
|
4
|
+
|
5
|
+
def print(object)
|
6
|
+
case object.class.name
|
7
|
+
when Theotokos::Model::TestResult.name then _print_test_result object
|
8
|
+
when Theotokos::Model::TestSuiteResult.name then _print_test_suite_result object
|
9
|
+
when Theotokos::Model::TestAppResult.name then _print_test_app_result object
|
10
|
+
else puts "Console printing is not supported for objects of type #{object.class.name}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def _print_test_result(test)
|
16
|
+
@output = ''
|
17
|
+
_append "Test case: ##{test.name}"
|
18
|
+
_append "Test description: #{test.description}"
|
19
|
+
_append "Tags: #{test.tags.join(', ')}" if test.tags
|
20
|
+
_append "Test expectations."
|
21
|
+
|
22
|
+
if test.test_expectation && !test.status.nil?
|
23
|
+
if test.test_expectation['file']
|
24
|
+
file = test.test_expectation['file']
|
25
|
+
_append " => File '#{file}'\n#{File.read(Helper.format_ws_output_path file)}"
|
26
|
+
_append " => Status: #{test.status.test_file_status ? 'Passed' : 'Failed'}\n"
|
27
|
+
end
|
28
|
+
puts
|
29
|
+
if test.test_expectation['text']
|
30
|
+
exp = test.test_expectation['text']
|
31
|
+
_append " => Text\n"
|
32
|
+
|
33
|
+
exp.each do |k, v|
|
34
|
+
_append "#{k}: #{v}"
|
35
|
+
if test.status.test_text_status.nil?
|
36
|
+
_append "Status: Not performed"
|
37
|
+
else
|
38
|
+
status = test.status.test_text_status[k.to_sym]
|
39
|
+
_append "Status: #{status ? 'Passed' : 'Failed'}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
if test.error
|
46
|
+
backtrace = ((test.error[:backtrace].instance_of? Array) ? test.error[:backtrace].join("\n") : test.error[:backtrace])
|
47
|
+
_append "\n - Error message: #{test.error[:message]}"
|
48
|
+
_append "\n - Error detail:\n#{backtrace}"
|
49
|
+
else
|
50
|
+
_append "\n- Found output."
|
51
|
+
_append (test.test_actual) ? File.read(test.test_actual) : ''
|
52
|
+
end
|
53
|
+
|
54
|
+
_append "\n- Test case status: #{((test.status.nil?) ? 'Skipped' : (test.status.success? ? 'Success' : 'Fail'))}"
|
55
|
+
_append "\n------\n\n"
|
56
|
+
|
57
|
+
@output
|
58
|
+
end
|
59
|
+
|
60
|
+
def _print_test_suite_result(suite)
|
61
|
+
@output = ''
|
62
|
+
_append "-" * 100
|
63
|
+
_append "Total test success: #{suite.total_success}"
|
64
|
+
_append "Total test failures: #{suite.total_failures}"
|
65
|
+
|
66
|
+
@output
|
67
|
+
end
|
68
|
+
|
69
|
+
def _print_test_app_result(app)
|
70
|
+
@output = ''
|
71
|
+
_append "*" * 100
|
72
|
+
_append "Total test suites success: #{app.total_success}"
|
73
|
+
_append "Total test suites failures: #{app.total_failures}\n"
|
74
|
+
|
75
|
+
if app.error?
|
76
|
+
_append "*" * 100
|
77
|
+
_append "- Broken tests"
|
78
|
+
app.broken_suites.each do |suite|
|
79
|
+
_append "Test suite: #{suite.model.source}\nTest cases: ##{suite.broken_tests.map {|t| t.name }.join(', #')}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@output
|
84
|
+
end
|
85
|
+
|
86
|
+
def _append(text)
|
87
|
+
@output << "\n" unless @output.empty?
|
88
|
+
@output << text
|
89
|
+
puts text unless ENV['ENVIRONMENT'] == 'test'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|