dromedary 0.1.00 → 0.3.01

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: f7c4953cb5e750a7e289cb591ab50655cad5920e
4
- data.tar.gz: e6c1dcf1798ea13779f1759c9bbff33bce912275
3
+ metadata.gz: fea21242953b1f423fb38f9d24aa1b444c540469
4
+ data.tar.gz: 868bab3b50c29e45f3dac3a96dab2b60cde378b8
5
5
  SHA512:
6
- metadata.gz: 7dc7fbae20ef3d331e3f27bd6e2779b7613193f275b4a8bd8602f63bdf81a57c7958d00120d8afb4d9da4422843e94c13872c2b07b6889942b26715c457270f9
7
- data.tar.gz: 3bd2f99b43dc908f165597c91cbad255bc4936cd41189179fe2c3fcab8bc36fe45304579ce7fc7e97a0f92e2ed7f2f8ab13ccb6b1f721a8039625c28ba12e0d3
6
+ metadata.gz: dedb64bf51d47651dd8331f394a2ac02fce2aeea987a59869d40a58212cb1752e06b1d0d3b56269d996a10338001c44e2a2954c77ad2de4a68a5a729fd7f31a1
7
+ data.tar.gz: 21d7bef695d7c24b972cf3d1da30eda87a82fc3c6263dd3f5d580eaf0f61b42c6a0a5ee0e5c4b7a39f73aa406cef919fdd2d5efe7054935d45e93ae87a8189ac
@@ -0,0 +1,11 @@
1
+ require 'rake'
2
+
3
+ module Dromedary
4
+ class Tasks
5
+ include Rake::DSL if defined? Rake::DSL
6
+ def install_tasks
7
+ load 'tasks/dromedary.rake'
8
+ end
9
+ end
10
+ end
11
+ Dromedary::Tasks.new.install_tasks
@@ -1,15 +1,23 @@
1
1
  module DromedaryInitializer
2
2
  def self.run
3
- if cucumber_initialized?
3
+ if cucumber_not_initialized?
4
4
  report_no_cucumber_found
5
5
  elsif already_initialized?
6
6
  report_already_initialized
7
7
  else
8
+ create_directory 'config'
8
9
  create_file 'config/dromedary.yml'
9
10
  create_file 'features/support/dromedary_hooks.rb'
11
+ create_file 'config/cucumber.yml'
12
+ create_file 'Rakefile'
10
13
 
11
14
  update_file 'config/dromedary.yml', dromedary_config_content
12
15
  update_file 'features/support/dromedary_hooks.rb', dromedary_hooks_content
16
+
17
+ update_file 'config/cucumber.yml', cucumber_config_content
18
+ update_file '.gitignore', gitignore_content
19
+ update_file 'Rakefile', rakefile_content
20
+ update_file 'Gemfile', gemfile_content
13
21
  end
14
22
  end
15
23
 
@@ -44,7 +52,7 @@ module DromedaryInitializer
44
52
  report_updating(file_name)
45
53
  end
46
54
 
47
- def self.cucumber_initialized?
55
+ def self.cucumber_not_initialized?
48
56
  !File.exist?('features/support/env.rb')
49
57
  end
50
58
 
@@ -156,10 +164,65 @@ module DromedaryInitializer
156
164
  '',
157
165
  ' # setting TestRail to generate reports at specific folder',
158
166
  " unless @local == 'true'",
159
- ' File.open("artifacts/test_rail_results/file_#{UUID.generate(:compact).to_s}.json", "w") do |file|',
167
+ ' File.open("artifacts/testrail_reports/file_#{Time.now.to_i}.json}.json", "w") do |file|',
160
168
  ' file.puts @results.to_json',
161
169
  ' end',
162
170
  ' end',
163
171
  'end']
164
172
  end
