testrailtagging 0.3.6.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 +7 -0
- data/.gitignore +9 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +75 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/files/RSpecParser.rb +177 -0
- data/lib/files/TestCase.rb +38 -0
- data/lib/files/testcase_modifications.rb +393 -0
- data/lib/files/testrail_apiclient_retry.rb +46 -0
- data/lib/files/testrail_operations.rb +369 -0
- data/lib/files/testrail_queries.rb +108 -0
- data/lib/files/testrail_rspec_integration.rb +385 -0
- data/lib/files/version.rb +3 -0
- data/lib/testrailtagging.rb +4 -0
- data/testrailtagging.gemspec +28 -0
- metadata +133 -0
@@ -0,0 +1,385 @@
|
|
1
|
+
require "rspec"
|
2
|
+
require_relative "testrail_operations"
|
3
|
+
|
4
|
+
module TestRailRSpecIntegration
|
5
|
+
# This class responsible for communicating a test run back to testrail.
|
6
|
+
# The status of a test example is NOT set until the 'after' hooks run.
|
7
|
+
# Because the 'after' hook is not meant for observing the status of examples.
|
8
|
+
# Thus you can NOT run an after block to get the completion status.
|
9
|
+
# For a better explanation see:
|
10
|
+
# https://github.com/rspec/rspec-core/issues/2011
|
11
|
+
|
12
|
+
# For pushing results up to an existing test run in TestRail, no matter whether the test run is independent
|
13
|
+
# or grouped under a test plan
|
14
|
+
# # This is different from simply creating a stand-alone test run from the results of the test.
|
15
|
+
# The tricky part about this is Jenkins run rspecs on multiple processes with different batches of
|
16
|
+
# rspec tests.
|
17
|
+
|
18
|
+
@@total_count = 0
|
19
|
+
@@run_count = 0
|
20
|
+
@@skip_count = 0
|
21
|
+
|
22
|
+
class TestRailPlanFormatter
|
23
|
+
RSpec::Core::Formatters.register self, :example_passed, :example_pending, :example_failed, :start, :stop
|
24
|
+
public
|
25
|
+
def initialize(out)
|
26
|
+
@out = out
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.set_product(product)
|
30
|
+
@@product = product
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_id_key
|
34
|
+
case @@product
|
35
|
+
when :bridge
|
36
|
+
:testrail_id
|
37
|
+
when :canvas
|
38
|
+
:test_id
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Gets whether the formatter is active or not.
|
43
|
+
# We don't want to push results up to test rail for instance if --dry-run is specified on the command line.
|
44
|
+
def active
|
45
|
+
!RSpec.configuration.dry_run
|
46
|
+
end
|
47
|
+
|
48
|
+
# This gets called before all tests are run
|
49
|
+
def start(_start_notification)
|
50
|
+
# It's been verified that these 4 environment variables already exist
|
51
|
+
# These three are not actively used in this class, but their presence governs whether
|
52
|
+
# this class is instantiated and used in the first place.
|
53
|
+
|
54
|
+
if is_for_test_rail_run
|
55
|
+
@testrail_run_id = ENV["TESTRAIL_RUN_ID"]
|
56
|
+
elsif !ENV["TESTRAIL_PLAN_ID"].nil?
|
57
|
+
@testrail_plan_id = ENV["TESTRAIL_PLAN_ID"]
|
58
|
+
@testrail_run_name = ENV["TESTRAIL_RUN"]
|
59
|
+
if is_for_test_rail_plan # run on jenkins
|
60
|
+
@testrail_run_id = ENV["TESTRAIL_ENTRY_RUN_ID"]
|
61
|
+
@testrail_entry_id = ENV["TESTRAIL_ENTRY_ID"]
|
62
|
+
else # run locally, and only one thread
|
63
|
+
ids = TestRailOperations.create_test_plan_entry(@testrail_plan_id, @testrail_run_name, include_all_cases: true)
|
64
|
+
@testrail_run_id = ids[:run_id]
|
65
|
+
@testrail_entry_id = ids[:entry_id]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Pull down ALL the test cases from testrail. Granted this is more than what rspec will actually
|
70
|
+
# execute. But there is no safe way to append a test case to a test run in a parallel environment.
|
71
|
+
# The Testrail API is just too limited.
|
72
|
+
puts "Using test run ID: #{@testrail_run_id}"
|
73
|
+
puts "Using test entry ID: #{@testrail_entry_id}"
|
74
|
+
|
75
|
+
puts "Count of skipped tests: #{TestRailRSpecIntegration.get_skip_count}"
|
76
|
+
puts "Count of tests to be run: #{TestRailRSpecIntegration.get_run_count}"
|
77
|
+
puts "Count of tests that entered filter: #{TestRailRSpecIntegration.get_total_count}"
|
78
|
+
|
79
|
+
@test_case_hash = TestRailOperations.get_test_run_cases(@testrail_run_id)
|
80
|
+
# save the test case ID's that were actually executed
|
81
|
+
@executed_test_ids = []
|
82
|
+
end
|
83
|
+
|
84
|
+
# This gets called after all tests are run
|
85
|
+
def stop(_examples_notification)
|
86
|
+
if @testrail_plan_id
|
87
|
+
# Need to prune un-executed tests from the test run on testrail
|
88
|
+
if is_for_test_rail_plan # run on jenkins, multiple threads doing this
|
89
|
+
# Need to dump a list of executed tests so unexecuted tests can be pruned later (on testrail)
|
90
|
+
# after all the rspec tests are done.
|
91
|
+
File.open("executed_tests_#{Process.pid}.json", 'w') do |f|
|
92
|
+
f.puts @executed_test_ids.to_json
|
93
|
+
end
|
94
|
+
# Another process will take the json file and use it to prune the test run.
|
95
|
+
else # run locally, and only one thread
|
96
|
+
# prune the test cases to only what was run
|
97
|
+
response = TestRailOperations.keep_only(@testrail_plan_id, @testrail_entry_id, @executed_test_ids)
|
98
|
+
end
|
99
|
+
elsif !ENV["TESTRAIL_RUN_ID"].nil?
|
100
|
+
# Results were already pushed to an existing testrail run. Nothing more to do here, we are done! :)
|
101
|
+
else
|
102
|
+
puts "Unknown condition"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# This gets called after all `after` hooks are run after each example is completed
|
107
|
+
def example_finished(notification)
|
108
|
+
return unless active
|
109
|
+
example = notification.example
|
110
|
+
result = example.execution_result
|
111
|
+
|
112
|
+
testrail_ids = example.metadata[test_id_key]
|
113
|
+
return unless testrail_ids.present?
|
114
|
+
completion_message = ""
|
115
|
+
|
116
|
+
if (result.status == :failed)
|
117
|
+
# This is the best format, unfortunately it has bash console color codes embedded in it.
|
118
|
+
completion_message = notification.fully_formatted(1)
|
119
|
+
# need to remove those color codes from the string
|
120
|
+
completion_message.gsub!(/\[(\d)+m/, '')
|
121
|
+
end
|
122
|
+
|
123
|
+
cases = [] # the test cases
|
124
|
+
Array(testrail_ids).each do |id|
|
125
|
+
tc = @test_case_hash[id.to_i]
|
126
|
+
next unless tc # A test case ID exists in the rspec file, but not on testrail
|
127
|
+
tc.set_status(result.status, completion_message)
|
128
|
+
cases << tc
|
129
|
+
@executed_test_ids << id.to_i
|
130
|
+
end
|
131
|
+
|
132
|
+
post_results cases
|
133
|
+
end
|
134
|
+
|
135
|
+
# test_cases is an array of TestCase instances
|
136
|
+
def post_results(test_cases)
|
137
|
+
data = []
|
138
|
+
test_cases.each do |tc|
|
139
|
+
|
140
|
+
status_value = TestRailOperations.status_rspec_to_testrail(tc.status)
|
141
|
+
if status_value == TestRailOperations::UNTESTED
|
142
|
+
# ! SUPER IMPORTANT !
|
143
|
+
# test rail does NOT allow you to set the status of a test to untested.
|
144
|
+
# so skip them
|
145
|
+
next
|
146
|
+
end
|
147
|
+
|
148
|
+
# id was not found in the list of test run id's. Due to incorrect include pattern in rspec.
|
149
|
+
next unless tc.temp_id
|
150
|
+
|
151
|
+
data << {
|
152
|
+
"test_id" => tc.temp_id, # results require the new test case temporary ID's, not the static ID's
|
153
|
+
"status_id" => status_value,
|
154
|
+
"comment" => tc.result_message
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
if data.size > 0
|
159
|
+
TestRailOperations.post_run_results(@testrail_run_id, data)
|
160
|
+
test_case_ids = test_cases.collect { |tc| tc.id }
|
161
|
+
@out.puts "Successfully posted results for testcases: #{test_case_ids} to test run: #{@testrail_run_id}"
|
162
|
+
else
|
163
|
+
@out.puts "No results sent to test rail"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
alias_method :example_passed, :example_finished
|
168
|
+
alias_method :example_pending, :example_finished
|
169
|
+
alias_method :example_failed, :example_finished
|
170
|
+
|
171
|
+
private
|
172
|
+
# For pushing results up to a test plan in TestRail.
|
173
|
+
def is_for_test_rail_plan
|
174
|
+
!ENV["TESTRAIL_RUN"].nil? && !ENV["TESTRAIL_PLAN_ID"].nil? && !ENV["TESTRAIL_ENTRY_ID"].nil? && !ENV["TESTRAIL_ENTRY_RUN_ID"].nil?
|
175
|
+
end
|
176
|
+
|
177
|
+
# For pushing results to a single, existing test run in TestRail
|
178
|
+
def is_for_test_rail_run
|
179
|
+
!ENV["TESTRAIL_RUN_ID"].nil? && ENV["TESTRAIL_RUN"].nil? && ENV["TESTRAIL_PLAN_ID"].nil?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.get_total_count
|
184
|
+
@@total_count
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.get_skip_count
|
188
|
+
@@skip_count
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.get_run_count
|
192
|
+
@@run_count
|
193
|
+
end
|
194
|
+
|
195
|
+
# Adds a documentation formatter to the rspec if one is not there already.
|
196
|
+
def self.add_formatter_for(config)
|
197
|
+
# For some reason, adding a custom formatter will remove any other formatters.
|
198
|
+
# Thus during execution nothing gets printed to the screen. Need to add another
|
199
|
+
# formatter to indicate some sort of progress
|
200
|
+
found_doc_formatter = false
|
201
|
+
config.formatters.each do |fm|
|
202
|
+
if (fm.class == RSpec::Core::Formatters::DocumentationFormatter)
|
203
|
+
found_doc_formatter = true
|
204
|
+
break
|
205
|
+
end
|
206
|
+
end
|
207
|
+
unless found_doc_formatter
|
208
|
+
config.add_formatter "doc"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Takes care of filtering out tests that are NOT assigned to the user. So essentially runs only
|
213
|
+
# tests specified in a testrun in testrail, and that are assigned to a particular user.
|
214
|
+
# \config - The Rspec configuration
|
215
|
+
# \user_id - An integer ID corresponding to the testrail user
|
216
|
+
# \test_run_cases - A hash of TestCase instances
|
217
|
+
def self.filter_rspecs_by_test_run_and_user(config, user_id, test_run_cases)
|
218
|
+
config.filter_run_including testrail_id: lambda { |value|
|
219
|
+
# The test id's are strings. Convert them to integers to make comparison easier
|
220
|
+
test_ids = value.collect { |str| str.to_i }
|
221
|
+
# Compute the intersection using the handy &() method
|
222
|
+
intersect = test_run_cases.keys & test_ids
|
223
|
+
assigned_to_ids = []
|
224
|
+
# Do include if the intersection contains a test id
|
225
|
+
if intersect.size > 0
|
226
|
+
test_ids.each do |id|
|
227
|
+
test_case = test_run_cases[id]
|
228
|
+
if test_case.nil?
|
229
|
+
next
|
230
|
+
end
|
231
|
+
assigned_to_ids << test_case.assigned_to
|
232
|
+
end
|
233
|
+
# return true to execute the test if any one of the testcase ID's is assigned to the user
|
234
|
+
do_execute = assigned_to_ids.include? user_id
|
235
|
+
if do_execute
|
236
|
+
puts "Assigned to user. Including testcase ID's: #{value}"
|
237
|
+
else
|
238
|
+
puts "Not assigned to user: Skipping #{value}"
|
239
|
+
end
|
240
|
+
do_execute
|
241
|
+
else
|
242
|
+
false
|
243
|
+
end
|
244
|
+
}
|
245
|
+
end
|
246
|
+
|
247
|
+
# Filters an rspec run by testrail_id's for bridge
|
248
|
+
# Filters an rspec run by testcases found in a particular testrun on testrail.
|
249
|
+
def self.filter_rspecs_by_test_run(config, test_run_cases)
|
250
|
+
# This lambda gets called once for each example
|
251
|
+
# Here value is an array of string test case ID's.
|
252
|
+
config.filter_run_including testrail_id: lambda { |value|
|
253
|
+
@@total_count += 1
|
254
|
+
unless value.is_a? Array
|
255
|
+
@@skip_count += 1
|
256
|
+
puts "ERROR! testcase has invalid testrail ID: #{value}. Value should be an array, got: #{value.class}".red
|
257
|
+
return false
|
258
|
+
end
|
259
|
+
# The test id's are strings. Convert them to integers to make comparison easier
|
260
|
+
test_ids = value.collect { |str| str.to_i }
|
261
|
+
# Compute the intersection using the handy &() method
|
262
|
+
intersect = test_run_cases.keys & test_ids
|
263
|
+
# Do not include if the test cases have already been run and have ALL passed.
|
264
|
+
# (That would be a waste of time to rerun test's that have already passed)
|
265
|
+
pass_count = 0
|
266
|
+
skip_count = 0
|
267
|
+
# Do include if the intersection contains a test id
|
268
|
+
if intersect.size > 0
|
269
|
+
test_ids.each do |id|
|
270
|
+
test_case = test_run_cases[id]
|
271
|
+
if test_case.nil?
|
272
|
+
next
|
273
|
+
end
|
274
|
+
# puts " #{id} temp id: #{test_case.temp_id} Status: #{test_case.status}, "
|
275
|
+
pass_count += 1 if test_case.status == :passed
|
276
|
+
skip_count += 1 if test_case.status == :pending
|
277
|
+
end
|
278
|
+
all_passed = pass_count == test_ids.count
|
279
|
+
all_skipped = skip_count == test_ids.count
|
280
|
+
if all_passed
|
281
|
+
@@skip_count += 1
|
282
|
+
puts "Skipping test case #{value}, because all tests already passed"
|
283
|
+
end
|
284
|
+
if all_skipped
|
285
|
+
@@skip_count += 1
|
286
|
+
puts "Skipping test case #{value}, because all tests marked pending"
|
287
|
+
end
|
288
|
+
do_execute = (pass_count + skip_count) != test_ids.count
|
289
|
+
@@run_count += 1 if do_execute
|
290
|
+
do_execute
|
291
|
+
else
|
292
|
+
@@skip_count += 1
|
293
|
+
false
|
294
|
+
end
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
298
|
+
# Filters an rspec run by test_id's for canvas.
|
299
|
+
# This is used for filtering out test cases that have already been run previously, say on a previous
|
300
|
+
# test run that was aborted early and restarted.
|
301
|
+
# In this case we skip tests that already passed or were marked as pending (rspec for skipped)
|
302
|
+
def self.filter_rspecs_by_testid(config, test_run_cases)
|
303
|
+
# This lambda gets called once for each example
|
304
|
+
# Here value is an array of string test case ID's.
|
305
|
+
config.filter_run_including test_id: lambda { |id|
|
306
|
+
@@total_count += 1
|
307
|
+
id = id.to_i
|
308
|
+
# The test id's are integers, and in canvas there is only one ID per test case, NOT an array like Bridge
|
309
|
+
in_run = test_run_cases.keys.include?( id )
|
310
|
+
|
311
|
+
# Do include if the intersection contains a test id
|
312
|
+
if in_run
|
313
|
+
test_case = test_run_cases[id]
|
314
|
+
|
315
|
+
if (test_case.status == :passed)
|
316
|
+
@@skip_count += 1
|
317
|
+
puts "Skipping test case #{id}, because it has already passed"
|
318
|
+
return false
|
319
|
+
end
|
320
|
+
|
321
|
+
if (test_case.status == :pending)
|
322
|
+
@@skip_count += 1
|
323
|
+
puts "Skipping test case #{id}, because it is marked pending"
|
324
|
+
return false
|
325
|
+
end
|
326
|
+
|
327
|
+
@@run_count += 1
|
328
|
+
return true # do execute this test
|
329
|
+
else
|
330
|
+
@@skip_count += 1
|
331
|
+
puts "Skipping test case #{id}, because it was not in test_run_cases"
|
332
|
+
return false
|
333
|
+
end
|
334
|
+
}
|
335
|
+
end
|
336
|
+
|
337
|
+
# The param is an RSPEC config
|
338
|
+
# The second param is a symbol for which product to hook into
|
339
|
+
def self.register_rspec_integration(config, product, add_formatter: true)
|
340
|
+
# Runs test cases as found in a test run on testrail
|
341
|
+
|
342
|
+
# This will select test examples to run based off of what test rail defines, not what
|
343
|
+
# the file pattern on the command line defines.
|
344
|
+
# That is, this will take a test run (int test rail), and run all the cases defined in it.
|
345
|
+
|
346
|
+
# First clear any filters passed in from the command line
|
347
|
+
config.inclusion_filter = nil
|
348
|
+
test_run_cases = TestRailOperations.get_test_run_cases(ENV["TESTRAIL_RUN_ID"].to_i)
|
349
|
+
|
350
|
+
user_id = nil
|
351
|
+
unless ENV["TESTRAIL_ASSIGNED_TO"].nil?
|
352
|
+
user_json = TestRailOperations.get_test_rail_user_by_email(ENV["TESTRAIL_ASSIGNED_TO"])
|
353
|
+
user_id = user_json["id"]
|
354
|
+
puts "Testrail assigned to: #{user_json}"
|
355
|
+
end
|
356
|
+
|
357
|
+
if user_id
|
358
|
+
TestRailRSpecIntegration.filter_rspecs_by_test_run_and_user(config, user_id, test_run_cases)
|
359
|
+
else
|
360
|
+
case(product)
|
361
|
+
when :bridge
|
362
|
+
TestRailRSpecIntegration.filter_rspecs_by_test_run(config, test_run_cases)
|
363
|
+
when :canvas
|
364
|
+
TestRailRSpecIntegration.filter_rspecs_by_testid(config, test_run_cases)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
config.add_formatter TestRailRSpecIntegration::TestRailPlanFormatter
|
369
|
+
TestRailRSpecIntegration::TestRailPlanFormatter.set_product(product)
|
370
|
+
if add_formatter
|
371
|
+
TestRailRSpecIntegration.add_formatter_for(config)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# Registers a callback custom formatter to an rspec. The new test run is created from
|
376
|
+
# the results of the tests. This is in effect the opposite of the method above
|
377
|
+
# (register_rspec_integration).
|
378
|
+
def self.add_rspec_callback(config, product, add_formatter: true)
|
379
|
+
config.add_formatter TestRailRSpecIntegration::TestRailPlanFormatter
|
380
|
+
TestRailRSpecIntegration::TestRailPlanFormatter.set_product(product)
|
381
|
+
if add_formatter
|
382
|
+
TestRailRSpecIntegration.add_formatter_for(config)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'files/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "testrailtagging"
|
8
|
+
spec.version = Testrailtagging::VERSION
|
9
|
+
spec.authors = ["Chris Johnson"]
|
10
|
+
spec.email = ["cjohnson@instructure.com"]
|
11
|
+
|
12
|
+
spec.summary = "Utilities for working with testrail."
|
13
|
+
spec.description = "Contains code for pushing rspec results up to testrail."
|
14
|
+
spec.homepage = "https://github.com/instructure/testrailtagging"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
|
25
|
+
spec.add_dependency 'testrail_client'
|
26
|
+
spec.add_dependency 'parser'
|
27
|
+
spec.add_dependency 'rspec'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: testrailtagging
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.6.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Johnson
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: testrail_client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: parser
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Contains code for pushing rspec results up to testrail.
|
84
|
+
email:
|
85
|
+
- cjohnson@instructure.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- CODE_OF_CONDUCT.md
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/console
|
97
|
+
- bin/setup
|
98
|
+
- lib/files/RSpecParser.rb
|
99
|
+
- lib/files/TestCase.rb
|
100
|
+
- lib/files/testcase_modifications.rb
|
101
|
+
- lib/files/testrail_apiclient_retry.rb
|
102
|
+
- lib/files/testrail_operations.rb
|
103
|
+
- lib/files/testrail_queries.rb
|
104
|
+
- lib/files/testrail_rspec_integration.rb
|
105
|
+
- lib/files/version.rb
|
106
|
+
- lib/testrailtagging.rb
|
107
|
+
- testrailtagging.gemspec
|
108
|
+
homepage: https://github.com/instructure/testrailtagging
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.4.5
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Utilities for working with testrail.
|
132
|
+
test_files: []
|
133
|
+
has_rdoc:
|