onlyoffice_testrail_wrapper 0.1.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/lib/onlyoffice_testrail_wrapper.rb +10 -0
- data/lib/onlyoffice_testrail_wrapper/helpers/hash_helper.rb +21 -0
- data/lib/onlyoffice_testrail_wrapper/helpers/rspec_helper.rb +24 -0
- data/lib/onlyoffice_testrail_wrapper/helpers/ruby_helper.rb +10 -0
- data/lib/onlyoffice_testrail_wrapper/helpers/string_helper.rb +12 -0
- data/lib/onlyoffice_testrail_wrapper/helpers/system_helper.rb +17 -0
- data/lib/onlyoffice_testrail_wrapper/mock/rspec_example_mock.rb +40 -0
- data/lib/onlyoffice_testrail_wrapper/name.rb +9 -0
- data/lib/onlyoffice_testrail_wrapper/rspec_extension.rb +14 -0
- data/lib/onlyoffice_testrail_wrapper/testrail.rb +187 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_case.rb +67 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_helper.rb +173 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_helper/testrail_helper_rspec_metadata.rb +55 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_helper/testrail_status_helper.rb +18 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_milestone.rb +23 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_plan.rb +92 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_plan_entry.rb +16 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_project.rb +227 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_project/testrail_project_plan_helper.rb +65 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_result.rb +47 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_run.rb +147 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_section.rb +109 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_suite.rb +113 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_test.rb +40 -0
- data/lib/onlyoffice_testrail_wrapper/testrail_tools/testrail_tools.rb +119 -0
- data/lib/onlyoffice_testrail_wrapper/version.rb +7 -0
- metadata +237 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c7cdb9209303106828ac8d2628bdfbd6243b0b66cbf9e57f8d1c3d506a29d0af
|
4
|
+
data.tar.gz: 54ad089da3f905190dc4b33784fbfc665faa725d865f0b28d77f034e4766b08e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 86813255438a058617f52e431bd1465fe1a2aba8397dc62cd41efc51fc270c22c271a3c0e6a8c59645540896b8842eab77ce53a3614048f7d7f4da9016615ce1
|
7
|
+
data.tar.gz: e198cc8aa5f2b5c537ee36ff4e30c03ebb262a0485f7852d12f4ef333ce3f751e9046df74a1a842221f9e5b17358afc55ef2ea73f92d64099dbdf368e8655072
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'onlyoffice_logger_helper'
|
4
|
+
require_relative 'onlyoffice_testrail_wrapper/rspec_extension'
|
5
|
+
require_relative 'onlyoffice_testrail_wrapper/testrail_helper'
|
6
|
+
require_relative 'onlyoffice_testrail_wrapper/mock/rspec_example_mock'
|
7
|
+
require_relative 'onlyoffice_testrail_wrapper/helpers/hash_helper'
|
8
|
+
require_relative 'onlyoffice_testrail_wrapper/helpers/rspec_helper'
|
9
|
+
require_relative 'onlyoffice_testrail_wrapper/helpers/string_helper'
|
10
|
+
require_relative 'onlyoffice_testrail_wrapper/testrail_tools/testrail_tools'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeTestrailWrapper
|
4
|
+
class HashHelper
|
5
|
+
class << self
|
6
|
+
def get_hash_from_array_with_two_parameters(array, key_parameter, value_parameter)
|
7
|
+
raise 'First argument must be Array!' unless array.is_a?(Array)
|
8
|
+
|
9
|
+
result_hash = {}
|
10
|
+
array.reverse_each { |element| result_hash[element[key_parameter]] = element[value_parameter] }
|
11
|
+
result_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_to_class_variable(hash, class_name)
|
15
|
+
object = class_name.new
|
16
|
+
hash.each { |key, value| object.instance_variable_set("@#{key}", value) }
|
17
|
+
object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeTestrailWrapper
|
4
|
+
# Methods to some rspec methods
|
5
|
+
module RspecHelper
|
6
|
+
# This method is based on
|
7
|
+
# https://github.com/rspec/rspec-core/blob/v3.3.0/lib/rspec/core/formatters/exception_presenter.rb#L130
|
8
|
+
# It extracted exact line of code from failed exception
|
9
|
+
# @param [RSpec::Core::Example] example
|
10
|
+
# @return [String] line value
|
11
|
+
def self.find_failed_line(example)
|
12
|
+
example_path = example.metadata[:absolute_file_path].downcase
|
13
|
+
dirty_line = example.exception.backtrace.find do |line|
|
14
|
+
next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
|
15
|
+
|
16
|
+
File.expand_path(line_path).casecmp(example_path).zero?
|
17
|
+
end
|
18
|
+
line_number = dirty_line[/:\d*:/].delete(':').to_i
|
19
|
+
OnlyofficeFileHelper::FileHelper.read_array_from_file(example.metadata[:absolute_file_path])[line_number - 1]
|
20
|
+
rescue StandardError => e
|
21
|
+
"Cannot find failed line because of exception: #{e}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeTestrailWrapper
|
4
|
+
class StringHelper
|
5
|
+
class << self
|
6
|
+
def warnstrip!(string)
|
7
|
+
warn "Beginning or end of string has spaces! In: #{string}" unless string == string.strip
|
8
|
+
string.strip
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
module OnlyofficeTestrailWrapper
|
6
|
+
# Stuff for working with OS
|
7
|
+
class SystemHelper
|
8
|
+
class << self
|
9
|
+
# @return [String] name of current host
|
10
|
+
def hostname
|
11
|
+
name = Socket.gethostname
|
12
|
+
OnlyofficeLoggerHelper.log("hostname is: #{name}")
|
13
|
+
name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeTestrailWrapper
|
4
|
+
# Mock Rspec example exception
|
5
|
+
class RspecExceptionMock
|
6
|
+
attr_accessor :backtrace
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@backtrace = %w[TestBackTraceLine1 TestBackTraceLine2]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class for mocking rspec result metadata
|
14
|
+
class RspecExceptionResultMock
|
15
|
+
attr_accessor :started_at
|
16
|
+
end
|
17
|
+
|
18
|
+
# Mock Rspec example
|
19
|
+
class RspecExampleMock
|
20
|
+
# @return [Object] object exception
|
21
|
+
attr_accessor :exception
|
22
|
+
# @return [Object] backtrace object
|
23
|
+
attr_accessor :backtrace
|
24
|
+
# @return [Hash] metadata
|
25
|
+
attr_accessor :metadata
|
26
|
+
# @return [True, False] is test pending
|
27
|
+
attr_accessor :pending
|
28
|
+
# @return [String] description of spec
|
29
|
+
attr_accessor :description
|
30
|
+
|
31
|
+
def initialize(description: 'MockDescription',
|
32
|
+
exception: RspecExceptionMock.new)
|
33
|
+
@exception = exception
|
34
|
+
@metadata = { execution_result: RspecExceptionResultMock.new }
|
35
|
+
@pending = false
|
36
|
+
@description = description
|
37
|
+
@section = ''
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @author Roman.Zagudaev
|
4
|
+
# lib for working with http queries
|
5
|
+
|
6
|
+
require 'net/http'
|
7
|
+
require 'json'
|
8
|
+
require 'yaml'
|
9
|
+
require_relative 'testrail_project'
|
10
|
+
|
11
|
+
module OnlyofficeTestrailWrapper
|
12
|
+
# Main class for working with testrail
|
13
|
+
# dvd_copy = Project.init_project_by_name('AVS Disc Creator')
|
14
|
+
# compete_test_suit= dvd_copy.init_suite_by_name('Complete Test Suite')
|
15
|
+
# test_run_from_api = compete_test_suit.start_test_run('TestRunName', "Simple description")
|
16
|
+
# incompleted_test = test_run_from_api.get_incomplete_tests()
|
17
|
+
# while(incomplete_test.length > 0)
|
18
|
+
# current_test = incomplete_test.sample
|
19
|
+
# p current_test.title
|
20
|
+
# current_test.add_result(Testrail2::TEST_RESULT_OK, 'description','version')
|
21
|
+
# incomplete_test = test_run_from_api.get_incomplete_tests()
|
22
|
+
# end1
|
23
|
+
class Testrail2
|
24
|
+
# @return [String] address of testrail
|
25
|
+
@testrail_url = nil
|
26
|
+
# @return [String] login for admin user
|
27
|
+
@admin_user = nil
|
28
|
+
# @return [String] password for admin user
|
29
|
+
@admin_pass = nil
|
30
|
+
|
31
|
+
# @return [Hash] project information
|
32
|
+
attr_accessor :projects_names
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@projects_names = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
attr_accessor :testrail_url
|
40
|
+
# Attribute to write admin_user
|
41
|
+
attr_writer :admin_user
|
42
|
+
# Attribute to write admin_pass
|
43
|
+
attr_writer :admin_pass
|
44
|
+
|
45
|
+
# @return [String] default config location
|
46
|
+
CONFIG_LOCATION = "#{Dir.home}/.gem-onlyoffice_testrail_wrapper/config.yml"
|
47
|
+
|
48
|
+
def read_keys
|
49
|
+
@testrail_url = ENV['TESTRAIL_URL']
|
50
|
+
@admin_user = ENV['TESTRAIL_USER']
|
51
|
+
@admin_pass = ENV['TESTRAIL_PASSWORD']
|
52
|
+
return unless @admin_user.nil? && @admin_pass.nil?
|
53
|
+
|
54
|
+
begin
|
55
|
+
yaml = YAML.load_file(CONFIG_LOCATION)
|
56
|
+
@testrail_url = yaml['url']
|
57
|
+
@admin_user = yaml['user']
|
58
|
+
@admin_pass = yaml['password']
|
59
|
+
rescue Errno::ENOENT
|
60
|
+
raise Errno::ENOENT, "No user of passwords found in #{CONFIG_LOCATION}. Please create correct config"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def admin_user
|
65
|
+
read_keys
|
66
|
+
@admin_user
|
67
|
+
end
|
68
|
+
|
69
|
+
def admin_pass
|
70
|
+
read_keys
|
71
|
+
@admin_pass
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_testrail_address
|
75
|
+
read_keys unless testrail_url
|
76
|
+
testrail_url
|
77
|
+
end
|
78
|
+
|
79
|
+
# Perform http get on address
|
80
|
+
# @param [String] request_url to perform http get
|
81
|
+
# @return [Hash] Json with result data in hash form
|
82
|
+
def http_get(request_url)
|
83
|
+
uri = URI get_testrail_address + request_url
|
84
|
+
request = Net::HTTP::Get.new uri.request_uri
|
85
|
+
response = send_request(uri, request)
|
86
|
+
JSON.parse response.body
|
87
|
+
end
|
88
|
+
|
89
|
+
# Perform http post on address
|
90
|
+
# @param [String] request_url to perform http get
|
91
|
+
# @param [Hash] data_hash headers to add to post query
|
92
|
+
# @return [Hash] Json with result data in hash form
|
93
|
+
def http_post(request_url, data_hash)
|
94
|
+
uri = URI get_testrail_address + request_url
|
95
|
+
request = Net::HTTP::Post.new uri.request_uri
|
96
|
+
request.body = data_hash.to_json
|
97
|
+
response = send_request(uri, request)
|
98
|
+
return if response.body == ''
|
99
|
+
|
100
|
+
JSON.parse response.body
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# region PROJECT
|
105
|
+
|
106
|
+
def project(name_or_id)
|
107
|
+
case name_or_id.class.to_s
|
108
|
+
when 'Fixnum'
|
109
|
+
get_project_by_id name_or_id
|
110
|
+
when 'String'
|
111
|
+
init_project_by_name name_or_id
|
112
|
+
else
|
113
|
+
raise 'Wrong argument. Must be name [String] or id [Integer]'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Get all projects on testrail
|
118
|
+
# @return [Array, ProjectTestrail] array of projects
|
119
|
+
def get_projects
|
120
|
+
projects = Testrail2.http_get 'index.php?/api/v2/get_projects'
|
121
|
+
@projects_names = HashHelper.get_hash_from_array_with_two_parameters(projects, 'name', 'id') if @projects_names.empty?
|
122
|
+
projects
|
123
|
+
end
|
124
|
+
|
125
|
+
def create_new_project(name, announcement = '', show_announcement = true)
|
126
|
+
new_project = HashHelper.parse_to_class_variable(Testrail2.http_post('index.php?/api/v2/add_project', name: StringHelper.warnstrip!(name.to_s), announcement: announcement,
|
127
|
+
show_announcement: show_announcement), TestrailProject)
|
128
|
+
OnlyofficeLoggerHelper.log "Created new project: #{new_project.name}"
|
129
|
+
new_project.instance_variable_set('@testrail', self)
|
130
|
+
@projects_names[new_project.name] = new_project.id
|
131
|
+
new_project
|
132
|
+
end
|
133
|
+
|
134
|
+
# Initialize project by it's name
|
135
|
+
# @param [String] name name of project
|
136
|
+
# @return [TestrailProject] project with this name
|
137
|
+
def init_project_by_name(name)
|
138
|
+
found_project = get_project_by_name name
|
139
|
+
found_project.nil? ? create_new_project(name) : found_project
|
140
|
+
end
|
141
|
+
|
142
|
+
# Get all projects on testrail
|
143
|
+
# @return [Array, ProjectTestrail] array of projects
|
144
|
+
def get_project_by_id(id)
|
145
|
+
project = HashHelper.parse_to_class_variable(Testrail2.http_get("index.php?/api/v2/get_project/#{id}"), TestrailProject)
|
146
|
+
OnlyofficeLoggerHelper.log("Initialized project: #{project.name}")
|
147
|
+
project.instance_variable_set('@testrail', self)
|
148
|
+
project
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_project_by_name(name)
|
152
|
+
get_projects if @projects_names.empty?
|
153
|
+
@projects_names[StringHelper.warnstrip!(name.to_s)].nil? ? nil : get_project_by_id(@projects_names[StringHelper.warnstrip!(name.to_s)])
|
154
|
+
end
|
155
|
+
|
156
|
+
# Check if Testrail connection is available
|
157
|
+
# @return [True, False] result of test connection
|
158
|
+
def available?
|
159
|
+
get_projects
|
160
|
+
true
|
161
|
+
rescue StandardError
|
162
|
+
false
|
163
|
+
end
|
164
|
+
|
165
|
+
# endregion
|
166
|
+
|
167
|
+
def self.send_request(uri, request)
|
168
|
+
request.basic_auth admin_user, admin_pass
|
169
|
+
request.delete 'content-type'
|
170
|
+
request.add_field 'content-type', 'application/json'
|
171
|
+
is_ssl = (uri.scheme == 'https')
|
172
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: is_ssl) do |http|
|
173
|
+
attempts = 0
|
174
|
+
begin
|
175
|
+
response = http.request(request)
|
176
|
+
rescue Timeout::Error
|
177
|
+
attempts += 1
|
178
|
+
retry if attempts < 3
|
179
|
+
raise 'Timeout error after 3 attempts'
|
180
|
+
rescue StandardError => e
|
181
|
+
raise e
|
182
|
+
end
|
183
|
+
return response
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeTestrailWrapper
|
4
|
+
# @author Roman.Zagudaev
|
5
|
+
# Class for description of test case
|
6
|
+
class TestrailCase
|
7
|
+
# @return [Integer] Id of test case
|
8
|
+
attr_accessor :id
|
9
|
+
# @return [String] title of test case
|
10
|
+
attr_accessor :title
|
11
|
+
# @return [Integer] type id of test case
|
12
|
+
attr_accessor :type_id
|
13
|
+
# @return [Integer] priority id of test case
|
14
|
+
attr_accessor :priority_id
|
15
|
+
# @return [String] Steps of test case
|
16
|
+
attr_accessor :custom_steps
|
17
|
+
# @return [String] Estimated test time
|
18
|
+
attr_accessor :estimate
|
19
|
+
|
20
|
+
# Default constructor
|
21
|
+
# @param [String] title name of test case, default = nil
|
22
|
+
# @param [Integer] type_id type id of test case, default = 3
|
23
|
+
# @param [Integer] priority_id priority id of test case, default = 4
|
24
|
+
# @param [String] custom_steps Steps of test case
|
25
|
+
# @param [Integer] id Id of test case
|
26
|
+
# @return [TestCaseTestrail] new test case
|
27
|
+
def initialize(title = nil, type_id = 3, priority_id = 4, custom_steps = nil, id = nil)
|
28
|
+
@id = id
|
29
|
+
@title = title
|
30
|
+
@type_id = type_id
|
31
|
+
@priority_id = priority_id
|
32
|
+
@custom_steps = custom_steps
|
33
|
+
end
|
34
|
+
|
35
|
+
def update(title = @title, type_id = @type_id, priority_id = @priority_id, custom_steps = @custom_steps)
|
36
|
+
@section.cases_names.delete @title
|
37
|
+
@section.cases_names[StringHelper.warnstrip!(title.to_s)] = @id
|
38
|
+
HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/update_case/#{@id}", title: title, type_id: type_id,
|
39
|
+
priority_id: priority_id, custom_steps: custom_steps), TestrailCase)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete
|
43
|
+
@section.cases_names.delete @title
|
44
|
+
OnlyofficeLoggerHelper.log "Deleted test case: #{@title}"
|
45
|
+
Testrail2.http_post "index.php?/api/v2/delete_case/#{@id}", {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_results(run_id)
|
49
|
+
case_results = Testrail2.http_get "index.php?/api/v2/get_results_for_case/#{run_id}/#{@id}"
|
50
|
+
case_results.each_with_index { |test_case, index| case_results[index] = HashHelper.parse_to_class_variable(test_case, TestrailResult) }
|
51
|
+
case_results
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_result(run_id, result, comment = '', custom_fields = {}, version = '')
|
55
|
+
response = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_result_for_case/#{run_id}/#{@id}", { status_id: TestrailResult::RESULT_STATUSES[result],
|
56
|
+
comment: comment, version: version }.merge(custom_fields)), TestrailResult)
|
57
|
+
OnlyofficeLoggerHelper.log "Set test case result: #{result}. URL: #{Testrail2.get_testrail_address}index.php?/tests/view/#{response.test_id}", output_colors[result]
|
58
|
+
response
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def output_colors
|
64
|
+
{ failed: 45, pending: 43, passed: 42, passed_2: 46, aborted: 41, blocked: 44 }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'onlyoffice_bugzilla_helper'
|
4
|
+
require_relative 'testrail_helper/testrail_helper_rspec_metadata'
|
5
|
+
require_relative 'testrail_helper/testrail_status_helper'
|
6
|
+
require_relative 'testrail'
|
7
|
+
require_relative 'helpers/ruby_helper'
|
8
|
+
require_relative 'helpers/system_helper'
|
9
|
+
|
10
|
+
module OnlyofficeTestrailWrapper
|
11
|
+
# Class with help methods with testrail
|
12
|
+
class TestrailHelper
|
13
|
+
include RubyHelper
|
14
|
+
include TestrailHelperRspecMetadata
|
15
|
+
include TestrailStatusHelper
|
16
|
+
attr_reader :project, :plan, :suite, :run
|
17
|
+
attr_accessor :add_all_suites, :ignore_parameters, :suites_to_add, :search_plan_by_substring, :in_debug, :version
|
18
|
+
|
19
|
+
def initialize(project_name, suite_name = nil, plan_name = nil, run_name = nil)
|
20
|
+
@in_debug = debug?
|
21
|
+
begin
|
22
|
+
@bugzilla_helper = OnlyofficeBugzillaHelper::BugzillaHelper.new
|
23
|
+
rescue Errno::ENOENT
|
24
|
+
@bugzilla_helper = nil
|
25
|
+
end
|
26
|
+
if @in_debug
|
27
|
+
OnlyofficeLoggerHelper.log 'Do not initialize Testrail, because spec run in debug'
|
28
|
+
@run = TestrailRun.new
|
29
|
+
return
|
30
|
+
end
|
31
|
+
OnlyofficeLoggerHelper.log 'Begin initializing Testrail...'
|
32
|
+
@suites_to_add = []
|
33
|
+
@add_all_suites = true
|
34
|
+
@search_plan_by_substring = false
|
35
|
+
yield(self) if block_given?
|
36
|
+
@project = Testrail2.new.project project_name.to_s.dup
|
37
|
+
if plan_name
|
38
|
+
@plan = @project.get_plan_by_name(search_plan_by_substring ? get_plan_name_by_substring(plan_name.to_s) : plan_name.to_s)
|
39
|
+
@plan ||= @project.create_new_plan(plan_name, suites_to_add_hash(@add_all_suites ? all_suites_names : @suites_to_add))
|
40
|
+
end
|
41
|
+
return if suite_name.nil?
|
42
|
+
|
43
|
+
@suite = @project.suite suite_name.to_s
|
44
|
+
if @plan
|
45
|
+
init_run_in_plan(suite_name.to_s)
|
46
|
+
else
|
47
|
+
@run = @project.init_run_by_name(run_name ? run_name.to_s : suite_name.to_s, @suite.id)
|
48
|
+
end
|
49
|
+
raise "Plan '#{@plan.name}' is completed! Cannot add results. See #{@plan.url}" if !@plan.nil? && @plan.is_completed
|
50
|
+
|
51
|
+
OnlyofficeLoggerHelper.log 'Initializing complete!'
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_cases_to_suite(cases, section_name = 'All Test Cases')
|
55
|
+
if @in_debug
|
56
|
+
OnlyofficeLoggerHelper.log 'Do not add test result, because spec run in debug '
|
57
|
+
return
|
58
|
+
end
|
59
|
+
OnlyofficeLoggerHelper.log "Begin scanning #{@suite.name} suite for new cases" unless cases.is_a?(Array)
|
60
|
+
section = @suite.section section_name.to_s
|
61
|
+
existing_cases = section.get_cases.map { |test_case| test_case['title'] }
|
62
|
+
cases.each { |case_name| section.create_new_case case_name.to_s unless existing_cases.include?(case_name) }
|
63
|
+
OnlyofficeLoggerHelper.log 'Suite scanning complete!'
|
64
|
+
@suite = @project.get_suite_by_id @suite.id
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_result_to_test_case(example, comment = '', section_name = 'All Test Cases')
|
68
|
+
if @in_debug
|
69
|
+
OnlyofficeLoggerHelper.log 'Do not add test result, because spec run in debug '
|
70
|
+
return
|
71
|
+
end
|
72
|
+
exception = example.exception
|
73
|
+
custom_fields = init_custom_fields(example)
|
74
|
+
if @ignore_parameters && (ignored_hash = ignore_case?(example.metadata))
|
75
|
+
comment += "\nTest ignored by #{ignored_hash}"
|
76
|
+
result = :blocked
|
77
|
+
elsif example.pending
|
78
|
+
result, comment, bug_id = parse_pending_comment(example.execution_result.pending_message)
|
79
|
+
if example.exception.to_s == 'Expected example to fail since it is pending, but it passed.'
|
80
|
+
result = :failed
|
81
|
+
comment = "Test passed! #{comment}"
|
82
|
+
end
|
83
|
+
custom_fields[:defects] = bug_id.to_s
|
84
|
+
example.add_custom_exception(comment) if result == :failed
|
85
|
+
result = :lpv if comment.downcase.include?('limited program version')
|
86
|
+
elsif exception.to_s.include?('got:') || exception.to_s.include?('expected:')
|
87
|
+
result = :failed
|
88
|
+
failed_line = RspecHelper.find_failed_line(example)
|
89
|
+
comment += "\n#{exception.to_s.gsub('got:', "got:\n").gsub('expected:', "expected:\n")}\nIn line:\n#{failed_line}"
|
90
|
+
elsif exception.to_s.include?('to return') || exception.to_s.include?('expected')
|
91
|
+
result = :failed
|
92
|
+
comment += "\n#{exception.to_s.gsub('to return ', "to return:\n").gsub(', got ', "\ngot:\n")}"
|
93
|
+
elsif exception.to_s.include?('Service Unavailable')
|
94
|
+
result = :service_unavailable
|
95
|
+
comment += "\n#{exception}"
|
96
|
+
elsif exception.to_s.include?('Limited program version')
|
97
|
+
result = :lpv
|
98
|
+
comment += "\n#{exception}"
|
99
|
+
elsif exception.nil?
|
100
|
+
result = if @last_case == example.description
|
101
|
+
:passed_2
|
102
|
+
elsif custom_fields.key?(:custom_js_error)
|
103
|
+
:js_error
|
104
|
+
else
|
105
|
+
:passed
|
106
|
+
end
|
107
|
+
comment += "\nOk"
|
108
|
+
else
|
109
|
+
result = :aborted
|
110
|
+
comment += "\n#{exception}"
|
111
|
+
custom_fields[:custom_autotest_error_line] = exception.backtrace.join("\n") unless exception.backtrace.nil?
|
112
|
+
end
|
113
|
+
@last_case = example.description
|
114
|
+
@suite.section(section_name).case(example.description).add_result @run.id, result, comment, custom_fields
|
115
|
+
end
|
116
|
+
|
117
|
+
def add_result_by_case_name(name, result, comment = 'ok', section_name = 'All Test Cases')
|
118
|
+
@suite.section(section_name).case(name.to_s).add_result(@run.id, result, comment)
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_incomplete_tests
|
122
|
+
@run.get_tests.map { |test| test['title'] if test['status_id'] == 3 || test['status_id'] == 4 }.compact
|
123
|
+
end
|
124
|
+
|
125
|
+
# @param [Array] result. Example: [:retest, :passed]
|
126
|
+
def get_tests_by_result(result)
|
127
|
+
check_status_exist(result)
|
128
|
+
result = [result] unless result.is_a?(Array)
|
129
|
+
@run.get_tests.map { |test| test['title'] if result.include?(TestrailResult::RESULT_STATUSES.key(test['status_id'])) }.compact
|
130
|
+
end
|
131
|
+
|
132
|
+
def delete_plan(plan_name)
|
133
|
+
@project.plan(get_plan_name_by_substring(plan_name.to_s)).delete
|
134
|
+
end
|
135
|
+
|
136
|
+
def mark_rest_environment_dependencies(supported_test_list, status_to_mark = :lpv)
|
137
|
+
get_incomplete_tests.each do |current_test|
|
138
|
+
add_result_by_case_name(current_test, status_to_mark, 'Not supported on this test environment') unless supported_test_list.include?(current_test)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def init_run_in_plan(run_name)
|
145
|
+
@plan.entries.each { |entry| @run = entry.runs.first if entry.name == run_name }
|
146
|
+
@run = @plan.add_entry(run_name, @suite.id).runs.first if @run.nil?
|
147
|
+
OnlyofficeLoggerHelper.log("Initialized run: #{@run.name}")
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_plan_name_by_substring(string)
|
151
|
+
@project.get_plans.each { |plan| return plan['name'] if plan['name'].include?(string) }
|
152
|
+
string
|
153
|
+
end
|
154
|
+
|
155
|
+
def all_suites_names
|
156
|
+
@suites ? (return @suites) : @suites = []
|
157
|
+
@project.get_suites
|
158
|
+
@project.suites_names.each_key { |key| @suites << key }
|
159
|
+
@suites.sort!
|
160
|
+
end
|
161
|
+
|
162
|
+
def ignore_case?(example_metadata)
|
163
|
+
raise 'Ignore parameters must be Hash!!' unless @ignore_parameters.instance_of?(Hash)
|
164
|
+
|
165
|
+
@ignore_parameters.each { |key, value| return { key => value } if example_metadata[key] == value }
|
166
|
+
false
|
167
|
+
end
|
168
|
+
|
169
|
+
def suites_to_add_hash(suites_names)
|
170
|
+
suites_names.map { |suite| all_suites_names.include?(suite) ? { 'suite_id' => @project.suites_names[suite] } : { 'suite_id' => @project.create_new_suite(suite).id } }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|