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.
@@ -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