173
+
174
+ def self.cucumber_config_content
175
+ ['',
176
+ '# Following lines were generated by Dromedary gem',
177
+ '# It contains required Cucumber profiles to ensure that all reporting works',
178
+ '',
179
+ cucumber_config_structure]
180
+ end
181
+
182
+ def self.cucumber_config_structure
183
+ ['junit_report: --format pretty --format junit --out artifacts/junit_xml_reports',
184
+ 'run_json_report: --format json --out artifacts/cucumber_json_reports/run.json',
185
+ 'rerun_json_report: --format json --out artifacts/cucumber_json_reports/rerun.json',
186
+ 'rerun_formatter: --format rerun --out artifacts/final_test_reports/fails.log']
187
+ end
188
+
189
+ def self.gitignore_content
190
+ ['',
191
+ gitignore_structure]
192
+ end
193
+
194
+ def self.gitignore_structure
195
+ ['artifacts/']
196
+ end
197
+
198
+ def self.rakefile_content
199
+ ['',
200
+ '',
201
+ '# require Dromedary gem dependencies',
202
+ rakefile_structure]
203
+ end
204
+
205
+ def self.rakefile_structure
206
+ ["require 'dromedary/tasks'",
207
+ '',
208
+ '# describing Dromedary rake tasks',
209
+ "desc 'Rake task to run all the Dromedary sequence'",
210
+ 'task :run_dromedary, :run_on do |task, args|',
211
+ ' ENV["RUN_ON"] = "#{args[:run_on]}"',
212
+ ' %W[prepare_for_a_ride store_cases_titles run_cucumber merge_junit_reports get_case_ids[run] rerun_if_needed generate_cucumber_json_reports create_run[smoke,#{args[:run_on]}] close_run[#{args[:run_on]}] final_clean_ups].each do |task_name|',
213
+ ' sh "rake #{task_name}" do',
214
+ ' #ignore errors',
215
+ ' end',
216
+ ' end',
217
+ 'end']
218
+ end
219
+
220
+ def self.gemfile_content
221
+ ['',
222
+ gemfile_structure]
223
+ end
224
+
225
+ def self.gemfile_structure
226
+ ["gem 'junit_merge'"]
227
+ end
165
228
  end
