trail_marker 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +71 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/testrail_marker.rb +44 -0
- data/exe/testrail_marker +45 -0
- data/lib/trail_marker/api_testrail.rb +364 -0
- data/lib/trail_marker/api_testrail_rev2.bak +350 -0
- data/lib/trail_marker/argument.rb +229 -0
- data/lib/trail_marker/config_file.rb +107 -0
- data/lib/trail_marker/mark_tests.rb +169 -0
- data/lib/trail_marker/request.rb +122 -0
- data/lib/trail_marker/response.rb +121 -0
- data/lib/trail_marker/results_parser.rb +241 -0
- data/lib/trail_marker/test.bak +12 -0
- data/lib/trail_marker/testrail.rb +106 -0
- data/lib/trail_marker/version.rb +3 -0
- data/lib/trail_marker.rb +17 -0
- metadata +133 -0
@@ -0,0 +1,350 @@
|
|
1
|
+
require_relative "response"
|
2
|
+
|
3
|
+
# TODO: CLEAN UP or DRY testruns and testplans methods since can be combined.
|
4
|
+
# Implement other API calls
|
5
|
+
#
|
6
|
+
class ApiTestRail
|
7
|
+
attr_accessor :project_id
|
8
|
+
attr_accessor :suite_id
|
9
|
+
attr_accessor :run_id
|
10
|
+
attr_accessor :test_case_id
|
11
|
+
attr_accessor :section_id
|
12
|
+
|
13
|
+
|
14
|
+
def initialize(client)
|
15
|
+
@client = client
|
16
|
+
@projects = get_projects()
|
17
|
+
@project = nil
|
18
|
+
@suites = nil
|
19
|
+
@suite = nil
|
20
|
+
@plans = nil
|
21
|
+
@plan = nil
|
22
|
+
@runs = nil
|
23
|
+
@run = nil
|
24
|
+
@test_cases = nil
|
25
|
+
@test_case = nil
|
26
|
+
@milestones = nil
|
27
|
+
@milestone = nil
|
28
|
+
@statuses = get_statuses()
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the project ID of the project name passed.
|
33
|
+
#
|
34
|
+
def get_project_id(project_name)
|
35
|
+
if @projects.nil?
|
36
|
+
get_projects()
|
37
|
+
end
|
38
|
+
@project_id = search_array_kv(@projects, 'name', project_name, 'id')
|
39
|
+
if @project_id.nil?
|
40
|
+
puts "\nProject '#{project_name}' WAS NOT FOUND, select from available projects."
|
41
|
+
resp_projects = Response.new(@projects)
|
42
|
+
project_name = resp_projects.picker("name")
|
43
|
+
@project_id = search_array_kv(@projects, 'name', project_name, 'id')
|
44
|
+
end
|
45
|
+
return @project_id
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_milestone_id(milestone_name)
|
49
|
+
ms_id = nil
|
50
|
+
if ! milestone_exists?(milestone_name)
|
51
|
+
puts "\nMilestone '#{milestone_name}' WAS NOT FOUND, select from available milestones."
|
52
|
+
resp_ms = Response.new(@milestones)
|
53
|
+
milestone_name = resp_ms.picker("name")
|
54
|
+
#ms_id = search_array_kv(@milestones, 'name', milestone_name, 'id')
|
55
|
+
end
|
56
|
+
ms_id = search_array_kv(@milestones, 'name', milestone_name, 'id')
|
57
|
+
return ms_id
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_test_runplan_id(runplan_name)
|
61
|
+
if @runs.nil?
|
62
|
+
get_runs(@project_id)
|
63
|
+
end
|
64
|
+
run_id = search_array_kv(@runs, 'name', runplan_name, 'id')
|
65
|
+
if run_id.nil?
|
66
|
+
puts "\nTest Run WAS NOT FOUND, select from available."
|
67
|
+
resp_runs = Response.new(@runs)
|
68
|
+
runplan_name = resp_runs.picker("name")
|
69
|
+
run_id = search_array_kv(@runs, 'name', runplan_name, 'id')
|
70
|
+
end
|
71
|
+
return run_id
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_testplan_id(testplan_name)
|
75
|
+
if @plans.nil?
|
76
|
+
get_plans(@project_id)
|
77
|
+
end
|
78
|
+
plan_id = search_array_kv(@plans, 'name', testplan_name, 'id')
|
79
|
+
if plan_id.nil?
|
80
|
+
puts "\nTestPlan #{testplan_name} WAS NOT FOUND, select from available."
|
81
|
+
resp_plans = Response.new(@plans)
|
82
|
+
plan_name = resp_plans.picker("name")
|
83
|
+
plan_id = search_array_kv(@plans, 'name', plan_name, 'id')
|
84
|
+
end
|
85
|
+
return plan_id
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_suite_id(proj_id, suite_name)
|
89
|
+
suite_id = nil
|
90
|
+
if suite_exists?(proj_id, suite_name)
|
91
|
+
suite_id = search_array_kv(@suites, 'name', suite_name, 'id')
|
92
|
+
end
|
93
|
+
return suite_id
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_projects()
|
97
|
+
@projects = request_get('get_projects')
|
98
|
+
return @projects
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_milestones(proj_id)
|
102
|
+
ms_req = "get_milestones/" + proj_id.to_s
|
103
|
+
@milestones = request_get(ms_req)
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_runs(proj_id)
|
107
|
+
runs_req = "get_runs/" + proj_id.to_s
|
108
|
+
@runs = request_get(runs_req)
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_plans(proj_id)
|
112
|
+
plans_req = "get_plans/" + proj_id.to_s
|
113
|
+
@plans = request_get(plans_req)
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_plan(plan_id)
|
117
|
+
plan_req = "get_plan/" + plan_id.to_s
|
118
|
+
@plan = request_get(plan_req)
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_suites(proj_id)
|
122
|
+
suite_req = "get_suites/" + proj_id.to_s
|
123
|
+
@suites = request_get(suite_req)
|
124
|
+
end
|
125
|
+
|
126
|
+
######################## VERIFY
|
127
|
+
|
128
|
+
def milestone_exists?(milestone_name)
|
129
|
+
it_exists = false
|
130
|
+
if @milestones.nil?
|
131
|
+
get_milestones(@project_id)
|
132
|
+
end
|
133
|
+
puts "ALL MILES: #{@milestones}"
|
134
|
+
ms_id = search_array_kv(@milestones, 'name', milestone_name, 'id')
|
135
|
+
if ! ms_id.nil?
|
136
|
+
it_exists = true
|
137
|
+
end
|
138
|
+
return it_exists
|
139
|
+
end
|
140
|
+
|
141
|
+
def run_exists?(proj_id, run_name)
|
142
|
+
it_exists = false
|
143
|
+
if @runs.nil?
|
144
|
+
@runs = get_runs(proj_id)
|
145
|
+
end
|
146
|
+
run_id = search_array_kv(@runs, 'name', run_name, 'id')
|
147
|
+
if ! run_id.nil?
|
148
|
+
it_exists = true
|
149
|
+
end
|
150
|
+
return it_exists
|
151
|
+
end
|
152
|
+
|
153
|
+
def suite_exists?(proj_id, suite_name)
|
154
|
+
it_exists = false
|
155
|
+
if @suites.nil?
|
156
|
+
@suites = get_suites(proj_id)
|
157
|
+
end
|
158
|
+
suite_id = search_array_kv(@suites, 'name', suite_name, 'id')
|
159
|
+
if ! suite_id.nil?
|
160
|
+
it_exists = true
|
161
|
+
end
|
162
|
+
return it_exists
|
163
|
+
end
|
164
|
+
|
165
|
+
#############
|
166
|
+
|
167
|
+
# Makes an API call to get all possible results status. Currently has 5
|
168
|
+
# passed, blocked, untested, retest, failed.
|
169
|
+
# Puts the name and status in @statuses array.
|
170
|
+
#
|
171
|
+
def get_statuses()
|
172
|
+
@statuses = []
|
173
|
+
status_req = request_get('get_statuses')
|
174
|
+
status_req.each do |status|
|
175
|
+
status_hash ={}
|
176
|
+
status_hash['id'] = status['id']
|
177
|
+
status_hash['name'] = status['name']
|
178
|
+
@statuses.push(status_hash)
|
179
|
+
end
|
180
|
+
return @statuses
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
######################## TEST PLANS #########################
|
186
|
+
|
187
|
+
# Returns an array of testrun IDs that is inside a testplan.
|
188
|
+
#
|
189
|
+
def get_testplan_testruns(testplan_id)
|
190
|
+
run_ids = []
|
191
|
+
plan_resp = get_plan(testplan_id)
|
192
|
+
tp_entries = plan_resp['entries']
|
193
|
+
tp_entries.each do |entry|
|
194
|
+
entry_runs = entry['runs']
|
195
|
+
entry_runs.each do |erun|
|
196
|
+
run_ids.push(erun['id'])
|
197
|
+
end
|
198
|
+
end
|
199
|
+
return run_ids
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns array of id for testruns inside a testplan
|
203
|
+
def get_testplan_run_ids(testplan_name)
|
204
|
+
testplan_id = get_testplan_id(testplan_name)
|
205
|
+
get_testplan_testruns(testplan_id)
|
206
|
+
end
|
207
|
+
|
208
|
+
# NOTE - NOT USED RIGHT NOW.
|
209
|
+
# Marks a test case inside a testplan. Testplans adds extra API calls
|
210
|
+
# because testruns are inside the testplans and are not named.
|
211
|
+
# See note below MARK_TESTPLAN
|
212
|
+
def markoff_testplan(case_id, testplan_id, pass_status)
|
213
|
+
status_id = search_array_kv(@statuses, 'name', 'failed', 'id')
|
214
|
+
defect_txt = ""
|
215
|
+
if pass_status
|
216
|
+
status_id = search_array_kv(@statuses, 'name', 'passed', 'id')
|
217
|
+
defect_txt = ""
|
218
|
+
end
|
219
|
+
equiv_json = {:status_id => status_id, :comment => 'Auto marker.', :defects => defect_txt}
|
220
|
+
add_result_req = "add_result_for_case/" + run_id.to_s + "/" + case_id.to_s
|
221
|
+
request_post(add_result_req, equiv_json)
|
222
|
+
end
|
223
|
+
|
224
|
+
def get_testid(run_id, case_id)
|
225
|
+
puts "SEARCH FOR TESTID: #{run_id} :: #{case_id}"
|
226
|
+
tests_req = 'get_tests/' + run_id.to_s
|
227
|
+
tests_resp = request_get(tests_req)
|
228
|
+
puts "GET_TESTS: #{tests_resp}"
|
229
|
+
id_equiv = search_array_kv(tests_resp, 'case_id', case_id.to_i, 'id')
|
230
|
+
return id_equiv
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
# TODO: Parse XML for failed reason and add to comment(?)
|
236
|
+
#
|
237
|
+
def markoff_test(case_id, run_id, pass_status, comment_txt)
|
238
|
+
status_id = search_array_kv(@statuses, 'name', 'failed', 'id')
|
239
|
+
defect_txt = ""
|
240
|
+
if pass_status
|
241
|
+
status_id = search_array_kv(@statuses, 'name', 'passed', 'id')
|
242
|
+
defect_txt = ""
|
243
|
+
end
|
244
|
+
equiv_json = {:status_id => status_id, :comment => comment_txt, :defects => defect_txt}
|
245
|
+
add_result_req = "add_result_for_case/" + run_id.to_s + "/" + case_id.to_s
|
246
|
+
request_post(add_result_req, equiv_json)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Makes a post call to create a new milestone
|
250
|
+
def create_milestone(proj_name, msname)
|
251
|
+
proj_id = get_project_id(proj_name)
|
252
|
+
if ! milestone_exists?(msname)
|
253
|
+
puts "Create Milestones #{msname} in Project #{proj_name} "
|
254
|
+
unix_timestamp = Time.now.to_i
|
255
|
+
req_field = {:name => msname, :due_on => unix_timestamp}
|
256
|
+
create_milestone_req = "add_milestone/" + proj_id.to_s
|
257
|
+
request_post(create_milestone_req, req_field)
|
258
|
+
sleep(2)
|
259
|
+
get_milestones(proj_id)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def delete_milestone(proj_name, msname)
|
264
|
+
proj_id = get_project_id(proj_name)
|
265
|
+
ms_id = get_milestone_id(msname)
|
266
|
+
del_ms_req = "delete_milestone/" + ms_id.to_s
|
267
|
+
request_post(del_ms_req, nil)
|
268
|
+
exit
|
269
|
+
end
|
270
|
+
|
271
|
+
def create_testrun(proj_name, msname, trname, tsname)
|
272
|
+
proj_id = get_project_id(proj_name)
|
273
|
+
if ! run_exists?(proj_id, trname)
|
274
|
+
if suite_exists?(proj_id, tsname)
|
275
|
+
ms_id = nil
|
276
|
+
if ! msname.nil? && msname != ""
|
277
|
+
ms_id = get_milestone_id(msname)
|
278
|
+
end
|
279
|
+
puts "MSID: #{msname} #{ms_id}"
|
280
|
+
ts_id = get_suite_id(proj_id, tsname)
|
281
|
+
req_field = {:name => trname, :suite_id => ts_id, :description => "AutoCreated"}
|
282
|
+
if ! ms_id.nil? && ms_id != ""
|
283
|
+
req_field[:milestone_id] = ms_id
|
284
|
+
end
|
285
|
+
add_run_req = "add_run/" + proj_id.to_s
|
286
|
+
request_post(add_run_req, req_field)
|
287
|
+
puts "CREATING RUN under #{proj_name} #{req_field}"
|
288
|
+
sleep(2)
|
289
|
+
get_runs(proj_id)
|
290
|
+
else
|
291
|
+
puts "CANNOT Create New TestRun, (-s) test suite name needed."
|
292
|
+
end
|
293
|
+
else
|
294
|
+
puts "CANNOT Create RUN #{trname}, already exists."
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
def request_get(api_cmd)
|
301
|
+
req = Request.new(@client)
|
302
|
+
resp = req.exec_get(api_cmd)
|
303
|
+
return resp
|
304
|
+
end
|
305
|
+
|
306
|
+
def request_post(api_cmd, data)
|
307
|
+
req = Request.new(@client)
|
308
|
+
resp = req.exec_post(api_cmd, data)
|
309
|
+
return resp
|
310
|
+
end
|
311
|
+
|
312
|
+
# Searched an array of hashes for a key and value to match
|
313
|
+
# and returns a field of that hash.
|
314
|
+
# * *Args* :
|
315
|
+
# - +rdata+ -> Array of hash data (e.g)
|
316
|
+
# - +k+ -> key (e.g. "name")
|
317
|
+
# - +v+ -> value to find (e.g. "Test Project")
|
318
|
+
# - +key_return+ -> name of another field to return (e.g. "id")
|
319
|
+
# * *Returns* :
|
320
|
+
# - Value of a field in the hash
|
321
|
+
# - nil if none found
|
322
|
+
#
|
323
|
+
# Example: rdata: [{'id' => 12, 'name' => 'Project-Files, 'owner' => 'Serban', 'run_name' => 'Sprint 2'},
|
324
|
+
# {'id' => 22, 'name' => 'Faspex, 'owner' => 'Ajanta', 'run_name' => 'Marathon 10'}]
|
325
|
+
#
|
326
|
+
# search_array_kv(rdata, "name", "Faspex", "owner")
|
327
|
+
# => Calling this find the hash that has 'Faspex' for name,
|
328
|
+
# then return the value of 'owner' in that hash 'Ajanta'
|
329
|
+
#
|
330
|
+
def search_array_kv(rdata, k, v, key_return)
|
331
|
+
retval = nil
|
332
|
+
fnd = rdata.detect {|unhash| unhash[k] == v}
|
333
|
+
if ! fnd.nil?
|
334
|
+
retval = fnd[key_return]
|
335
|
+
end
|
336
|
+
return retval
|
337
|
+
end
|
338
|
+
|
339
|
+
|
340
|
+
# NOTE: MARK_TEST_PLAN
|
341
|
+
# User Input: Project Name, TestRun Name
|
342
|
+
# Project Name > Get project_id
|
343
|
+
# Call API get_plans/project_id to get all test plans for the project
|
344
|
+
# Get testplan_id of testplan with the given name
|
345
|
+
# Call API get_plan/testplan_id to get testruns inside this testplan
|
346
|
+
#
|
347
|
+
|
348
|
+
|
349
|
+
|
350
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
|
2
|
+
# Parses command line argument.
|
3
|
+
# Avoids requiring a dependent gem, easy to add any parameters and tags
|
4
|
+
# To Add New Parameter:
|
5
|
+
# => Add new tag in @valid_parameters
|
6
|
+
# => Change HELP message to describe new parameter added
|
7
|
+
#
|
8
|
+
class Argument
|
9
|
+
|
10
|
+
USAGE = "Usage: \n testrail_marker -r run_plan_name -p project_name -x /home/path_to/results_xml/dir \n"
|
11
|
+
HELP = " -h, Show HELP
|
12
|
+
-p *, name of project (e.g. TestRail API Gem) (required parameter)
|
13
|
+
-r or -t *, name of test run (-r) or test plan (-t) (required parameter)
|
14
|
+
-m, milestone name (can be used when creating a test run)
|
15
|
+
-s, test suite name (* required when creating a test run)
|
16
|
+
-u, user (e.g. ibarra@apitestrail.com)
|
17
|
+
-pw, password or token (recommended)
|
18
|
+
-url, URL of TestRail (e.g. https://yourcompany.testrail.io)
|
19
|
+
-cf, create a configuration file
|
20
|
+
-d, debug mode (set to false to suppresses most messages)
|
21
|
+
-x or -f *, path (-x, Directory) or specific file (-f) for results to parse
|
22
|
+
-com, comment to put on each test
|
23
|
+
|
24
|
+
|
25
|
+
NOTES: Results must have TestRail test case numbers to match. See README file for
|
26
|
+
more details.
|
27
|
+
Create options are available by adding \'c\' to some arguments, ex. -cr would create a new test run."
|
28
|
+
|
29
|
+
REQUIRED = "\nMissing required parameter/s (until config file implemented):
|
30
|
+
Ex: testrail_marker -p TestRail API Gem -r Regression Suite -x ./results/path
|
31
|
+
-p, name of project (e.g. -p TestRail API Gem)
|
32
|
+
-r or -t, name of test run or test plan (e.g. -r Regression Suite)
|
33
|
+
-x or -f, path (Directory) or a specific file of results to parse (e.g. -f /home/path/results/rspec_results.xml)\n"
|
34
|
+
|
35
|
+
# Constructor. Requires passing the parameters from the command line argument.
|
36
|
+
#
|
37
|
+
def initialize(passed_arguments)
|
38
|
+
@arg_passed = passed_arguments
|
39
|
+
@valid_parameters = ['-p', '-m', '-r', '-h', '-u', '-pw', '-url', '-d', '-x', '-t', '-s', '-com', '-f']
|
40
|
+
@create_parameters = ['-cm', '-cr', '-ct']
|
41
|
+
@delete_parameters = ['-dm', '-dr', '-dt']
|
42
|
+
@runner_parameters = ['-cf']
|
43
|
+
@valid_parameters += @create_parameters
|
44
|
+
@valid_parameters += @delete_parameters
|
45
|
+
@valid_parameters += @runner_parameters
|
46
|
+
@required_parameters = ['-p']
|
47
|
+
@requires_atleast_one = ['-r', '-t', '-cr', '-ct']
|
48
|
+
@requires_only_one = ['-x', '-f']
|
49
|
+
|
50
|
+
check_help(passed_arguments)
|
51
|
+
initialize_holder()
|
52
|
+
parse_args(passed_arguments)
|
53
|
+
check_required_parameters(passed_arguments)
|
54
|
+
print_arguments
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_arguments()
|
58
|
+
puts "\nPassed Arguments:"
|
59
|
+
@holder.each do |hold|
|
60
|
+
if hold[:value] != ""
|
61
|
+
puts " #{hold[:tag]} #{hold[:value]}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_args(arguments)
|
67
|
+
par_index = []
|
68
|
+
puts "ARG: #{arguments}"
|
69
|
+
@valid_parameters.each do |tag|
|
70
|
+
arg_index = arguments.index(tag).nil? ? -1 : arguments.index(tag)
|
71
|
+
par_index.push(arg_index)
|
72
|
+
end
|
73
|
+
@valid_parameters.each_with_index do |tag, x|
|
74
|
+
tag_index = par_index[x]
|
75
|
+
end_index = get_next_highest(tag_index, par_index)
|
76
|
+
save_arg_to_holder(arguments, tag_index, end_index)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the argument parameter passed with the specified tag
|
81
|
+
#
|
82
|
+
def get_arg_value(tag)
|
83
|
+
tag_value = nil
|
84
|
+
if @valid_parameters.include?(tag)
|
85
|
+
tag_hash = @holder.detect{|tag_data| tag_data[:tag] == tag}
|
86
|
+
tag_value = tag_hash[:value]
|
87
|
+
else
|
88
|
+
puts "ERROR: Parameter #{tag} not recognized."
|
89
|
+
end
|
90
|
+
return tag_value
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_optional_arg(tag_arr)
|
94
|
+
tag_value = nil
|
95
|
+
tag_arr.each do |tag|
|
96
|
+
if @valid_parameters.include?(tag)
|
97
|
+
tag_hash = @holder.detect{|tag_data| tag_data[:tag] == tag}
|
98
|
+
tag_value = tag_hash[:value]
|
99
|
+
else
|
100
|
+
puts "ERROR: Parameter #{tag} not recognized."
|
101
|
+
end
|
102
|
+
if tag_value == ""
|
103
|
+
tag_value = nil
|
104
|
+
end
|
105
|
+
if ! tag_value.nil?
|
106
|
+
break
|
107
|
+
end
|
108
|
+
end
|
109
|
+
return tag_value
|
110
|
+
end
|
111
|
+
|
112
|
+
def arg_exists?(tag)
|
113
|
+
it_exists = false
|
114
|
+
tagv = get_arg_value(tag)
|
115
|
+
if ! tagv.nil? && tagv != ""
|
116
|
+
it_exists = true
|
117
|
+
end
|
118
|
+
return it_exists
|
119
|
+
end
|
120
|
+
|
121
|
+
def has_argument?(tag)
|
122
|
+
if @arg_passed.include?(tag)
|
123
|
+
return true
|
124
|
+
end
|
125
|
+
return false
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# Creates an array to hold values of possible parameter tags.
|
131
|
+
#
|
132
|
+
def initialize_holder()
|
133
|
+
@holder = []
|
134
|
+
@valid_parameters.each do |tag|
|
135
|
+
param_hash = {:tag => tag, :value => ""}
|
136
|
+
@holder.push(param_hash)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns the next highest value in the array
|
141
|
+
# If num is the highest, then returns 100
|
142
|
+
def get_next_highest(num, array_num)
|
143
|
+
retval = nil
|
144
|
+
if ! num.nil? && num != -1
|
145
|
+
arr_size = array_num.size
|
146
|
+
sorted_nums = array_num.sort
|
147
|
+
num_index = sorted_nums.index(num)
|
148
|
+
if num_index == arr_size - 1
|
149
|
+
retval = 100
|
150
|
+
else
|
151
|
+
retval = sorted_nums[num_index + 1]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
return retval
|
155
|
+
end
|
156
|
+
|
157
|
+
def save_arg_to_holder(arguments, startx, endx)
|
158
|
+
if startx >= 0
|
159
|
+
which_tag = arguments[startx]
|
160
|
+
tag_hash = @holder.detect{|tag_data| tag_data[:tag] == which_tag}
|
161
|
+
tag_hash[:value] = arguments[startx+1..endx-1].join(" ")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def check_help(arguments)
|
166
|
+
if arguments.include?('-h')
|
167
|
+
puts "#{USAGE}"
|
168
|
+
puts "#{HELP} \n\n"
|
169
|
+
exit(0)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
# Verifies that all required parameters are passed in the argument.
|
176
|
+
# Two types of required. First, parameters that are absolutely needed.
|
177
|
+
# Second, parameters that are not all required but at least one must
|
178
|
+
# be passed.
|
179
|
+
# Exits the script if parameter requirements are not satisfied.
|
180
|
+
#
|
181
|
+
def check_required_parameters(arguments)
|
182
|
+
params_good = true
|
183
|
+
|
184
|
+
@runner_parameters.each do |run_par|
|
185
|
+
if arguments.include?(run_par)
|
186
|
+
return true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
@required_parameters.each do |req_par|
|
190
|
+
passed_reqpar = get_arg_value(req_par)
|
191
|
+
if passed_reqpar.nil? || passed_reqpar == ''
|
192
|
+
params_good = false
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
has_atleast_one = true
|
197
|
+
if @requires_atleast_one.size > 0
|
198
|
+
has_atleast_one = false
|
199
|
+
@requires_atleast_one.each do |least_one|
|
200
|
+
luno = get_arg_value(least_one)
|
201
|
+
if ! luno.nil? && luno != ""
|
202
|
+
has_atleast_one = true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
has_only_one = true
|
208
|
+
if @requires_only_one.size > 0
|
209
|
+
has_only_one = false
|
210
|
+
num_detected = 0
|
211
|
+
@requires_only_one.each do |only_one|
|
212
|
+
if arg_exists?(only_one)
|
213
|
+
num_detected += 1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
if num_detected == 1
|
217
|
+
has_only_one = true
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
if !params_good || ! has_atleast_one || ! has_only_one
|
222
|
+
puts "#{REQUIRED}"
|
223
|
+
exit(1)
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# History:
|
4
|
+
# 2/19/2018 Created ibarra.alfonso@gmail.com
|
5
|
+
#
|
6
|
+
#
|
7
|
+
class ConfigFile
|
8
|
+
|
9
|
+
attr_accessor :username, :token, :testrail_url, :filename, :default_comment
|
10
|
+
|
11
|
+
def initialize(cfile)
|
12
|
+
@filename = cfile
|
13
|
+
read_config_file
|
14
|
+
end
|
15
|
+
|
16
|
+
def prompt_user(user_msg, default_val)
|
17
|
+
retval = default_val
|
18
|
+
newval = ''
|
19
|
+
atmps = 0
|
20
|
+
while newval.strip == '' && atmps < 3
|
21
|
+
atmps += 1
|
22
|
+
print "#{user_msg}"
|
23
|
+
newval = STDIN.gets
|
24
|
+
retval = newval.strip == '' ? default_val : newval.strip
|
25
|
+
newval = retval
|
26
|
+
end
|
27
|
+
if atmps >= 3
|
28
|
+
puts "\nERROR: Value cannot be empty... exiting."
|
29
|
+
exit(1)
|
30
|
+
end
|
31
|
+
return retval
|
32
|
+
end
|
33
|
+
|
34
|
+
def user_continue?(user_msg, default_val=false)
|
35
|
+
retval = default_val
|
36
|
+
reply = prompt_user(user_msg, 'N')
|
37
|
+
if reply.upcase == "Y"
|
38
|
+
retval = true
|
39
|
+
end
|
40
|
+
return retval
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_config_file
|
44
|
+
if File.exist?(@filename)
|
45
|
+
@trail_info = YAML.load_file(@filename)
|
46
|
+
@username = @trail_info["username"]
|
47
|
+
@token = @trail_info["token"]
|
48
|
+
@testrail_url = @trail_info["testrail_url"]
|
49
|
+
@default_comment = @trail_info['default_comment']
|
50
|
+
else
|
51
|
+
@trail_info = Hash.new
|
52
|
+
@username = ''
|
53
|
+
@token = ''
|
54
|
+
@testrail_url = ''
|
55
|
+
@default_comment = 'Marked by Automation'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def check_create_configfile
|
60
|
+
if ! File.exist?(@filename)
|
61
|
+
puts "\nWARNING: Configuration File does not exist."
|
62
|
+
if user_continue?("Create a new config file (Y/N)? : ", 'N')
|
63
|
+
create_configfile
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_configfile
|
69
|
+
@username = prompt_user("Enter testrail email (#{@username}): ", @username)
|
70
|
+
@token = prompt_user("Enter testrail token (#{@token}): ", @token)
|
71
|
+
@testrail_url = prompt_user("TestRail URL (#{@testrail_url}): ", @testrail_url)
|
72
|
+
@default_comment = prompt_user("Test comment (Default - Marked by Automation): ", "Marked by Automation")
|
73
|
+
@trail_info = Hash.new
|
74
|
+
@trail_info["username"] = @username
|
75
|
+
@trail_info["token"] = @token
|
76
|
+
@trail_info["testrail_url"] = @testrail_url
|
77
|
+
@trail_info["default_comment"] = @default_comment
|
78
|
+
save
|
79
|
+
# Comment out until overwrite is finished.
|
80
|
+
#if user_continue?("Do you want to save the testrail project info (Y/N)?")
|
81
|
+
# config_project
|
82
|
+
# thash["project_name"] = @project_name
|
83
|
+
# thash["testrun"] = @testrun
|
84
|
+
# thash["testplan"] = @testplan
|
85
|
+
#end
|
86
|
+
end
|
87
|
+
|
88
|
+
def config_project
|
89
|
+
@project_name = prompt_user("Enter testrail project name: ")
|
90
|
+
@testrun = prompt_user("Enter name of test run: ", "NA")
|
91
|
+
@testplan = prompt_user("Enter name of test plan: ", "NA")
|
92
|
+
end
|
93
|
+
|
94
|
+
def update(varname, varvalue)
|
95
|
+
if defined? @trail_info
|
96
|
+
@trail_info[varname] = varvalue
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def save
|
101
|
+
File.open(@filename, 'w') { |f|
|
102
|
+
f.write @trail_info.to_yaml
|
103
|
+
puts "Successfully saved config file: #{@filename}"
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|