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,334 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'testrail/testrail'
|
4
|
+
require_relative 'testrail/milestone'
|
5
|
+
require_relative 'testrail/testcase'
|
6
|
+
require_relative 'testrail/testrun'
|
7
|
+
require_relative 'testrail/dataprep'
|
8
|
+
require_relative 'testrail/testsuite'
|
9
|
+
require_relative 'testrail/report'
|
10
|
+
require_relative 'testrail/cleanup'
|
11
|
+
require_relative 'testrail/attachment'
|
12
|
+
require_relative 'testrail/log'
|
13
|
+
require_relative 'testrail/results'
|
14
|
+
require_relative 'testrail/sections'
|
15
|
+
require_relative 'testrail/testbdd.rb'
|
16
|
+
|
17
|
+
require_relative 'import/importflutter'
|
18
|
+
require_relative 'import/importgolang'
|
19
|
+
require_relative 'import/importjest'
|
20
|
+
require_relative 'import/importrspec'
|
21
|
+
require_relative 'import/importjunit'
|
22
|
+
require_relative 'import/importcucumber'
|
23
|
+
require_relative 'import/importfeature'
|
24
|
+
|
25
|
+
require_relative 'db/mysql'
|
26
|
+
require_relative '../util/script/generatereport'
|
27
|
+
|
28
|
+
require 'json'
|
29
|
+
require 'fileutils'
|
30
|
+
require 'dotenv'
|
31
|
+
require 'colorize'
|
32
|
+
require 'open-uri'
|
33
|
+
require 'mysql2'
|
34
|
+
require 'thor'
|
35
|
+
require 'highline'
|
36
|
+
require 'gitlab'
|
37
|
+
|
38
|
+
module Tms
|
39
|
+
module Preprocessing
|
40
|
+
module_function
|
41
|
+
|
42
|
+
include Dataprep
|
43
|
+
include Milestone
|
44
|
+
include Testcase
|
45
|
+
include Testrun
|
46
|
+
include Testsuite
|
47
|
+
include Report
|
48
|
+
include Log
|
49
|
+
include Sections
|
50
|
+
|
51
|
+
include Flutter
|
52
|
+
include Golang
|
53
|
+
include Jest
|
54
|
+
include Rspec
|
55
|
+
include JUnit
|
56
|
+
include Cucumber
|
57
|
+
include Cleanup
|
58
|
+
include Attachment
|
59
|
+
include GenerateReport
|
60
|
+
|
61
|
+
# variable to store Run ID of current tests
|
62
|
+
@@run_id = ''
|
63
|
+
|
64
|
+
# This method will process json report and put the result into testrail
|
65
|
+
def execute_preprocessing(report_file, milestone_name, attachment_dir, runner_type)
|
66
|
+
puts 'Execute preprocessing, NOT handle TEST ID'
|
67
|
+
client = Dataprep.client_tr
|
68
|
+
file_name = report_file.size > 1 ? File.basename(report_file[0])[0...-7].concat(".json") : File.basename(report_file[0])
|
69
|
+
tr_version = Dataprep.testrail_version(client, ENV['TR_BASEURL'])
|
70
|
+
project_id = Dataprep.project_id_by_report_file(client, file_name, tr_version)
|
71
|
+
puts "PROJECT ID : #{project_id}"
|
72
|
+
section_name = Dataprep.section_name(file_name)
|
73
|
+
puts "SECTION NAME : #{section_name}"
|
74
|
+
env = Dataprep.test_env(file_name)
|
75
|
+
platform_name = Dataprep.platform_name(file_name)
|
76
|
+
suite_id = Testsuite.testsuite_id(client, project_id, "master")[0]['id']
|
77
|
+
puts "SUITE ID : #{suite_id}"
|
78
|
+
raise "Error suite id not found" if suite_id.nil?
|
79
|
+
section_id = Dataprep.section_id(client, project_id, suite_id, section_name, tr_version)
|
80
|
+
puts "SECTION ID : #{section_id}"
|
81
|
+
|
82
|
+
# handle legacy cli without runner type parameter
|
83
|
+
if runner_type.eql? ''
|
84
|
+
# read json runner type for legacy
|
85
|
+
runner_type_file = if ENV['CI']
|
86
|
+
File.read('/testrail/runner_type.json')
|
87
|
+
else
|
88
|
+
File.read('./runner_type.json')
|
89
|
+
end
|
90
|
+
runner_type_data = JSON.parse(runner_type_file)
|
91
|
+
|
92
|
+
filtererd_runner_type_data = runner_type_data.find do |obj|
|
93
|
+
obj['project_id'] == project_id && obj['test_type'].casecmp?(section_name)
|
94
|
+
end
|
95
|
+
raise 'No runner found with project and test type' if filtererd_runner_type_data.nil?
|
96
|
+
|
97
|
+
runner_type = filtererd_runner_type_data['runner']
|
98
|
+
end
|
99
|
+
|
100
|
+
@@cases = Testcase.get_cases(client, project_id, suite_id, section_id, offset = 0)
|
101
|
+
|
102
|
+
report_file.each do |report|
|
103
|
+
puts "Start #{report}"
|
104
|
+
file = File.read("#{report}")
|
105
|
+
data_hash = JSON.parse(file) unless report.include? ".xml"
|
106
|
+
|
107
|
+
case runner_type
|
108
|
+
when 'rspec'
|
109
|
+
Rspec.import_data(client, project_id, suite_id, section_id, data_hash, tr_version)
|
110
|
+
when 'dart'
|
111
|
+
Flutter.import_data(client, project_id, suite_id, section_id, data_hash, tr_version)
|
112
|
+
when 'jest'
|
113
|
+
Jest.import_data(client, project_id, suite_id, section_id, data_hash, tr_version)
|
114
|
+
when 'go'
|
115
|
+
Golang.import_data(client, project_id, suite_id, section_id, data_hash, tr_version)
|
116
|
+
when 'junit'
|
117
|
+
JUnit.import_data(client, project_id, suite_id, section_id, report, tr_version)
|
118
|
+
when 'cucumber'
|
119
|
+
Cucumber.import_data(client, project_id, suite_id, section_id, data_hash, tr_version)
|
120
|
+
else
|
121
|
+
abort("invalid runner type - #{runner_type}")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
tc_ids = Testcase.test_ids
|
126
|
+
test_results = Testcase.test_results
|
127
|
+
milestone_id = Milestone.milestone_id(client, project_id, milestone_name, tr_version)
|
128
|
+
puts "Updating milestone #{milestone_name} with ID #{milestone_id}..."
|
129
|
+
list_platform = ['dweb', 'mweb', 'api', 'android', 'ios']
|
130
|
+
if list_platform.include?(platform_name.downcase)
|
131
|
+
run_id = Testrun.testrun_id(client, project_id, suite_id, milestone_id, section_id, section_name, tc_ids, env, platform_name)
|
132
|
+
else
|
133
|
+
run_id = Testrun.testrun_id(client, project_id, suite_id, milestone_id, section_id, section_name, tc_ids, env, platform_name='')
|
134
|
+
end
|
135
|
+
|
136
|
+
Report.post(client, test_results, run_id)
|
137
|
+
# remove to prevent milestone is not show when create tc
|
138
|
+
# Milestone.completed_old_milestone(client, project_id)
|
139
|
+
|
140
|
+
unless attachment_dir.eql?('')
|
141
|
+
puts 'attach files to test cases result...'
|
142
|
+
result_ids = {}
|
143
|
+
Report.results(client, run_id).each { |result| result_ids.store("#{result['test_id']}".to_sym, "#{result['id']}") }
|
144
|
+
Testrun.test_ids(client, run_id).each do |data|
|
145
|
+
refs = data['refs'].nil? ? '' : data['refs']
|
146
|
+
title = data['title'].gsub(':', '').gsub('\'','').gsub(' ', '_')
|
147
|
+
folder_path = attachment_dir.to_s.tr('*', '')
|
148
|
+
Dir["#{attachment_dir}"].select do |file|
|
149
|
+
if File.basename(file).include?(title) && File.basename(file).include?(refs)
|
150
|
+
begin
|
151
|
+
temp_file = folder_path + refs.to_s + "_" + title.to_s + File.extname(file)
|
152
|
+
File.rename(file, temp_file)
|
153
|
+
Attachment.attach_file(client, result_ids[data['id'].to_s.to_sym], temp_file)
|
154
|
+
puts "#{temp_file} uploaded successfully"
|
155
|
+
rescue => e
|
156
|
+
puts "#{temp_file} not uploaded"
|
157
|
+
puts e.message
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
Testrun.close_test_run(client, run_id)
|
165
|
+
Milestone.completed_milestone(client, milestone_id)
|
166
|
+
end
|
167
|
+
|
168
|
+
def execute_preprocessing_bdd(report_file, suite_name, section_name)
|
169
|
+
puts 'Execute preprocessing BDD automation results, handle TEST ID'
|
170
|
+
client = Dataprep.client_tr
|
171
|
+
file_name = report_file.size > 1 ? File.basename(report_file[0])[0...-7].concat(".json") : File.basename(report_file[0])
|
172
|
+
tr_version = Dataprep.testrail_version(client, ENV['TR_BASEURL'])
|
173
|
+
project_id = Dataprep.project_id_by_report_file(client, file_name, tr_version)
|
174
|
+
puts "PROJECT ID : #{project_id}"
|
175
|
+
env = Dataprep.test_env(file_name)
|
176
|
+
puts "PLATFORM/SUITE NAME : #{suite_name}"
|
177
|
+
suite_id = Testsuite.testsuite_id(client, project_id, suite_name)[0]['id']
|
178
|
+
puts "SUITE ID : #{suite_id}"
|
179
|
+
raise "Error suite id not found" if suite_id.nil?
|
180
|
+
section_id = Dataprep.section_id(client, project_id, suite_id, section_name, tr_version)
|
181
|
+
puts "SECTION ID : #{section_id}"
|
182
|
+
|
183
|
+
report_file.each do |report|
|
184
|
+
puts "Start #{report}"
|
185
|
+
file = File.read("#{report}")
|
186
|
+
data_hash = JSON.parse(file) unless report.include? ".xml"
|
187
|
+
|
188
|
+
Cucumber.import_data_bdd(client, project_id, suite_id, section_id, data_hash, tr_version)
|
189
|
+
end
|
190
|
+
|
191
|
+
test_type = ENV['TESTRAIL_TEST_TYPE']
|
192
|
+
milestone_id = ENV["TESTRAIL_#{test_type}_MILESTONE_ID"]
|
193
|
+
run_id = ENV["TESTRAIL_#{test_type}_RUN_ID"]
|
194
|
+
puts "Test Type: #{test_type}"
|
195
|
+
|
196
|
+
unless test_type.downcase.eql? 'regression'
|
197
|
+
unless milestone_id.nil? || milestone_id.empty?
|
198
|
+
state = Milestone.get_milestone_state(client, milestone_id)
|
199
|
+
unless state == true
|
200
|
+
Milestone.completed_milestone(client, milestone_id)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
unless run_id.nil? || run_id.empty?
|
205
|
+
Testrun.close_test_run(client, run_id)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# This method will clean up refs on testrail
|
211
|
+
def execute_clean_testcase(project_id)
|
212
|
+
client = Dataprep.client_tr
|
213
|
+
Cleanup.cleanup_tc(client, project_id)
|
214
|
+
end
|
215
|
+
|
216
|
+
# This method will generate traceability metric and coverage report
|
217
|
+
def execute_generate_report(project_name, milestone_name)
|
218
|
+
client = Dataprep.client_tr
|
219
|
+
tr_version = Dataprep.testrail_version(client, ENV['TR_BASEURL'])
|
220
|
+
project_id = Dataprep.project_id_by_name(client, project_name, tr_version)
|
221
|
+
GenerateReport.generate(project_id, milestone_name)
|
222
|
+
end
|
223
|
+
|
224
|
+
# This method will capture test report of current milestone
|
225
|
+
def execute_capture_result(project_name, milestone_name)
|
226
|
+
client = Dataprep.client_tr
|
227
|
+
tr_version = Dataprep.testrail_version(client, ENV['TR_BASEURL'])
|
228
|
+
project_id = Dataprep.project_id_by_name(client, project_name, tr_version)
|
229
|
+
milestone_id = Milestone.get_milestone_id(client, project_id, milestone_name)
|
230
|
+
|
231
|
+
@@run_id = Testrun.testrun_id_by_milestone(client, project_id, milestone_id)
|
232
|
+
GenerateReport.capture_dashboard(project_id, milestone_name)
|
233
|
+
end
|
234
|
+
|
235
|
+
# This method will delete milestone for merge request test
|
236
|
+
def delete_milestones_runs(project_name, milestone_name)
|
237
|
+
client = Dataprep.client_tr
|
238
|
+
tr_version = Dataprep.testrail_version(client, ENV['TR_BASEURL'])
|
239
|
+
project_id = Dataprep.project_id_by_name(client, project_name, tr_version)
|
240
|
+
milestone_id = Milestone.get_milestone_id(client, project_id, milestone_name)
|
241
|
+
Milestone.delete_milestone(client, milestone_id)
|
242
|
+
|
243
|
+
# Delete test runs associated to the milestone
|
244
|
+
run_ids = @@run_id.map { |run| run["id"] }
|
245
|
+
|
246
|
+
unless run_ids.nil?
|
247
|
+
run_ids.each do |run_id|
|
248
|
+
Testrun.delete_testrun(client, run_id)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
puts "Milestone #{milestone_name} and #{@@run_id.size} associated test runs are deleted!"
|
252
|
+
end
|
253
|
+
|
254
|
+
# Returns Run ID of current tests (by provide Project ID and Milestone ID), the enable next funciton to get what test type included (ex: UT, E2E)
|
255
|
+
def run_id
|
256
|
+
@@run_id
|
257
|
+
end
|
258
|
+
|
259
|
+
# This method will delete all cases from desired section
|
260
|
+
def delete_cases_from_section(suite_id, group_name, limit)
|
261
|
+
client = Dataprep.client_tr
|
262
|
+
|
263
|
+
# find cases from a section
|
264
|
+
suite = Testsuite.suite_id(client, suite_id)
|
265
|
+
project_id = suite['project_id']
|
266
|
+
suite_sections = Sections.get_sections(client, project_id, suite_id)
|
267
|
+
section = suite_sections['sections'].find { |section| section['name'].downcase.eql? group_name }
|
268
|
+
raise "no group name found" if section.nil?
|
269
|
+
|
270
|
+
# get all existing test cases and delete it with pagination
|
271
|
+
puts 'Retrieving cases from Testrail...'
|
272
|
+
puts "Deleting in batch with limit = #{limit}\n"
|
273
|
+
page = 0
|
274
|
+
loop do
|
275
|
+
page += 1
|
276
|
+
get_cases = Testcase.get_cases(client, project_id, suite_id, section['id'], offset = 0)
|
277
|
+
case_ids = get_cases.map { |case_object| case_object['id']}
|
278
|
+
puts "deleting cases for page: #{page}"
|
279
|
+
delete_cases = Testcase.delete_cases_from_suite(client, suite_id, case_ids)
|
280
|
+
puts "cases deleted #{case_ids.to_s}"
|
281
|
+
|
282
|
+
break if get_cases['_links']['next'].nil?
|
283
|
+
|
284
|
+
sleep(5)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# This method will upload feature to testrail
|
289
|
+
def upload_feature(dir)
|
290
|
+
# Filter out entries that are not files (directories, ".", and "..")
|
291
|
+
work_dir = Dir.entries(dir).reject { |entry| File.directory?(File.join(dir, entry)) || entry == '.' || entry == '..' }
|
292
|
+
files_to_upload = []
|
293
|
+
|
294
|
+
work_dir.each do |file_name|
|
295
|
+
if file_name.end_with?('.feature')
|
296
|
+
puts "Processing file #{file_name}"
|
297
|
+
client = Dataprep.client_tr
|
298
|
+
file_path = File.join(dir, file_name)
|
299
|
+
|
300
|
+
# Handle creation new test cases
|
301
|
+
if file_name.include?('_')
|
302
|
+
parts = file_name.split('_')
|
303
|
+
project_name = parts[0].gsub("-", " ")
|
304
|
+
suite_name = parts[1] + " Automation"
|
305
|
+
group_name = parts[2].sub('.feature', '')
|
306
|
+
|
307
|
+
project_id = Cucumber.search_project(client, project_name)
|
308
|
+
suite_id = Cucumber.search_suite(client, project_id, suite_name)
|
309
|
+
section_list = Sections.get_sections(client, project_id, suite_id)
|
310
|
+
section_id = section_list['sections'].find { |section| section['name'].downcase.eql? group_name }['id']
|
311
|
+
|
312
|
+
# Handle post body that contains json
|
313
|
+
if File.read(file_path).include? ('"""')
|
314
|
+
Feature.add_case(client, section_id, file_path)
|
315
|
+
else
|
316
|
+
Testbdd.add_bdd(client, section_id, file_path)
|
317
|
+
end
|
318
|
+
|
319
|
+
files_to_upload << file_name
|
320
|
+
else
|
321
|
+
# Handle updating existing test cases
|
322
|
+
case_id = file_name.sub('.feature', '')
|
323
|
+
Feature.update_bdd(client, case_id, file_path)
|
324
|
+
files_to_upload << file_name
|
325
|
+
end
|
326
|
+
|
327
|
+
# log separator for each file
|
328
|
+
puts "----------------------------"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
puts "Successfully processed #{files_to_upload.length} feature files"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
data/lib/regression.rb
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'testrail/testrail'
|
4
|
+
require_relative 'testrail/milestone'
|
5
|
+
require_relative 'testrail/testcase'
|
6
|
+
require_relative 'testrail/testrun'
|
7
|
+
require_relative 'testrail/dataprep'
|
8
|
+
require_relative 'testrail/testsuite'
|
9
|
+
require_relative 'testrail/testplan'
|
10
|
+
require_relative 'testrail/sections'
|
11
|
+
require_relative 'testrail/log'
|
12
|
+
|
13
|
+
|
14
|
+
module Tms
|
15
|
+
module Regression
|
16
|
+
module_function
|
17
|
+
|
18
|
+
include Dataprep
|
19
|
+
include Milestone
|
20
|
+
include Testcase
|
21
|
+
include Testrun
|
22
|
+
include Testsuite
|
23
|
+
include Testplan
|
24
|
+
include Sections
|
25
|
+
include Log
|
26
|
+
|
27
|
+
# Preparation for regression:
|
28
|
+
# creating milestone, test plans, and test runs
|
29
|
+
# @param app name. ex: android_marketplace
|
30
|
+
# @param version name. ex: v16.8
|
31
|
+
def execute_regression_prep(app_name, version_name)
|
32
|
+
# getting app name
|
33
|
+
@platform, @app_name = app_name.split('_')
|
34
|
+
|
35
|
+
project_id = get_app_project_id(app_name)
|
36
|
+
client = Dataprep.client_tr
|
37
|
+
|
38
|
+
main_version = version_name.match(/^v\d+\.\d+/)[0]
|
39
|
+
milestone_name = "#{@platform} #{@app_name} #{main_version}"
|
40
|
+
puts "Creating milestone regression for #{milestone_name}"
|
41
|
+
|
42
|
+
milestone = create_regression_milestone(client, project_id, milestone_name)
|
43
|
+
test_plans = create_squad_test_plan(client, project_id, milestone, main_version)
|
44
|
+
puts generate_json_output(app_name, main_version, test_plans)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns project id for the app project
|
48
|
+
# @param app name. ex: android_marketplace
|
49
|
+
def get_app_project_id(app_name)
|
50
|
+
project_id = if app_name.include? 'android'
|
51
|
+
ENV['TR_ANDROID_PROJECT_ID']
|
52
|
+
elsif app_name.include? 'ios'
|
53
|
+
ENV['TR_IOS_PROJECT_ID']
|
54
|
+
else
|
55
|
+
raise 'Incorrect app name!'
|
56
|
+
end
|
57
|
+
return project_id
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create a new milestone for regresion
|
61
|
+
# @param client testrail
|
62
|
+
# @param project id
|
63
|
+
# @param version name
|
64
|
+
def create_regression_milestone(client, project_id, version_name)
|
65
|
+
# check if the same milstone is already created
|
66
|
+
response = Milestone.get_milestones(client, project_id)
|
67
|
+
same_milestone = response.select { |milestone| milestone['name'].include? version_name }
|
68
|
+
|
69
|
+
if !same_milestone.eql? []
|
70
|
+
puts "Same milestone is exist. Skipping regression preparation..."
|
71
|
+
exit 1
|
72
|
+
end
|
73
|
+
|
74
|
+
response = Milestone.create_milestone(client, project_id, version_name)
|
75
|
+
puts "Milestone " + version_name + " Created!"
|
76
|
+
return response
|
77
|
+
end
|
78
|
+
|
79
|
+
# Create squads test plans and its test runs for regression
|
80
|
+
# @param client testrail
|
81
|
+
# @param project id
|
82
|
+
# @param version name
|
83
|
+
def create_squad_test_plan(client, project_id, milestone_id, version_name)
|
84
|
+
suites = Testsuite.suites(client, project_id)
|
85
|
+
test_plans = []
|
86
|
+
suites.each do |squad|
|
87
|
+
sections = Sections.get_sections(client, project_id, squad['id'])
|
88
|
+
test_runs = generate_test_run_titles(sections['sections'])
|
89
|
+
puts "\nCreating test runs for #{squad['name']}..."
|
90
|
+
test_runs.each_with_index do |data, index|
|
91
|
+
puts "#{index + 1}. ID: #{data[:id]}, Title: #{data[:title]}"
|
92
|
+
end
|
93
|
+
runs = test_runs.map do |test_run|
|
94
|
+
cases = Testcase.get_cases(client, project_id, squad['id'], test_run[:id])
|
95
|
+
next if cases.eql? []
|
96
|
+
{
|
97
|
+
name: "#{squad['name']} #{test_run[:title]} #{version_name}",
|
98
|
+
suite_id: squad['id'],
|
99
|
+
include_all: false,
|
100
|
+
case_ids: cases.map { |c| c['id'] }
|
101
|
+
}
|
102
|
+
end.compact
|
103
|
+
|
104
|
+
payload = {
|
105
|
+
name: "#{squad['name']} Regression #{@app_name} #{version_name}",
|
106
|
+
milestone_id: milestone_id,
|
107
|
+
entries: runs
|
108
|
+
}
|
109
|
+
test_plans << Testplan.create_testplan(client, project_id, payload) unless payload[:entries].eql? []
|
110
|
+
end
|
111
|
+
return test_plans
|
112
|
+
end
|
113
|
+
|
114
|
+
# Generate test runs titles based on suite sections
|
115
|
+
# @param array of sections
|
116
|
+
def generate_test_run_titles(test_sections)
|
117
|
+
test_runs = []
|
118
|
+
test_sections.each do |section|
|
119
|
+
if !test_sections.any? { |s| s['parent_id'] == section['id'] }
|
120
|
+
parent_ids = []
|
121
|
+
parent_id = section['parent_id']
|
122
|
+
while parent_id
|
123
|
+
parent_ids << parent_id
|
124
|
+
parent_id = test_sections.find { |s| s['id'] == parent_id }['parent_id']
|
125
|
+
end
|
126
|
+
test_run = parent_ids.reverse.map { |id| test_sections.find { |s| s['id'] == id }['name'] }.join(' ')
|
127
|
+
test_run = "#{test_run} #{section['name']}"
|
128
|
+
test_runs << { id: section['id'], title: test_run } if test_run.downcase.include? @app_name
|
129
|
+
end
|
130
|
+
end
|
131
|
+
test_runs
|
132
|
+
end
|
133
|
+
|
134
|
+
# Generate json result of test runs creation
|
135
|
+
# @param array of test plans
|
136
|
+
def generate_json_output(app_name, version_name, test_plans)
|
137
|
+
squads_test_plans = test_plans.map do |test_plan|
|
138
|
+
{
|
139
|
+
squad: test_plan['name'].split(" ").first,
|
140
|
+
test_runs: test_plan['entries'].map do |entry|
|
141
|
+
{
|
142
|
+
id: (entry['runs'][0])['id'],
|
143
|
+
name: (entry['runs'][0])['name'],
|
144
|
+
url: (entry['runs'][0])['url'],
|
145
|
+
}
|
146
|
+
end
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
regression_output = {
|
151
|
+
app: app_name,
|
152
|
+
version: version_name,
|
153
|
+
test_plans: squads_test_plans,
|
154
|
+
}
|
155
|
+
|
156
|
+
json_data = JSON.pretty_generate(regression_output)
|
157
|
+
folder_path = 'output'
|
158
|
+
file_name = 'output_regression.json'
|
159
|
+
file_path = File.join(folder_path, file_name)
|
160
|
+
|
161
|
+
FileUtils.mkdir_p(folder_path) # Create the folder if it doesn't exist
|
162
|
+
File.write(file_path, json_data)
|
163
|
+
|
164
|
+
puts "\nOutput JSON file created at #{file_path}"
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
# Returns latest automation test runs for regression
|
169
|
+
# @param app name
|
170
|
+
# @param squad name
|
171
|
+
# @param environment name
|
172
|
+
def get_latest_automation_run(app_name, squad_name, environment_name, custom_section)
|
173
|
+
client = Dataprep.client_tr
|
174
|
+
|
175
|
+
# get app project id
|
176
|
+
project_id = get_app_project_id(app_name)
|
177
|
+
app = app_name.split('_')[1]
|
178
|
+
puts app
|
179
|
+
|
180
|
+
# get test plan from 2 months earlier
|
181
|
+
two_months_before = Dataprep.get_timestamp_prev_month(2)
|
182
|
+
filter = "created_after=#{two_months_before}"
|
183
|
+
plans = Testplan.get_plans(client, project_id, filter)
|
184
|
+
|
185
|
+
# get test plan from latest version and squad name
|
186
|
+
app_version = get_latest_version(app_name)
|
187
|
+
puts 'App version: ' + app_version
|
188
|
+
test_plan_name="#{app} #{app_version}"
|
189
|
+
plans_version = plans.select { |plan| plan['name'].include? test_plan_name }
|
190
|
+
squad_plan = plans_version.find { |plan| plan['name'].downcase.include? squad_name }
|
191
|
+
if !squad_plan.nil?
|
192
|
+
puts 'Found squad plan id: ' + squad_plan['id'].to_s
|
193
|
+
puts squad_plan['name']
|
194
|
+
else
|
195
|
+
raise 'Squad plan not found!'
|
196
|
+
end
|
197
|
+
|
198
|
+
plan = Testplan.get_plan(client, squad_plan['id'])
|
199
|
+
# get automation test run
|
200
|
+
custom_section = custom_section.gsub('/', ' ')
|
201
|
+
automation_run = plan['entries'].find { |run| run['name'].downcase.include? "automation #{environment_name.downcase} #{custom_section.downcase}"}
|
202
|
+
if !automation_run.nil?
|
203
|
+
puts 'Found squad automation run id: ' + automation_run['id'].to_s
|
204
|
+
puts automation_run['name']
|
205
|
+
else
|
206
|
+
raise "No Automation Runs Found for: automation #{environment_name} #{custom_section}"
|
207
|
+
end
|
208
|
+
|
209
|
+
return automation_run['runs'].first['id']
|
210
|
+
end
|
211
|
+
|
212
|
+
# get latest version from env
|
213
|
+
def get_latest_version(app_name)
|
214
|
+
case app_name
|
215
|
+
when 'android_marketplace'
|
216
|
+
ENV['ANDROID_MARKETPLACE_REGRESSION_VERSION']
|
217
|
+
when 'android_mitra'
|
218
|
+
ENV['ANDROID_MITRA_REGRESSION_VERSION']
|
219
|
+
when 'android_mitra-b2b'
|
220
|
+
ENV['ANDROID_MITRAB2B_REGRESSION_VERSION']
|
221
|
+
when 'android_bmoney'
|
222
|
+
ENV['ANDROID_BMONEY_REGRESSION_VERSION']
|
223
|
+
when 'ios_marketplace'
|
224
|
+
ENV['IOS_MARKETPLACE_REGRESSION_VERSION']
|
225
|
+
when 'ios_bmoney'
|
226
|
+
ENV['IOS_BMONEY_REGRESSION_VERSION']
|
227
|
+
else
|
228
|
+
raise 'No app found'
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
|
5
|
+
module Tms
|
6
|
+
module Attachment
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# This method will put file to test result
|
10
|
+
# @param client testrail
|
11
|
+
# @param result_id is test result id get from test run
|
12
|
+
# @param file image or video
|
13
|
+
def attach_file(client, result_id, file)
|
14
|
+
client.send_post("add_attachment_to_result/#{result_id}", file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './testrail'
|
4
|
+
|
5
|
+
module Tms
|
6
|
+
module Cleanup
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# This method will clean invalid reference on testcase
|
10
|
+
# @param client testrail
|
11
|
+
# @param project id
|
12
|
+
def cleanup_tc(client, project_id)
|
13
|
+
suite_id = suite_id(client, project_id)
|
14
|
+
cases = set_cases(client, project_id, suite_id)
|
15
|
+
validate_reff(client, cases)
|
16
|
+
end
|
17
|
+
|
18
|
+
# This method will get suite id
|
19
|
+
# @param client testrail
|
20
|
+
# @param project id
|
21
|
+
def suite_id(client, project_id)
|
22
|
+
response = client.send_get("get_suites/#{project_id}")
|
23
|
+
response.empty? ? nil : response[0]['id']
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method will get all test case based on project id and suite id
|
27
|
+
# @param client testrail
|
28
|
+
# @param project id
|
29
|
+
# @param suite id
|
30
|
+
def set_cases(client, project_id, suite_id)
|
31
|
+
client.send_get("get_cases/#{project_id}&suite_id=#{suite_id}")
|
32
|
+
end
|
33
|
+
|
34
|
+
# This method will set reference into '' on test case
|
35
|
+
# @param client testrail
|
36
|
+
# @param test case id
|
37
|
+
def update_case_clean_refs(client, tc_id)
|
38
|
+
payload = { refs: '' }
|
39
|
+
client.send_post("update_case/#{tc_id}", payload)
|
40
|
+
end
|
41
|
+
|
42
|
+
# This method will validate the reference is valid format story id and then update when is invalid
|
43
|
+
# @param client testrail
|
44
|
+
# @param cases
|
45
|
+
def validate_reff(client, cases)
|
46
|
+
cases.each do |tcase|
|
47
|
+
next if tcase['refs'].to_s.eql?('')
|
48
|
+
|
49
|
+
tcase['refs'].split(',').each do |ref|
|
50
|
+
update_case_clean_refs(client, tcase['id']) unless valid_refs(ref)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# This method will validate the reference is valid format story id
|
56
|
+
# @param client testrail
|
57
|
+
# @return
|
58
|
+
def valid_refs(refs)
|
59
|
+
refs.include?('-') &&
|
60
|
+
refs.split('-').size.eql?(2) &&
|
61
|
+
(refs.split('-')[1] =~ /[^0-9]/).nil?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|