tms-cli 0.0.pre.beta
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/bin/tms +5 -0
- data/lib/.env +11 -0
- data/lib/cucumber.rb +369 -0
- data/lib/db/mysql.rb +107 -0
- data/lib/import/importcucumber.rb +123 -0
- data/lib/import/importfeature.rb +34 -0
- data/lib/import/importflutter.rb +40 -0
- data/lib/import/importgolang.rb +47 -0
- data/lib/import/importjest.rb +81 -0
- data/lib/import/importjunit.rb +76 -0
- data/lib/import/importrspec.rb +36 -0
- data/lib/jira/jira_api.rb +37 -0
- data/lib/jira/jira_issues.rb +48 -0
- data/lib/preprocessing.rb +334 -0
- data/lib/regression.rb +232 -0
- data/lib/testrail/attachment.rb +17 -0
- data/lib/testrail/cleanup.rb +64 -0
- data/lib/testrail/dataprep.rb +169 -0
- data/lib/testrail/log.rb +15 -0
- data/lib/testrail/milestone.rb +136 -0
- data/lib/testrail/projects.rb +39 -0
- data/lib/testrail/report.rb +61 -0
- data/lib/testrail/results.rb +20 -0
- data/lib/testrail/sections.rb +32 -0
- data/lib/testrail/testbdd.rb +72 -0
- data/lib/testrail/testcase.rb +196 -0
- data/lib/testrail/testplan.rb +93 -0
- data/lib/testrail/testrail.rb +136 -0
- data/lib/testrail/testrun.rb +184 -0
- data/lib/testrail/testsuite.rb +49 -0
- data/lib/tms.rb +337 -0
- data/util/script/generate-password.rb +47 -0
- data/util/script/generatereport.rb +90 -0
- data/util/script/mergerequest.rb +38 -0
- metadata +300 -0
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Tms
|
8
|
+
module Testcase
|
9
|
+
module_function
|
10
|
+
|
11
|
+
@@cases = {}
|
12
|
+
@@tc_ids = {}
|
13
|
+
@@test_results = []
|
14
|
+
|
15
|
+
def validate_testcase(client, section_id, test_title, test_status, refs_from_report, tr_version, error_comment)
|
16
|
+
# find case with the same title
|
17
|
+
# update existing case if found the same title
|
18
|
+
# and create new case if no case have the same title
|
19
|
+
tc = @@cases.find { |case_object| case_object['title'] == test_title }
|
20
|
+
if !tc.nil?
|
21
|
+
tc_refs = tc['refs'].nil? ? '' : tc['refs'].to_s
|
22
|
+
put_existing_tc_id(tc, test_status, section_id, error_comment)
|
23
|
+
|
24
|
+
# update tc refs if previous refs is different or empty
|
25
|
+
if validate_update_reference(refs_from_report, tc_refs) || tc_refs.eql?('')
|
26
|
+
update_test_refs(client, tc['id'], refs_from_report)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
put_new_tc_id(client, section_id, test_title, test_status, error_comment, refs_from_report)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# this method will directly update test case when ref available in report file
|
34
|
+
def validate_testcase_bdd(client, section_id, test_id, refs_from_report, tr_version)
|
35
|
+
tc = get_tc_by_test_id(client, test_id)
|
36
|
+
tc_refs = tc['refs'].nil? ? '' : tc['refs'].to_s
|
37
|
+
if validate_update_reference(refs_from_report, tc_refs) || tc_refs.empty?
|
38
|
+
update_test_refs(client, tc['case_id'], refs_from_report)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def put_existing_tc_id(tc, test_status, section_id, error_comment)
|
43
|
+
tc_arr = []
|
44
|
+
tmp_hash = {}
|
45
|
+
|
46
|
+
tc_arr = @@tc_ids[section_id] unless @@tc_ids[section_id].nil?
|
47
|
+
tc_arr.push(tc['id'])
|
48
|
+
@@tc_ids[section_id] = tc_arr
|
49
|
+
tmp_hash['case_id'] = tc['id']
|
50
|
+
tmp_hash['status_id'] = test_status
|
51
|
+
tmp_hash['comment'] = error_comment
|
52
|
+
|
53
|
+
@@test_results.push(tmp_hash) unless @@test_results.include? tmp_hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_test_refs(client, tc_id, refs)
|
57
|
+
payload = { refs: refs.to_s }
|
58
|
+
client.send_post("update_case/#{tc_id}", payload)
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_testcase(client, section_id, test_title, refs)
|
62
|
+
begin
|
63
|
+
payload = { title: test_title.to_s, refs: refs.to_s, template_id: 1 }
|
64
|
+
client.send_post("add_case/#{section_id}", payload)
|
65
|
+
rescue TestRail::APIError => e
|
66
|
+
puts "Error occurred while creating test case with title: '#{test_title}'"
|
67
|
+
puts "Error message: #{e.message}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def put_new_tc_id(client, section_id, test_title, test_status, error_comment, refs)
|
72
|
+
tc_arr = []
|
73
|
+
response = create_testcase(client, section_id, test_title, refs)
|
74
|
+
@@cases.push(response)
|
75
|
+
tc_id = response['id']
|
76
|
+
tc_arr = @@tc_ids[section_id] unless @@test_results.empty?
|
77
|
+
|
78
|
+
tc_arr.push(tc_id)
|
79
|
+
@@tc_ids[section_id] = tc_arr
|
80
|
+
|
81
|
+
tmp_hash = {}
|
82
|
+
|
83
|
+
tmp_hash['case_id'] = tc_id
|
84
|
+
tmp_hash['status_id'] = test_status
|
85
|
+
tmp_hash['comment'] = error_comment
|
86
|
+
@@test_results.push(tmp_hash) unless @@test_results.include? tmp_hash
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_cases(client, project_id, suite_id, section_id, offset = 0)
|
90
|
+
# handle cases more than 250 entries
|
91
|
+
offset = 0
|
92
|
+
cases = []
|
93
|
+
|
94
|
+
loop do
|
95
|
+
get_cases = client.send_get("get_cases/#{project_id}&suite_id=#{suite_id}§ion_id=#{section_id}&offset=#{offset}")
|
96
|
+
cases.push get_cases['cases']
|
97
|
+
offset += 250
|
98
|
+
break if get_cases['_links']['next'].nil?
|
99
|
+
end
|
100
|
+
cases = cases.flatten
|
101
|
+
|
102
|
+
return cases
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_status_id(status)
|
106
|
+
case status
|
107
|
+
when 'passed' then 1
|
108
|
+
when 'todo' then 2
|
109
|
+
when 'skipped' then 4
|
110
|
+
when 'failed' then 5
|
111
|
+
when 'pending' then 6
|
112
|
+
else abort('Invalid status on report json')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def validate_update_reference(refs_from_report, tc_refs)
|
117
|
+
refs_eql = false
|
118
|
+
unless tc_refs.nil? || refs_from_report.nil?
|
119
|
+
tc_refs.split(',').each do |tc_ref|
|
120
|
+
refs_from_report.split(',').each do |ref|
|
121
|
+
if tc_ref.eql?(ref)
|
122
|
+
refs_eql = true
|
123
|
+
break
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
refs_eql
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_ids
|
132
|
+
@@tc_ids
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_results
|
136
|
+
@@test_results
|
137
|
+
end
|
138
|
+
|
139
|
+
def validate_refs(refs)
|
140
|
+
refs.include?('-') &&
|
141
|
+
refs.split('-').size.eql?(2) &&
|
142
|
+
(refs.split('-')[1] =~ /[^0-9]/).nil?
|
143
|
+
end
|
144
|
+
|
145
|
+
# This method will get case id by test id
|
146
|
+
# @param client testrail
|
147
|
+
# @param test_id is existing test run
|
148
|
+
def get_tc_by_test_id(client, test_id)
|
149
|
+
client.send_get("get_test/#{test_id}")
|
150
|
+
end
|
151
|
+
|
152
|
+
# This method will get case id by test id
|
153
|
+
# @param client testrail
|
154
|
+
# @param suite_id is the id of the suite
|
155
|
+
def delete_cases_from_suite(client, suite_id, case_ids)
|
156
|
+
payload = { case_ids: case_ids }
|
157
|
+
client.send_post("delete_cases/#{suite_id}&soft=1", payload)
|
158
|
+
end
|
159
|
+
|
160
|
+
def add_case(client, section_id, refs, title, label, bdd)
|
161
|
+
puts "Create test case: #{title}"
|
162
|
+
begin
|
163
|
+
payload = {
|
164
|
+
title: title,
|
165
|
+
refs: refs,
|
166
|
+
custom_label_id: label,
|
167
|
+
template_id: 4,
|
168
|
+
custom_testrail_bdd_scenario:[{content: bdd}]
|
169
|
+
}
|
170
|
+
client.send_post("add_case/#{section_id}", payload)
|
171
|
+
rescue TestRail::APIError => e
|
172
|
+
puts "Error occurred while creating test case with title: '#{test_title}'"
|
173
|
+
puts "Error message: #{e.message}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# This method will set reference into '' on test case
|
178
|
+
# @param client testrail
|
179
|
+
# @param test case id
|
180
|
+
def update_case(client, tc_id, refs, title, label, bdd)
|
181
|
+
puts "Update test case: #{title}"
|
182
|
+
begin
|
183
|
+
payload = {
|
184
|
+
title: title,
|
185
|
+
refs: refs,
|
186
|
+
custom_label_id: label,
|
187
|
+
custom_testrail_bdd_scenario:[{content: bdd}]
|
188
|
+
}
|
189
|
+
client.send_post("update_case/#{tc_id}", payload)
|
190
|
+
rescue TestRail::APIError => e
|
191
|
+
puts "Error occurred while creating test case with title: '#{title}'"
|
192
|
+
puts "Error message: #{e.message}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
require_relative './dataprep'
|
5
|
+
require_relative './projects'
|
6
|
+
require 'json'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
module Tms
|
10
|
+
module Testplan
|
11
|
+
module_function
|
12
|
+
|
13
|
+
include Dataprep
|
14
|
+
include Projects
|
15
|
+
|
16
|
+
# Returns an existing test plan
|
17
|
+
# @param client testrail
|
18
|
+
# @param plan id
|
19
|
+
def get_plan(client, plan_id)
|
20
|
+
client.send_get("get_plan/#{plan_id}")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns all list existing test plans and handle plans more than 250
|
24
|
+
# @param client testrail
|
25
|
+
# @param project_id
|
26
|
+
def get_plans(client, project_id, filter = '')
|
27
|
+
offset = 0
|
28
|
+
plans = []
|
29
|
+
|
30
|
+
puts "Retrieving test plans from project id #{project_id} ..."
|
31
|
+
|
32
|
+
loop do
|
33
|
+
get_plans = client.send_get("get_plans/#{project_id}&#{filter}&offset=#{offset}&is_completed=0")
|
34
|
+
plans.push get_plans['plans']
|
35
|
+
offset += 250
|
36
|
+
break if get_plans['_links']['next'].nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
plans = plans.flatten
|
40
|
+
return plans
|
41
|
+
end
|
42
|
+
|
43
|
+
# Creates a new test plan
|
44
|
+
# @param client testrail
|
45
|
+
# @param project id
|
46
|
+
# @param payload object
|
47
|
+
def create_testplan(client, project_id, payload)
|
48
|
+
client.send_post("add_plan/#{project_id}", payload)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Adds one or more new test runs to a test plan
|
52
|
+
# @param client testrail
|
53
|
+
# @param plan id
|
54
|
+
# @param suite id
|
55
|
+
# @param array of test runs
|
56
|
+
def add_plan_entry(client, plan_id, suite_id, runs)
|
57
|
+
payload = {
|
58
|
+
suite_id: suite_id,
|
59
|
+
include_all: false,
|
60
|
+
entries: runs
|
61
|
+
}
|
62
|
+
puts payload
|
63
|
+
client.send_post("add_plan_entry/#{plan_id}", payload)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Close the active test plan in the testrail project
|
67
|
+
# @param client testrail
|
68
|
+
# @param plan id
|
69
|
+
def close_test_plan(client, plan_id)
|
70
|
+
client.send_post("close_plan/#{plan_id}", {})
|
71
|
+
end
|
72
|
+
|
73
|
+
# Closes test plans created before a specified number of months ago.
|
74
|
+
#
|
75
|
+
# This method closes test plans that were created before the specified number
|
76
|
+
# of months ago for all projects. It iterates through the projects, retrieves
|
77
|
+
# the test plans that meet the criteria, and then closes each test run.
|
78
|
+
#
|
79
|
+
# @param client [DataprepClient] The Dataprep client instance.
|
80
|
+
# @param month [Integer] The number of months ago to consider for closing test plans.
|
81
|
+
def close_test_plan_months_before(client, month)
|
82
|
+
filter = "created_before=#{month}&created_by=1"
|
83
|
+
Projects.get_list_project_ids(client).each do |project_id|
|
84
|
+
get_plans(client, project_id, filter).each do |run_detail|
|
85
|
+
plan_id = run_detail['id']
|
86
|
+
created_on = run_detail['created_on']
|
87
|
+
close_test_plan(client, plan_id)
|
88
|
+
puts "Close Testrail Plan ID: #{plan_id} with started on date: #{created_on}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# TestRail API binding for Java (API v2, available since TestRail 3.0)
|
3
|
+
# Updated for TestRail 5.7
|
4
|
+
#
|
5
|
+
# Learn more:
|
6
|
+
#
|
7
|
+
# http://docs.gurock.com/testrail-api2/start
|
8
|
+
# http://docs.gurock.com/testrail-api2/accessing
|
9
|
+
#
|
10
|
+
# Copyright Gurock Software GmbH. See license.md for details.
|
11
|
+
#
|
12
|
+
|
13
|
+
require 'net/http'
|
14
|
+
require 'net/https'
|
15
|
+
require 'uri'
|
16
|
+
require 'json'
|
17
|
+
|
18
|
+
module TestRail
|
19
|
+
class APIClient
|
20
|
+
@url = ''
|
21
|
+
@user = ''
|
22
|
+
@password = ''
|
23
|
+
@openTimeout = 360
|
24
|
+
@readTimeout = 360
|
25
|
+
|
26
|
+
attr_accessor :user, :password
|
27
|
+
|
28
|
+
def initialize(base_url)
|
29
|
+
base_url += '/' unless base_url.match(%r{/$})
|
30
|
+
@url = base_url + 'index.php?/api/v2/'
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Send Get
|
35
|
+
#
|
36
|
+
# Issues a GET request (read) against the API and returns the result
|
37
|
+
# (as Ruby hash).
|
38
|
+
# If 'get_attachment/{id}' is successful, returns the data parameter
|
39
|
+
#
|
40
|
+
# Arguments:
|
41
|
+
#
|
42
|
+
# uri The API method to call including parameters
|
43
|
+
# (e.g. get_case/1)
|
44
|
+
# data When using get_attachment/{id}, this should be
|
45
|
+
# the file path (including filename) where the
|
46
|
+
# attachment should be saved
|
47
|
+
#
|
48
|
+
def send_get(uri, data = nil)
|
49
|
+
_send_request('GET', uri, data)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Send POST
|
54
|
+
#
|
55
|
+
# Issues a POST request (write) against the API and returns the result
|
56
|
+
# (as Ruby hash).
|
57
|
+
#
|
58
|
+
# Arguments:
|
59
|
+
#
|
60
|
+
# uri The API method to call including parameters
|
61
|
+
# (e.g. add_case/1)
|
62
|
+
# data The data to submit as part of the request (as
|
63
|
+
# Ruby hash, strings must be UTF-8 encoded)
|
64
|
+
# If adding an attachment, should be the path
|
65
|
+
# to the file
|
66
|
+
#
|
67
|
+
def send_post(uri, data)
|
68
|
+
_send_request('POST', uri, data)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def _send_request(method, uri, data)
|
74
|
+
url = URI.parse(@url + uri)
|
75
|
+
if method == 'POST'
|
76
|
+
request = Net::HTTP::Post.new(url.path + '?' + url.query, :open_timeout => @openTimeout)
|
77
|
+
if uri.start_with?('add_attachment') || uri.start_with?('add_bdd')
|
78
|
+
# SOURCE: https://yukimotopress.github.io/http
|
79
|
+
boundary = 'TestRailAPIAttachmentBoundary'
|
80
|
+
post_body = []
|
81
|
+
post_body << "--#{boundary}\r\n"
|
82
|
+
post_body << "Content-Disposition: form-data; name=\"attachment\"; filename=\"#{File.basename(data)}\"\r\n"
|
83
|
+
post_body << "\r\n"
|
84
|
+
post_body << File.open(data, 'rb') { |io| io.read }
|
85
|
+
post_body << "\r\n--#{boundary}--\r\n"
|
86
|
+
|
87
|
+
request.body = post_body.join
|
88
|
+
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
|
89
|
+
else
|
90
|
+
request['Content-Type'] = 'application/json'
|
91
|
+
request.body = JSON.dump(data)
|
92
|
+
end
|
93
|
+
else
|
94
|
+
request = Net::HTTP::Get.new(url.path + '?' + url.query, :open_timeout => @openTimeout, :read_timeout => @readTimeout)
|
95
|
+
request['Content-Type'] = 'application/json'
|
96
|
+
end
|
97
|
+
request.basic_auth(@user, @password)
|
98
|
+
|
99
|
+
conn = Net::HTTP.new(url.host, url.port)
|
100
|
+
conn.open_timeout = @openTimeout
|
101
|
+
conn.read_timeout = @readTimeout
|
102
|
+
if url.scheme == 'https'
|
103
|
+
conn.use_ssl = true
|
104
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
105
|
+
end
|
106
|
+
response = conn.request(request)
|
107
|
+
|
108
|
+
if response.body && !response.body.empty? && (response.code == '200')
|
109
|
+
if uri.start_with?('get_attachment/')
|
110
|
+
File.open(data, 'w') { |file| file.write(response.body) }
|
111
|
+
result = data
|
112
|
+
elsif uri.start_with?('get_bdd/')
|
113
|
+
result = response.body
|
114
|
+
else
|
115
|
+
result = JSON.parse(response.body)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
result = {}
|
119
|
+
end
|
120
|
+
|
121
|
+
if response.code != '200'
|
122
|
+
error = if result && result.key?('error')
|
123
|
+
'"' + result['error'] + '"'
|
124
|
+
else
|
125
|
+
'No additional error message received'
|
126
|
+
end
|
127
|
+
raise APIError, format('TestRail API returned HTTP %s (%s)', response.code, response.body, error)
|
128
|
+
end
|
129
|
+
|
130
|
+
result
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class APIError < StandardError
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
require_relative './dataprep'
|
5
|
+
require_relative './projects'
|
6
|
+
require 'json'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
module Tms
|
10
|
+
module Testrun
|
11
|
+
module_function
|
12
|
+
|
13
|
+
include Dataprep
|
14
|
+
include Projects
|
15
|
+
|
16
|
+
# This method will get test run id on current milestone
|
17
|
+
# @param client testrail
|
18
|
+
# @param project id
|
19
|
+
# @param suite id
|
20
|
+
# @param milestone id
|
21
|
+
# @param section id
|
22
|
+
# @param section name
|
23
|
+
# @param tcs id is list of test case to put on test run
|
24
|
+
# @param env
|
25
|
+
def testrun_id(client, project_id, suite_id, milestone_id, section_id, section_name, tc_ids, env, platform_name)
|
26
|
+
list_tc = tc_ids[section_id]
|
27
|
+
run_id = ''
|
28
|
+
env = env.eql?('') ? '' : "_#{env}"
|
29
|
+
if platform_name != ''
|
30
|
+
test_run_name = "Test_Run_#{section_name}#{env}_#{platform_name}"
|
31
|
+
else
|
32
|
+
test_run_name = "Test_Run_#{section_name}#{env}"
|
33
|
+
end
|
34
|
+
|
35
|
+
is_run_name_avail = false
|
36
|
+
|
37
|
+
if !list_tc.nil?
|
38
|
+
response = client.send_get("get_runs/#{project_id}&milestone_id=#{milestone_id}")['runs']
|
39
|
+
|
40
|
+
if response.empty?
|
41
|
+
run_id = create_testrun(client, project_id, suite_id, milestone_id, list_tc, test_run_name)
|
42
|
+
else
|
43
|
+
response.each do |run|
|
44
|
+
next unless run['name'].eql? test_run_name
|
45
|
+
|
46
|
+
is_run_name_avail = true
|
47
|
+
run_id = update_testrun(client, run['id'], milestone_id, list_tc)
|
48
|
+
puts "TEST RUN ID : #{run_id}"
|
49
|
+
break
|
50
|
+
end
|
51
|
+
|
52
|
+
run_id = create_testrun(client, project_id, suite_id, milestone_id, list_tc, test_run_name) unless is_run_name_avail
|
53
|
+
end
|
54
|
+
else
|
55
|
+
abort('List test cases is empty')
|
56
|
+
end
|
57
|
+
run_id
|
58
|
+
end
|
59
|
+
|
60
|
+
# This method will get test run id on current milestone
|
61
|
+
# @param client testrail
|
62
|
+
# @param project id
|
63
|
+
# @param milestone id
|
64
|
+
def testrun_id_by_milestone(client, project_id, milestone_id)
|
65
|
+
client.send_get("get_runs/#{project_id}&milestone_id=#{milestone_id}")['runs']
|
66
|
+
end
|
67
|
+
|
68
|
+
# This method will get test run for a specific suite
|
69
|
+
# @param client testrail
|
70
|
+
# @param project id
|
71
|
+
# @param milestone id
|
72
|
+
# @param suite id
|
73
|
+
def testrun_id_by_suite(client, project_id, milestone_id, suite_id)
|
74
|
+
offset = 0
|
75
|
+
runs = []
|
76
|
+
|
77
|
+
loop do
|
78
|
+
get_runs = client.send_get("get_runs/#{project_id}&milestone_id=#{milestone_id}&suite_id=#{suite_id}&offset=#{offset}&is_completed=0")
|
79
|
+
runs.push get_runs['runs']
|
80
|
+
offset += 250
|
81
|
+
break if get_runs['_links']['next'].nil?
|
82
|
+
end
|
83
|
+
runs = runs.flatten
|
84
|
+
return runs
|
85
|
+
end
|
86
|
+
|
87
|
+
# This method will create test run
|
88
|
+
# @param client testrail
|
89
|
+
# @param project id
|
90
|
+
# @param suite id
|
91
|
+
# @param milestone id
|
92
|
+
# @param tcs id is list of test case to put on test run
|
93
|
+
# @param test_run_name
|
94
|
+
def create_testrun(client, project_id, suite_id, milestone_id = 0, list_tc, test_run_name)
|
95
|
+
payload = { suite_id: suite_id.to_i, name: test_run_name.to_s,
|
96
|
+
case_ids: list_tc, include_all: false, milestone_id: milestone_id }
|
97
|
+
payload.delete(:milestone_id) if milestone_id.eql?(0)
|
98
|
+
client.send_post("add_run/#{project_id}", payload)['id']
|
99
|
+
end
|
100
|
+
|
101
|
+
# This method will update list of test case on existing test run
|
102
|
+
# @param client testrail
|
103
|
+
# @param test_run_id is existing test run
|
104
|
+
# @param milestone id
|
105
|
+
# @param tcs id is list of test case to put on test run
|
106
|
+
def update_testrun(client, test_run_id, milestone_id, list_tc)
|
107
|
+
payload = { case_ids: list_tc, include_all: false, milestone_id: milestone_id}
|
108
|
+
client.send_post("update_run/#{test_run_id}", payload)['id']
|
109
|
+
end
|
110
|
+
|
111
|
+
# This method will get all test result on test run
|
112
|
+
# @param client testrail
|
113
|
+
# @param test_run_id is existing test run
|
114
|
+
# @param offset is the number that sets the position response start from
|
115
|
+
# handle tests more than 250 entries
|
116
|
+
def test_ids(client, test_run_id, offset = 0)
|
117
|
+
offset = 0
|
118
|
+
tests = []
|
119
|
+
|
120
|
+
loop do
|
121
|
+
get_tests = client.send_get("get_tests/#{test_run_id}&offset=#{offset}")
|
122
|
+
tests.push get_tests['tests']
|
123
|
+
offset += 250
|
124
|
+
break if get_tests['_links']['next'].nil?
|
125
|
+
end
|
126
|
+
tests = tests.flatten
|
127
|
+
return tests
|
128
|
+
end
|
129
|
+
|
130
|
+
# This method will get all test result on test run
|
131
|
+
# @param client testrail
|
132
|
+
# @param test_run_id is existing test run
|
133
|
+
def get_runs(client, project_id, filter = '')
|
134
|
+
offset = 0
|
135
|
+
runs = []
|
136
|
+
|
137
|
+
puts "Retrieving test runs from project id #{project_id} ..."
|
138
|
+
|
139
|
+
loop do
|
140
|
+
get_runs = client.send_get("get_runs/#{project_id}&#{filter}&offset=#{offset}&is_completed=0")
|
141
|
+
runs.push get_runs['runs']
|
142
|
+
offset += 250
|
143
|
+
break if get_runs['_links']['next'].nil?
|
144
|
+
end
|
145
|
+
runs = runs.flatten
|
146
|
+
return runs
|
147
|
+
end
|
148
|
+
|
149
|
+
# This method will delete test run
|
150
|
+
# @param client testrail
|
151
|
+
# @param test run id
|
152
|
+
def delete_testrun(client, run_id)
|
153
|
+
client.send_post("delete_run/#{run_id}", {})
|
154
|
+
end
|
155
|
+
|
156
|
+
# This method will close test run
|
157
|
+
# @param client testrail
|
158
|
+
# @param test run id
|
159
|
+
def close_test_run(client, run_id)
|
160
|
+
client.send_post("close_run/#{run_id}", {})
|
161
|
+
puts "Close the Test Run with ID: #{run_id}"
|
162
|
+
end
|
163
|
+
|
164
|
+
# Closes test runs created before a specified number of months ago.
|
165
|
+
#
|
166
|
+
# This method closes test runs that were created before the specified number
|
167
|
+
# of months ago for all projects. It iterates through the projects, retrieves
|
168
|
+
# the test runs that meet the criteria, and then closes each test run.
|
169
|
+
#
|
170
|
+
# @param client [DataprepClient] The Dataprep client instance.
|
171
|
+
# @param month [Integer] The number of months ago to consider for closing test runs.
|
172
|
+
def close_test_run_months_before(client, month)
|
173
|
+
filter = "created_before=#{month}&created_by=1"
|
174
|
+
Projects.get_list_project_ids(client).each do |project_id|
|
175
|
+
get_runs(client, project_id, filter).each do |run_detail|
|
176
|
+
run_id = run_detail['id']
|
177
|
+
created_on = run_detail['created_on']
|
178
|
+
close_test_run(client, run_id)
|
179
|
+
puts "Close Testrail Run ID: #{run_id} with started on date: #{created_on}"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Tms
|
8
|
+
module Testsuite
|
9
|
+
module_function
|
10
|
+
|
11
|
+
# This method will get suite id
|
12
|
+
# will create new test suite with name 'master' if there is no test suite
|
13
|
+
# @param client testrail
|
14
|
+
# @param project id
|
15
|
+
def testsuite_id(client, project_id, suite_name)
|
16
|
+
response = client.send_get("get_suites/#{project_id}")
|
17
|
+
if response == []
|
18
|
+
payload = { name: 'master', description: 'created by automation' }
|
19
|
+
client.send_post("add_suite/#{project_id}", payload)
|
20
|
+
client.send_get("get_suites/#{project_id}")
|
21
|
+
else
|
22
|
+
found_suites = response.select { |suites| suites['name']&.include?(suite_name) }
|
23
|
+
|
24
|
+
if found_suites.empty?
|
25
|
+
"Creating suites of #{suite_name}..."
|
26
|
+
payload = { name: 'master', description: 'created by automation' }
|
27
|
+
client.send_post("add_suite/#{project_id}", payload)
|
28
|
+
else
|
29
|
+
puts "Fetching suites of #{suite_name}..."
|
30
|
+
return found_suites
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a list of test suites for a project.
|
36
|
+
# @param client testrail
|
37
|
+
# @param project id
|
38
|
+
def suites(client, project_id)
|
39
|
+
client.send_get("get_suites/#{project_id}")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns an existing test suite
|
43
|
+
# @param client testrail
|
44
|
+
# @param suite id
|
45
|
+
def suite_id(client, suite_id)
|
46
|
+
client.send_get("get_suite/#{suite_id}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|