@@ -0,0 +1,267 @@
1
+ require 'nokogiri'
2
+ require 'yaml'
3
+ require_relative '../testrail'
4
+
5
+ DROMEDARY = YAML.load_file("#{Dir.pwd}/config/dromedary.yml")
6
+
7
+ # TASKS
8
+
9
+ # Preparation tasks
10
+
11
+ desc 'This task creates required folders and files'
12
+ task :prepare_for_a_ride do
13
+ %W[create_folders create_files].each do |task_name|
14
+ sh "rake #{task_name}" do
15
+ #ignore errors
16
+ end
17
+ end
18
+ end
19
+
20
+ desc 'This task creates required folder tree for reporting'
21
+ task :create_folders do
22
+ %W[artifacts artifacts/cucumber_json_reports artifacts/junit_xml_reports artifacts/testrail_reports artifacts/final_test_reports].each do |dir_name|
23
+ Dir.mkdir "#{dir_name}"
24
+ end
25
+ end
26
+
27
+ desc 'This task creates and updates required files for reporting'
28
+ task :create_files do
29
+ %W[artifacts/cucumber_json_reports/run.json artifacts/cucumber_json_reports/rerun.json artifacts/final_test_reports/final_cucumber_json_report.json artifacts/final_test_reports/run_results_with_case_id.json artifacts/final_test_reports/rerun_results_with_case_id.json artifacts/final_test_reports/test_cases.json].each do |file_name|
30
+ File.open(file_name, 'w') do |file|
31
+ file.puts '[]'
32
+ end
33
+ end
34
+ File.open('artifacts/final_test_reports/final_junit_report.xml', 'w') do |file|
35
+ xml_structure.each do |line|
36
+ file.puts line
37
+ end
38
+ end
39
+ end
40
+
41
+ desc 'Saving Test cases from remote TestRail project'
42
+ task :store_cases_titles do
43
+ @client = TestRail::APIClient.new(DROMEDARY['testrail']['url'])
44
+ @client.user = DROMEDARY['testrail']['user']
45
+ @client.password = DROMEDARY['testrail']['password']
46
+
47
+ project_id = DROMEDARY['testrail']['project_id']
48
+ suite_id = DROMEDARY['testrail']['suite_id']
49
+ cases = @client.get_cases_for_suite(project_id, suite_id)
50
+ @full_cases = @client.get_cases_titles(cases, project_id, suite_id)
51
+
52
+ File.open('artifacts/final_test_reports/test_cases.json', 'w') do |file|
53
+ require 'json'
54
+ file.puts @full_cases.to_json
55
+ end
56
+ end
57
+
58
+ # Runner tasks
59
+
60
+ desc 'Run Cucumber features for the first run'
61
+ task :run_cucumber do
62
+ sh "cucumber -p junit_report -p rerun_formatter -p run_json_report" do
63
+ #ignore errors
64
+ end
65
+ end
66
+
67
+ desc 'Rerun Cucumber features according to the fails.log'
68
+ task :rerun_failed do
69
+ sh "cucumber @artifacts/final_test_reports/fails.log -p junit_report -p rerun_json_report" do
70
+ #ignore errors
71
+ end
72
+ end
73
+
74
+ task :rerun_if_needed do
75
+ if File.file?("artifacts/final_test_reports/fails.log")
76
+ if File.read("artifacts/final_test_reports/fails.log").empty?
77
+ puts 'Rerun step skipped, no fails occurred during the first run'
78
+ else
79
+ fails = File.read("artifacts/final_test_reports/fails.log")
80
+
81
+ File.open('artifacts/final_test_reports/fails.log', 'w') do |file|
82
+ file.puts fails.gsub('\n', ' ')
83
+ end
84
+
85
+ sh "rake rerun_and_update_reports" do
86
+ #ignore errors
87
+ end
88
+ end
89
+ else
90
+ puts 'Rerun step skipped, no fails occurred during the first run'
91
+ end
92
+ end
93
+
94
+ desc 'Rerun failed Cucumber features and update respective reports'
95
+ task :rerun_and_update_reports do
96
+ %W[clean_interim_reports rerun_failed merge_junit_reports get_case_ids[rerun]].each do |task_name|
97
+ sh "rake #{task_name}" do
98
+ #ignore errors
99
+ end
100
+ end
101
+ end
102
+
103
+ # Cleaning tasks
104
+
105
+ desc 'Cleaning all interim reports'
106
+ task :clean_interim_reports do
107
+ %W[clean_test_rail clean_junit].each do |task_name|
108
+ sh "rake #{task_name}" do
109
+ #ignore errors
110
+ end
111
+ end
112
+ end
113
+
114
+ desc 'Cleaning interim TestRail reports'
115
+ task :clean_test_rail do
116
+ catalog = 'artifacts/testrail_reports'
117
+ files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) }
118
+ files.map! { |f| "#{catalog}/#{f}" }
119
+ rm files
120
+ end
121
+
122
+ desc 'Cleaning interim JUnit reports'
123
+ task :clean_junit do
124
+ catalog = 'artifacts/junit_xml_reports'
125
+ files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) }
126
+ files.map! { |f| "#{catalog}/#{f}" }
127
+ rm files
128
+ end
129
+
130
+ desc 'Cleaning interim Cucumber JSON reports'
131
+ task :clean_cucumber_json do
132
+ catalog = 'artifacts/cucumber_json_reports'
133
+ files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) }
134
+ files.map! { |f| "#{catalog}/#{f}" }
135
+ rm files
136
+ end
137
+
138
+ desc 'Cleaning rudimentary folders'
139
+ task :clean_folders do
140
+ catalog = 'artifacts'
141
+ dirs = Dir.entries(catalog).drop 2
142
+ dirs.delete('final_test_reports')
143
+ dirs.map! { |f| "#{catalog}/#{f}" }
144
+ dirs.each do |dir_path|
145
+ remove_dir dir_path
146
+ end
147
+ end
148
+
149
+ desc 'Cleaning project tree from unnecessary files and folders'
150
+ task :final_clean_ups do
151
+ %W[clean_test_rail clean_junit clean_cucumber_json clean_folders].each do |task_name|
152
+ sh "rake #{task_name}" do
153
+ #ignore errors
154
+ end
155
+ end
156
+ end
157
+
158
+ # Report generation tasks
159
+
160
+ desc 'Merging interim JUnit reports to final JUnit report'
161
+ task :merge_junit_reports do
162
+ file_names = Dir.entries('artifacts/junit_xml_reports').delete_if { |entry| File.directory?(entry) }
163
+ file_names.each do |file_name|
164
+ sh "junit_merge artifacts/junit_xml_reports/#{file_name} artifacts/final_test_reports/final_junit_report.xml" do
165
+ #ignore errors
166
+ end
167
+ end
168
+ end
169
+
170
+ desc 'Merging interim Cucumber json reports to final Cucumber json report'
171
+ task :generate_cucumber_json_reports do
172
+ test_results = []
173
+
174
+ run_results = JSON.parse(File.read('artifacts/cucumber_json_reports/run.json'))
175
+ rerun_results = JSON.parse(File.read('artifacts/cucumber_json_reports/rerun.json'))
176
+
177
+ run_results.each do |x|
178
+ rerun_results.each do |y|
179
+ if y.values[0] == x.values[0]
180
+ x.merge!(y)
181
+ end
182
+ end
183
+ test_results.push(x)
184
+ end
185
+
186
+ File.open('artifacts/final_test_reports/final_cucumber_json_report.json', 'w') do |file|
187
+ require 'json'
188
+ file.puts test_results.to_json
189
+ end
190
+ end
191
+
192
+ desc 'Generating interim TestRail report for a particular run'
193
+ task :get_case_ids, :run_type do |task, args|
194
+ @test_results = {}
195
+ file = File.read('artifacts/final_test_reports/test_cases.json')
196
+ @full_cases = JSON.parse(file)
197
+
198
+ file_names = Dir.entries('artifacts/testrail_reports').delete_if { |entry| File.directory?(entry) }
199
+ file_names.each do |file_name|
200
+ result = JSON.parse(File.read("artifacts/testrail_reports/#{file_name}"))
201
+ @test_results.update(result)
202
+ end
203
+
204
+ @results_json = []
205
+ @test_results.map do |full_desc,status_id|
206
+ n = 0
207
+ until n == status_id.count do
208
+ current_result = {:case_id => find_id(full_desc)[n], :status_id => status_id[n] } if find_id(full_desc)
209
+ @results_json.push(current_result)
210
+ n += 1
211
+ end
212
+ end
213
+
214
+ @results_json.compact!
215
+ File.open("artifacts/final_test_reports/#{args[:run_type]}_results_with_case_id.json", 'w') do |file|
216
+ file.write(@results_json.to_json)
217
+ end
218
+ end
219
+
220
+ desc 'Creating Test Run on remote TestRail project'
221
+ task :create_run, :suite_type, :environment, :section_name do |task, args|
222
+ @client = TestRail::APIClient.new(DROMEDARY['testrail']['url'])
223
+ @client.user = DROMEDARY['testrail']['user']
224
+ @client.password = DROMEDARY['testrail']['password']
225
+ project_id = DROMEDARY['testrail']['project_id']
226
+ suite_id = DROMEDARY['testrail']['suite_id']
227
+
228
+ test_run_name = DROMEDARY['testrail']['test_run_default_name'] + ' ' + args[:suite_type].capitalize + ' on ' + args[:environment].capitalize
229
+ test_run = @client.add_run(project_id, suite_id, test_run_name)
230
+ file = File.open('artifacts/final_test_reports/test_run_id.txt', File::CREAT|File::TRUNC|File::RDWR)
231
+ file.puts test_run['id']
232
+ file.close
233
+ end
234
+
235
+ desc 'Closing Test Run on remote TestRail project'
236
+ task :close_run, :environment do
237
+ @client = TestRail::APIClient.new(DROMEDARY['testrail']['url'])
238
+ @client.user = DROMEDARY['testrail']['user']
239
+ @client.password = DROMEDARY['testrail']['password']
240
+
241
+ run_results = JSON.parse(File.read('artifacts/final_test_reports/run_results_with_case_id.json'))
242
+ rerun_results = JSON.parse(File.read('artifacts/final_test_reports/rerun_results_with_case_id.json'))
243
+ test_results = run_results + rerun_results
244
+
245
+ run_id = File.new('artifacts/final_test_reports/test_run_id.txt').read.chomp
246
+ @client.add_results_for_cases(run_id, test_results)
247
+ @client.mark_untested_tests_failed(run_id)
248
+ @client.close_run(run_id, data = {})
249
+ end
250
+
251
+ # METHODS
252
+
253
+ def xml_structure
254
+ ['<?xml version="1.0" encoding="UTF-8"?>',
255
+ '<testsuite name="" tests="" failures="" errors="" time="" timestamp="">',
256
+ ' <!-- Randomized with seed 00000 -->',
257
+ ' <properties/>',
258
+ '</testsuite>']
259
+ end
260
+
261
+ def find_id(full_title)
262
+ @ids_array = []
263
+ @full_cases.select {|c| c['title'] == full_title.gsub(' ', ' ')}.each do |e|
264
+ @ids_array << e['id']
265
+ end
266
+ @ids_array unless @ids_array.empty?
267
+ end
@@ -0,0 +1,264 @@
1
+ #
2
+ # TestRail API binding for Ruby (API v2, available since TestRail 3.0)
3
+ #
4
+ # Learn more:
5
+ #
6
+ # http://docs.gurock.com/testrail-api2/start
7
+ # http://docs.gurock.com/testrail-api2/accessing
8
+ #
9
+ # Copyright Gurock Software GmbH. See license.md for details.
10
+ #
11
+
12
+ require 'net/http'
13
+ require 'net/https'
14
+ require 'uri'
15
+ require 'json'
16
+
17
+ module TestRail
18
+ class APIClient
19
+ @url = ''
20
+ @user = ''
21
+ @password = ''
22
+
23
+ attr_accessor :user
24
+ attr_accessor :password
25
+
26
+ def initialize(base_url)
27
+ if !base_url.match(/\/$/)
28
+ base_url += '/'
29
+ end
30
+ @url = base_url + 'index.php?/api/v2/'
31
+ end
32
+
33
+ def add_run(project_id, suite_id, test_run_name, section_id=nil)
34
+ cases_ids = section_id ? get_all_cases(project_id, suite_id, section_id) : get_cases_for_suite(project_id, suite_id).map {|item| item['id']}
35
+ data = {'suite_id'=> suite_id, 'name' => test_run_name,'include_all'=>false, 'case_ids' => cases_ids }
36
+ send_post("add_run/#{project_id}", data)
37
+ end
38
+
39
+ def get_all_cases(project_id, suite_id, section_id)
40
+ all_sections = get_all_inherited_sections(project_id, suite_id, section_id)
41
+ cases_ids = []
42
+ all_sections.uniq!
43
+ all_sections.each do |section|
44
+ cases_ids += get_cases_for_section(project_id, suite_id, section)
45
+ end
46
+ cases_ids
47
+ end
48
+
49
+ def get_cases_for_suite(project_id, suite_id)
50
+ send_get("get_cases/#{project_id}&suite_id=#{suite_id}")
51
+ end
52
+
53
+ def get_cases_for_section(project_id, suite_id, section_id)
54
+ send_get("get_cases/#{project_id}&suite_id=#{suite_id}&section_id=#{section_id}").map {|item| item['id']}
55
+ end
56
+
57
+ def get_all_inherited_sections(project_id, suite_id, section_id)
58
+ hash = sections_hash(project_id, suite_id)
59
+ to_preceed = hash['entries'].find{|el| el['id'] == section_id}
60
+ results = []
61
+ get_entries_array to_preceed, results
62
+ results.map { |el| el['id']}
63
+ end
64
+
65
+ def get_cases_titles(cases, project_id, suite_id)
66
+ sections = get_sections(project_id, suite_id)
67
+ full_cases = []
68
+ cases.each do |c|
69
+ c['title'] = full_title(c, sections)
70
+ full_cases << c
71
+ end
72
+
73
+ full_cases
74
+ end
75
+
76
+ def add_results_for_cases(run_id, test_rail_results)
77
+ data = {}
78
+ data[:results] = test_rail_results
79
+ send_post("add_results_for_cases/#{run_id}", data)
80
+ end
81
+
82
+ def full_title(case_hash, sections)
83
+ parent_section_id = case_hash['section_id']
84
+ results = []
85
+ section = sections.find do |sec|
86
+ sec['id'] == parent_section_id
87
+ end
88
+
89
+ get_full_sections_title_for(section, sections, results)
90
+ results.push(case_hash['title']).join(' ')
91
+ end
92
+
93
+ def get_section(section_id)
94
+ send_get("get_section/#{section_id}")
95
+ end
96
+
97
+ def get_full_sections_title_for(section, sections, results)
98
+ results.unshift(section['name'])
99
+ unless section['depth'] == 0
100
+ parent_section = parent_section(section, sections)
101
+ get_full_sections_title_for(parent_section, sections, results)
102
+ end
103
+ end
104
+
105
+
106
+ def get_entries_array(node, results)
107
+ results << node
108
+ node['entries'].each do |entry|
109
+ results << entry
110
+ unless entry['entries'].empty?
111
+ get_entries_array(entry, results)
112
+ end
113
+ end
114
+ end
115
+
116
+ def parent_section(section, sections)
117
+ sections.find { |sec| sec['id'] == section['parent_id'] }
118
+ end
119
+
120
+ def build_hash(node, array)
121
+ nodes_to_proceed = array.select do |section|
122
+ section['parent_id'] == node['id']
123
+ end
124
+
125
+ nodes_to_proceed.each do |n|
126
+ node['entries'] << n
127
+ array.delete n
128
+ build_hash(n, array)
129
+ end
130
+ end
131
+
132
+
133
+ def sections_hash(project_id, suite_id)
134
+ all_sections = get_sections(project_id, suite_id)
135
+ all_sections.map! {|el| el['entries'] =[]; el}
136
+ main = all_sections.find {|el| el['depth'] == 0}
137
+ all_sections.delete(main)
138
+ build_hash(main, all_sections)
139
+ main
140
+ end
141
+
142
+ def get_section_id(project_id, suite_id, section_title)
143
+ all_sections = get_sections(project_id, suite_id)
144
+ all_sections.find{|section| section['name'] == section_title}['id']
145
+ end
146
+
147
+ def get_sections(project_id, suite_id)
148
+ send_get("get_sections/#{project_id}&suite_id=#{suite_id}")
149
+ end
150
+
151
+ def add_result_for_case(run_id, case_id, data)
152
+ send_post("add_result_for_case/#{run_id}/#{case_id}", data)
153
+ end
154
+
155
+ def close_run(run_id, data)
156
+ send_post("close_run/#{run_id}", data)
157
+ end
158
+
159
+ def mark_untested_tests_failed(run_id)
160
+ tests = get_untested_tests(run_id)
161
+ return if tests.empty?
162
+ tests_ids = tests.map {|t| t['id']}
163
+ mark_failed_tests_for_run(run_id, tests_ids)
164
+ end
165
+
166
+ def add_milestone(project_id, ms_name)
167
+ data = {"name"=> ms_name + Time.now.strftime("_%H/%M/%S_%d/%m/%Y")}
168
+ response = send_post("add_milestone/#{project_id}", data)
169
+ response['id']
170
+ end
171
+
172
+ def close_milestone(ms_id)
173
+ data = {'is_completed' => true}
174
+ send_post("update_milestone/#{ms_id}", data)
175
+ end
176
+
177
+ def mark_failed_tests_for_run(run_id, tests_ids)
178
+ data = {}
179
+ data['results'] = []
180
+ tests_ids.each do |id|
181
+ data['results'] << {'test_id'=>id, 'status_id'=>5}
182
+ end
183
+ send_post("add_results/#{run_id}", data)
184
+ end
185
+
186
+ def get_untested_tests(run_id)
187
+ send_get("get_tests/#{run_id}&status_id=3")
188
+ end
189
+
190
+
191
+ #
192
+ # Send Get
193
+ #
194
+ # Issues a GET request (read) against the API and returns the result
195
+ # (as Ruby hash).
196
+ #
197
+ # Arguments:
198
+ #
199
+ # uri The API method to call including parameters
200
+ # (e.g. get_case/1)
201
+ #
202
+ def send_get(uri)
203
+ _send_request('GET', uri, nil)
204
+ end
205
+
206
+ #
207
+ # Send POST
208
+ #
209
+ # Issues a POST request (write) against the API and returns the result
210
+ # (as Ruby hash).
211
+ #
212
+ # Arguments:
213
+ #
214
+ # uri The API method to call including parameters
215
+ # (e.g. add_case/1)
216
+ # data The data to submit as part of the request (as
217
+ # Ruby hash, strings must be UTF-8 encoded)
218
+ #
219
+ def send_post(uri, data)
220
+ _send_request('POST', uri, data)
221
+ end
222
+
223
+ private
224
+ def _send_request(method, uri, data)
225
+ url = URI.parse(@url + uri)
226
+ if method == 'POST'
227
+ request = Net::HTTP::Post.new(url.path + '?' + url.query)
228
+ request.body = JSON.dump(data)
229
+ else
230
+ request = Net::HTTP::Get.new(url.path + '?' + url.query)
231
+ end
232
+ request.basic_auth(@user, @password)
233
+ request.add_field('Content-Type', 'application/json')
234
+
235
+ conn = Net::HTTP.new(url.host, url.port)
236
+ if url.scheme == 'https'
237
+ conn.use_ssl = true
238
+ conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
239
+ end
240
+ response = conn.request(request)
241
+
242
+ if response.body && !response.body.empty?
243
+ result = JSON.parse(response.body)
244
+ else
245
+ result = {}
246
+ end
247
+
248
+ if response.code != '200'
249
+ if result && result.key?('error')
250
+ error = '"' + result['error'] + '"'
251
+ else
252
+ error = 'No additional error message received'
253
+ end
254
+ raise APIError.new('TestRail API returned HTTP %s (%s)' %
255
+ [response.code, error])
256
+ end
257
+
258
+ result
259
+ end
260
+ end
261
+
262
+ class APIError < StandardError
263
+ end
264
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dromedary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.00
4
+ version: 0.3.01
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denys Bazarnyi
@@ -20,8 +20,11 @@ extra_rdoc_files: []
20
20
  files:
21
21
  - bin/dromedary
22
22
  - lib/dromedary.rb
23
+ - lib/dromedary/tasks.rb
23
24
  - lib/dromedary_initializer.rb
24
- homepage:
25
+ - lib/tasks/dromedary.rake
26
+ - lib/testrail.rb
27
+ homepage: http://rubygems.org/gems/dromedary
25
28
  licenses:
26
29
  - MIT
27
30
  metadata: {}