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.
- checksums.yaml +7 -0
- data/lib/kankankan.rb +299 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -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
|
data/lib/kankankan.rb
ADDED
@@ -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: []
|