testrailtagging 0.3.6.8
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|