kankankan 0.0.2

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/kankankan.rb +299 -0
  3. metadata +43 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d1c932b1a6f900e710bddda3e662a1fabe9007b8
4
+ data.tar.gz: 8d2276de6bd71a180ebc556a81a89c8c23ccca7c
5
+ SHA512:
6
+ metadata.gz: e8db96269c05349ab9593217db4e7837840a57563031db6b35c7205d1979af71e50ff8f427d218b9226a29fa1cfa745c8ab57e6587b626aa2a370d2b70cfffb1
7
+ data.tar.gz: 6fddc0dfe5f75f549c4557d5b9719e4d4494d56d6e253656e043349eb447460ed1ad3354d3f3664b55b6ef503756fd0d274d9d9ffb0be427cc9a03eae216d21d
@@ -0,0 +1,299 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'json'
5
+
6
+ module Kankankan
7
+
8
+ # GET/POST client
9
+ class APIClient
10
+ @url = ''
11
+ @user = ''
12
+ @password = ''
13
+
14
+ attr_accessor :user
15
+ attr_accessor :password
16
+
17
+ def initialize(base_url)
18
+ base_url += '/' unless base_url.match(/\/$/)
19
+ @url = base_url + 'index.php?/api/v2/'
20
+ end
21
+
22
+ #
23
+ # Send Get
24
+ #
25
+ # Issues a GET request (read) against the API and returns the result
26
+ # (as Ruby hash).
27
+ #
28
+ # Arguments:
29
+ #
30
+ # uri The API method to call including parameters
31
+ # (e.g. get_case/1)
32
+ #
33
+ def send_get(uri)
34
+ _send_request('GET', uri, nil)
35
+ end
36
+
37
+ #
38
+ # Send POST
39
+ #
40
+ # Issues a POST request (write) against the API and returns the result
41
+ # (as Ruby hash).
42
+ #
43
+ # Arguments:
44
+ #
45
+ # uri The API method to call including parameters
46
+ # (e.g. add_case/1)
47
+ # data The data to submit as part of the request (as
48
+ # Ruby hash, strings must be UTF-8 encoded)
49
+ #
50
+ def send_post(uri, data)
51
+ _send_request('POST', uri, data)
52
+ end
53
+
54
+ private
55
+
56
+ def _send_request(method, uri, data)
57
+ url = URI.parse(@url + uri)
58
+ if method == 'POST'
59
+ request = Net::HTTP::Post.new(url.path + '?' + url.query)
60
+ request.body = JSON.dump(data)
61
+ else
62
+ request = Net::HTTP::Get.new(url.path + '?' + url.query)
63
+ end
64
+ request.basic_auth(@user, @password)
65
+ request.add_field('Content-Type', 'application/json')
66
+
67
+ conn = Net::HTTP.new(url.host, url.port)
68
+ if url.scheme == 'https'
69
+ conn.use_ssl = true
70
+ conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
71
+ end
72
+ response = conn.request(request)
73
+
74
+ if response.body && !response.body.empty?
75
+ result = JSON.parse(response.body)
76
+ else
77
+ result = {}
78
+ end
79
+
80
+ if response.code != '200'
81
+ if result && result.key?('error')
82
+ error = '"' + result['error'] + '"'
83
+ else
84
+ error = 'No additional error message received'
85
+ end
86
+ fail APIError.new('TestRail API returned HTTP %s (%s)' %
87
+ [response.code, error])
88
+ end
89
+
90
+ result
91
+ end
92
+ end
93
+
94
+ class APIError < StandardError
95
+ end
96
+
97
+ class Project
98
+ attr_accessor :test_plan_id
99
+ attr_accessor :test_suite_id
100
+
101
+ def initialize(project_id, user, password, base_url = nil)
102
+ @project_id = project_id
103
+ @client = APIClient.new(base_url.nil? ? 'https://testrail.com':base_url)
104
+ @client.user = user
105
+ @client.password = password
106
+ @project_info = @client.send_get("get_project/#{@project_id}")
107
+
108
+ @test_plan_id = ENV['TEST_PLAN_ID'] if ENV.key?('TEST_PLAN_ID')
109
+ @test_run_name = 'Debug Run'
110
+ use_test_run_name(ENV['RUN_NAME']) if ENV.key?('RUN_NAME')
111
+ use_test_run_id(ENV['RUN_ID']) if ENV.key?('RUN_ID')
112
+ end
113
+
114
+ def testsuites
115
+ @test_suites = @client.send_get("get_suites/#{@project_id}") unless @test_suites
116
+ end
117
+
118
+ def use_test_run_id(test_run_id)
119
+ @test_run_name = ''
120
+ @test_run_id = test_run_id
121
+ end
122
+
123
+ def use_test_run_name(test_run_name)
124
+ @test_run_name = test_run_name
125
+ @test_run_id = ''
126
+ end
127
+
128
+ def dump
129
+ puts @project_info
130
+ end
131
+
132
+ def _get_test_run_entry_id(test_plan_id)
133
+ runs = []
134
+ test_run_entry_id = nil
135
+
136
+ if @project_info['suite_mode'].to_i == 1
137
+ runs = @client.send_get("get_runs/#{@project_id}")
138
+ else
139
+ if @test_plan_id
140
+ @test_plan = @client.send_get("get_plan/#{test_plan_id}")
141
+
142
+ @test_plan['entries'].each do |entry|
143
+ runs += entry['runs']
144
+ end
145
+ end
146
+ end
147
+ runs.each do |run|
148
+ if @test_run_name && @test_run_name != ''
149
+ next unless run['name'].eql?(@test_run_name)
150
+ test_run_entry_id = run['entry_id']
151
+ break
152
+ else
153
+ next unless run['id'].to_s.eql?(@test_run_id)
154
+ test_run_entry_id = run['entry_id']
155
+ break
156
+ end
157
+ end
158
+
159
+ test_run_entry_id
160
+ end
161
+
162
+ def _get_test_run_id(test_plan_id)
163
+ runs = []
164
+ test_run_id = nil
165
+
166
+ if @project_info['suite_mode'].to_i == 1
167
+ runs = @client.send_get("get_runs/#{@project_id}")
168
+ else
169
+ if @test_plan_id
170
+ @test_plan = @client.send_get("get_plan/#{test_plan_id}")
171
+
172
+ @test_plan['entries'].each do |entry|
173
+ runs += entry['runs']
174
+ end
175
+ end
176
+ end
177
+
178
+ runs.each do |run|
179
+ if @test_run_name && @test_run_name != ''
180
+ next unless run['name'].eql?(@test_run_name)
181
+ test_run_id = run['id']
182
+ break
183
+ else
184
+ next unless run['id'].to_s.eql?(@test_run_id)
185
+ test_run_id = run['id']
186
+ break
187
+ end
188
+ end
189
+
190
+ test_run_id
191
+ end
192
+
193
+ def _get_test_run_id_from_name(_test_run_name)
194
+ runs = []
195
+ test_run_id = nil
196
+
197
+ if @project_info['suite_mode'].to_i == 1
198
+ runs = @client.send_get("get_runs/#{@project_id}")
199
+ else
200
+ if @test_plan_id
201
+ @test_plan = @client.send_get("get_plan/#{test_plan_id}")
202
+
203
+ @test_plan['entries'].each do |entry|
204
+ runs += entry['runs']
205
+ end
206
+ end
207
+ end
208
+
209
+ runs.each do |run|
210
+ next unless run['name'].eql?(@test_run_name)
211
+ test_run_id = run['id']
212
+ break
213
+ end
214
+
215
+ test_run_id
216
+ end
217
+
218
+ def _test_run_id_exists?(test_run_id, test_plan_id = nil)
219
+ if test_run_id.nil? || test_run_id.empty?
220
+ if test_plan_id.nil?
221
+ return true if _get_test_run_id_from_name(@test_run_name)
222
+ end
223
+
224
+ return false
225
+ end
226
+
227
+ if @project_info['suite_mode'].to_i == 1 || test_plan_id.nil?
228
+ run = @client.send_get("get_run/#{test_run_id}")
229
+ return !run.nil?
230
+ else
231
+ return !_get_test_run_entry_id(test_plan_id).nil?
232
+ end
233
+ end
234
+
235
+ def _prepare_test_run(test_run_id, case_id)
236
+ existing_test_run_id = _test_run_id_exists?(test_run_id)
237
+
238
+ if existing_test_run_id
239
+ test_run_id = _get_test_run_id(@test_plan_id)
240
+ end
241
+
242
+ if @project_info['suite_mode'].to_i == 1
243
+ new_run = @client.send_post("add_run/#{@project_id}", name: @test_run_name, include_all: false) unless existing_test_run_id
244
+ else
245
+ if @test_plan_id
246
+ run_entry_id = _get_test_run_entry_id(@test_plan_id)
247
+
248
+ unless run_entry_id
249
+ newPlanEntry = @client.send_post("add_plan_entry/#{@test_plan_id}",
250
+ suite_id: @test_suite_id,
251
+ include_all: false,
252
+ name: @test_run_name,
253
+ case_ids:case_id.to_s.split(',').map(&:to_i)
254
+ )
255
+ new_run = newPlanEntry['runs'][0]
256
+ run_entry_id = newPlanEntry['id']
257
+ end
258
+
259
+ else
260
+ new_run = @client.send_post("add_run/#{@project_id}", name: @test_run_name, include_all: false) unless existing_test_run_id
261
+ end
262
+ end
263
+ new_run = @client.send_get("get_run/#{test_run_id}") unless new_run
264
+
265
+ # extract all tests in the run
266
+ allTestsForRun = @client.send_get("get_tests/#{new_run['id']}")
267
+ included_tests = []
268
+ included_tests << case_id.to_i # append our new case
269
+ allTestsForRun.each do |testInRun|
270
+ included_tests << testInRun['case_id'].to_i
271
+ end
272
+
273
+ if @test_plan_id
274
+ @client.send_post("update_plan_entry/#{@test_plan_id}/#{run_entry_id}",
275
+ include_all: false, case_ids: included_tests
276
+ )
277
+ else
278
+ @client.send_post("update_run/#{new_run['id']}", case_ids: included_tests)
279
+ end
280
+
281
+ new_run
282
+ end
283
+
284
+ def add_result(case_id, ok, comment)
285
+ if case_id.to_i
286
+ test_run = _prepare_test_run(@test_run_id, case_id)
287
+ # puts test_run
288
+ # puts "case id #{case_id}"
289
+ # send the result to TestRail
290
+ @client.send_post("add_result_for_case/#{test_run['id']}/#{case_id}",
291
+ status_id: ok ? 1 : 5,
292
+ comment: comment
293
+ )
294
+ else
295
+ puts 'Skipping testrail update due to empty case_id'
296
+ end
297
+ end
298
+ end
299
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kankankan
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Akhmad Fathonih
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Wrapper for simple testrail result synchronization
14
+ email: akhmad.fathonih@rakuten.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/kankankan.rb
20
+ homepage:
21
+ licenses: []
22
+ metadata: {}
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ required_rubygems_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ requirements: []
38
+ rubyforge_project:
39
+ rubygems_version: 2.0.14.1
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: Testrail result push!
43
+ test_files: []