itriagetestrail 0.7.7 → 0.7.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14b7fb818edd695a537a8acccf3ce811b2b80fe6
4
- data.tar.gz: 40ead653fcf3fe91fec75e955c35962a308016c5
3
+ metadata.gz: 557a1b8a6a4e1a197b314a665013ac48579524e7
4
+ data.tar.gz: d0a26fb1d45e51dccc35f9d076181d9de8750275
5
5
  SHA512:
6
- metadata.gz: d2f26dc39ac84a78b61db9c4c9ebb83859db44c1dfd8187c193cc70839aa336b58a8ab0b39d59b44c9ef7c1cd91565c9cb8de4a3777231845fdc5454968f25c8
7
- data.tar.gz: 39eef8fecf7959a3e3d304cc3ce7f5ec3e47407d68c7ff25a7e2986a911c5e6679bb67a7666de20a506d9dc8ae9a1f6c19d2181761509dd80baa2565fb71ced7
6
+ metadata.gz: 1fd123e1d574e8c65c09e324fdeee5f594498566813b0a30e0e1a7693724bfff395c6a32b09f85cd8de6bbf8b62a5debedb4ee943cdb68258d28adedf4da7d01
7
+ data.tar.gz: 4caeb1ac5214e4d1e790ccfc67d8d766607f5629c04bc699499afd9d5ef3fe9a88c629361053ada3a5d60e7b08fb198a3edd077194f7119938300b6ce573fb6f
@@ -0,0 +1,404 @@
1
+
2
+ module Projects
3
+ # populate projects instance variable with all projects objects in the testrail site
4
+ def projects
5
+ @projects ||= @client.send_get("get_projects")
6
+ end
7
+
8
+ def project_by_name(name)
9
+ res = -1
10
+ projects.each do |project|
11
+ res = project if project['name'] == name
12
+ end
13
+ res
14
+ end
15
+
16
+ # return the project object for a given project id
17
+ def project_by_id(id)
18
+ res = -1
19
+ projects.each do |project|
20
+ res = project if project['id'] == id.to_i
21
+ end
22
+ res
23
+ end
24
+
25
+ # set the project_id by a requested project from config/environment variable
26
+ def set_project
27
+ requested_id = @testrail_config[:projectId]
28
+ case requested_id
29
+ when nil, ''
30
+ # a project id was not provided, fetch it from TestRail by project name
31
+ res = project_by_name(@testrail_config[:projectName])
32
+ if res == -1
33
+ @execute = false
34
+ return
35
+ end
36
+ @project_id = res['id']
37
+ @suite_mode = res['suite_mode']
38
+ else
39
+ # use the requested project id
40
+ @project_id = requested_id
41
+ @suite_mode = project_by_id(@project_id)['suite_mode']
42
+ end
43
+ end
44
+ end
45
+
46
+ module Suites
47
+ # TestRail Suites
48
+ def testrail_suites
49
+ case @suite_mode
50
+ when 2,3
51
+ @suites = @client.send_get("get_suites/#{@project_id}")
52
+ end
53
+ end
54
+
55
+ def testrail_suite_id(suite_name)
56
+ res = -1
57
+ @suites.each do |suite|
58
+ res = suite['id'] if suite['name'] == suite_name
59
+ end
60
+ res
61
+ end
62
+
63
+ def add_testrail_suite(suite_name)
64
+ body = { name: suite_name }
65
+ res = @client.send_post("add_suite/#{@project_id}", body)
66
+ testrail_suite = res['id']
67
+
68
+ #re-establish suites
69
+ testrail_suites
70
+
71
+ testrail_suite
72
+ end
73
+ end
74
+
75
+ module Milestones
76
+
77
+ # Establish the milestone name based on origin passed in,
78
+ # usually origin represents a branch or environment
79
+ def normalize_milestone
80
+ case @testrail_config[:origin]
81
+ when 'prd', 'production', 'origin/production'
82
+ 'Production'
83
+ when 'stg', 'staging', 'origin/staging'
84
+ 'Staging'
85
+ when 'dev', 'development', 'origin/development'
86
+ 'Development'
87
+ when 'local', ''
88
+ 'Local'
89
+ when 'master', 'origin/master'
90
+ if @testrail_config[:masterMilestone].nil? || @testrail_config[:masterMilestone].empty?
91
+ 'Master'
92
+ else
93
+ @testrail_config[:masterMilestone]
94
+ end
95
+ else
96
+ 'Dev Branch'
97
+ end
98
+ end
99
+
100
+ # returns timestamp for begining of first day of current quarter
101
+ def milestone_period_start
102
+ time_zone = TZInfo::Timezone.get('America/Denver')
103
+ current_year = time_zone.now.year
104
+ month = time_zone.now.mon
105
+
106
+ # determine which quarter we are in
107
+ if month <= 3
108
+ time_zone.utc_to_local(Time.utc(current_year, 1, 1))
109
+ elsif month <= 6
110
+ time_zone.utc_to_local(Time.utc(current_year, 4, 1))
111
+ elsif month <= 9
112
+ time_zone.utc_to_local(Time.utc(current_year, 7, 1))
113
+ else
114
+ time_zone.utc_to_local(Time.utc(current_year, 10, 1))
115
+ end
116
+ end
117
+
118
+ # determine the due date (end of quarter) for a new milestone being added
119
+ def milestone_due_date
120
+ time_zone = TZInfo::Timezone.get('America/Denver')
121
+ current_year = time_zone.now.year
122
+ month = time_zone.now.mon
123
+
124
+ # determine which quarter we are in
125
+ if month <= 3
126
+ Time.utc(current_year, 3, 31).strftime('%s')
127
+ elsif month <= 6
128
+ Time.utc(current_year, 6, 30).strftime('%s')
129
+ elsif month <= 9
130
+ Time.utc(current_year, 9, 30).strftime('%s')
131
+ else
132
+ Time.new(current_year, 12, 31).strftime('%s')
133
+ end
134
+ end
135
+
136
+ # returns the id for a requested milestone by name, or creates one if the milestone does not exist
137
+ def fetch_milestone(requested_milestone_name)
138
+ milestones = @client.send_get("get_milestones/#{@project_id}")
139
+ res = -1
140
+ milestones.each do |milestone|
141
+ res = milestone['id'] if milestone['name'] == requested_milestone_name
142
+ end
143
+
144
+ if res == -1
145
+ # We need to add the milestone to TestRail
146
+
147
+ body = {
148
+ name: requested_milestone_name,
149
+ due_on: milestone_due_date
150
+ }
151
+
152
+ res = @client.send_post("add_milestone/#{@project_id}", body)['id']
153
+ end
154
+ res
155
+ end
156
+
157
+ # return a standardized name for a milestone to be archived
158
+ def milestone_archive_name(milestone_name, date)
159
+ year = date.year
160
+ month = date.mon
161
+
162
+ if month <= 3
163
+ "#{milestone_name} #{year}-Q1"
164
+ elsif month <= 6
165
+ "#{milestone_name} #{year}-Q2"
166
+ elsif month <= 9
167
+ "#{milestone_name} #{year}-Q3"
168
+ else
169
+ "#{milestone_name} #{year}-Q4"
170
+ end
171
+ end
172
+
173
+ # return all the runs associated with an existing milestone
174
+ def milestone_runs(milestone_name)
175
+ # use the matching milestone id for project
176
+ milestone_id = fetch_milestone(milestone_name)
177
+
178
+ # fetch all test runs associated with the milestone id for project
179
+ @client.send_get("get_runs/#{@project_id}&milestone_id=#{milestone_id}&is_completed=1") || []
180
+ end
181
+
182
+ # testrail call to rename a milestone (for archiving)
183
+ def rename_milestone(id, new_name)
184
+ # todo: rename milestone with previous_milestone
185
+ body = { name: new_name }
186
+ res = @client.send_post("update_milestone/#{id}", body)['id']
187
+ end
188
+
189
+ # this archives a milestone at the turn of a quarter and creates a new one in its place
190
+ def reset_milestone(milestone_name)
191
+ runs = milestone_runs(milestone_name)
192
+ if runs.size > 0
193
+ last_run_time = Time.at(runs.last['completed_on'])
194
+ if last_run_time < milestone_period_start
195
+ rename_milestone(@milestone_id, milestone_archive_name(milestone_name, last_run_time))
196
+ @milestone_id = fetch_milestone(@milestone_name)
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ module Sections
203
+ # TestRail Sections
204
+ def testrail_sections
205
+ case @suite_mode
206
+ when 2,3
207
+ @suite_id = testrail_suite_id(@suite_name)
208
+ @sections = @client.send_get("get_sections/#{@project_id}&suite_id=#{@suite_id}")
209
+ else
210
+ @sections = @client.send_get("get_sections/#{@project_id}")
211
+ end
212
+ end
213
+
214
+ def testrail_section_id(section_title)
215
+ res = -1
216
+ @sections.each do |section|
217
+ res = section['id'] if section['name'] == section_title
218
+ end
219
+ res
220
+ end
221
+
222
+ def add_testrail_section(section_title)
223
+ if @suite_name
224
+ body = {
225
+ name: section_title,
226
+ suite_id: testrail_suite_id(@suite_name)
227
+ }
228
+ else
229
+ body = {
230
+ name: section_title
231
+ }
232
+ end
233
+
234
+ res = @client.send_post("add_section/#{@project_id}", body)
235
+
236
+ testrail_section = res['id']
237
+
238
+ # re-establish sections
239
+ testrail_sections
240
+
241
+ testrail_section
242
+ end
243
+ end
244
+
245
+ module TestCases
246
+ # TestRail Cases
247
+ def testrail_ids
248
+ case @suite_mode
249
+ when 2,3
250
+ @test_cases = @client.send_get("get_cases/#{@project_id}&suite_id=#{@suite_id}&type_id=3")
251
+ else
252
+ @test_cases = @client.send_get("get_cases/#{@project_id}&type_id=3")
253
+ end
254
+
255
+ @test_case_ids = []
256
+
257
+ @test_cases.each { |test_case| @test_case_ids << test_case['id'] }
258
+ end
259
+
260
+ def testrail_test_case_id(external_id)
261
+ res = -1
262
+ @test_cases.each do |test_case|
263
+ if test_case['custom_external_case_id'] == external_id
264
+ res = test_case['id']
265
+ end
266
+ end
267
+ res
268
+ end
269
+
270
+ def associate_result(external_id)
271
+ test_case_id = testrail_test_case_id(external_id)
272
+ # store the test case id with the local result
273
+ @results[:results].each do |result|
274
+ next unless result[:external_id] == external_id
275
+ @external_results[:results] << { case_id: test_case_id,
276
+ status_id: result['status_id'],
277
+ comment: result['comment'] }
278
+ end
279
+ end
280
+
281
+ # add the test case if it doesn't exist
282
+ def add_testrail_test_case(scenario_title, external_id, scenario_steps, section_id)
283
+ body = {
284
+ title: scenario_title,
285
+ custom_external_case_id: external_id,
286
+ custom_steps: scenario_steps,
287
+ type_id: 3
288
+ }
289
+
290
+ @client.send_post("add_case/#{section_id}", body)
291
+
292
+ # refresh test case ids
293
+ testrail_ids
294
+ end
295
+
296
+ def test_name
297
+ label = ''
298
+ label += "App Version:#{@app_version}" unless @app_version.nil? || @app_version == ''
299
+ label += " Jenkins Build:#{@jenkins_build}" unless @jenkins_build .nil? || @jenkins_build == ''
300
+ label.strip!
301
+ label = 'Regression' if label == ''
302
+ label + ' (' + @time_zone.now.strftime('%-I:%M %p') + ')'
303
+ end
304
+ end
305
+
306
+ module TestRuns
307
+ def extend_testrail_run
308
+ # Reset test scope to include all cases
309
+ body = { include_all: true }
310
+ @client.send_post("update_run/#{@run_id}", body)
311
+ end
312
+
313
+ def existing_cases_from_description
314
+ # Grabs from testrail run description
315
+ run = @client.send_get("get_run/#{@run_id}")
316
+ @description = run["description"]
317
+ @description.nil? ? [] : @description.split(",")
318
+ end
319
+
320
+ def existing_cases_from_run
321
+
322
+ tests = @client.send_get("get_tests/#{@run_id}&status_id=1,2,4,5") || []
323
+
324
+ cases = []
325
+
326
+ tests.each do |test|
327
+
328
+ cases << test["case_id"]
329
+
330
+ end
331
+ cases
332
+ end
333
+
334
+ # open a test run to submit test results
335
+ def add_testrail_run
336
+ body = {
337
+ name: test_name,
338
+ description: '',
339
+ include_all: true,
340
+ milestone_id: @milestone_id
341
+ }
342
+
343
+ unless @testrail_config[:include_all] || true
344
+ body[:include_all] = false
345
+ body[:case_ids] = @test_case_ids
346
+ end
347
+
348
+ case @suite_mode
349
+ when 2,3
350
+ body[:suite_id] = @suite_id
351
+ end
352
+ res = @client.send_post("add_run/#{@project_id}", body)
353
+ @run_id = res['id']
354
+ end
355
+ end
356
+
357
+ module TestResults
358
+ def send_results_to_testrail
359
+ return unless @results[:results].size != 0
360
+ # copy what is in the results
361
+ @submitted[:results] << @results[:results]
362
+
363
+ begin
364
+ send = { results: @results[:results] }
365
+ res = @client.send_post("add_results_for_cases/#{@run_id}", send)
366
+ clear_results
367
+ rescue StandardError => e
368
+ raise e
369
+ end
370
+ end
371
+
372
+ def update_test_suite(scenario_title, external_id, scenario_steps)
373
+ feature = external_id.split(';')[0].split('#')[0]
374
+
375
+ # if the testrail case does not exist, update cases
376
+ if testrail_test_case_id(external_id) == -1
377
+
378
+ section_id = testrail_section_id(feature)
379
+
380
+ # if the testrail section does not exist, update sections
381
+ section_id = add_testrail_section(feature) if section_id == -1
382
+
383
+ add_testrail_test_case(scenario_title, external_id, scenario_steps, section_id)
384
+ sleep 1
385
+ end
386
+ # store the case id associated with the external_id
387
+ associate_result(external_id)
388
+ end
389
+
390
+ def store_result(scenario_title, external_id, scenario_steps, status_id, comment)
391
+ update_test_suite scenario_title, external_id, scenario_steps
392
+
393
+ case_id = testrail_test_case_id(external_id)
394
+ @results[:results] << {
395
+ case_id: case_id,
396
+ scenario_title: scenario_title,
397
+ external_id: external_id,
398
+ scenario_steps: scenario_steps,
399
+ status_id: status_id,
400
+ comment: comment,
401
+ custom_branch_name: @testrail_config[:origin]
402
+ }
403
+ end
404
+ end
@@ -1,3 +1,3 @@
1
1
  module Itriagetestrail
2
- VERSION = '0.7.7'
2
+ VERSION = '0.7.8'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itriagetestrail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.7.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - a801069
@@ -59,6 +59,7 @@ extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
61
  - lib/itriagetestrail.rb
62
+ - lib/itriagetestrail/modules.rb
62
63
  - lib/itriagetestrail/pool.rb
63
64
  - lib/itriagetestrail/testrail_binding.rb
64
65
  - lib/itriagetestrail/trcucumber13.rb