rspec_trunk_flaky_tests 0.14.0-aarch64-linux-gnu

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 33b80ec00e07e5bd2af8a60f3e7a06016425367b53b3c3677310c593b9836ddf
4
+ data.tar.gz: fd7d07d27996a6d241bfbb9dc979bcd9ec11156b4a2d8c911a7ea3b6af7136ce
5
+ SHA512:
6
+ metadata.gz: 9cb2b4a83fc9502d8b78b26e93444ee5974c7c806a51f978fb3a9f2931b8740c77d6cecfb4418bc92bcdae9b7045acf47417ec2c9437a420e1edfbd6a0d4e25b
7
+ data.tar.gz: d19eb3f553df531a0e6d78e7bf4f3d73865fe707a6ea611f7a55d3ce9d5a7d98074a8521b809e75cddd0591915b634ae855bc6afae04ebf0c3050229ac6ba15f
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
5
+ require_relative "rspec_trunk_flaky_tests/#{ruby_version}/rspec_trunk_flaky_tests"
6
+ rescue LoadError
7
+ begin
8
+ require_relative 'rspec_trunk_flaky_tests/rspec_trunk_flaky_tests'
9
+ rescue LoadError
10
+ raise LoadError, <<~MSG
11
+ Could not load the native extension for rspec_trunk_flaky_tests.
12
+
13
+ You are using the pure ruby variant of this gem, which is a placeholder
14
+ that exists so that Gemfile.lock files with `PLATFORMS ruby` can resolve
15
+ this dependency. It does not include a precompiled native extension.
16
+
17
+ Precompiled native gems are available for:
18
+ x86_64-linux-gnu, x86_64-linux-musl, aarch64-linux-gnu,
19
+ aarch64-linux-musl, arm64-darwin, x86_64-darwin
20
+
21
+ If you are on a supported platform and seeing this error, make sure
22
+ bundler is selecting the native variant for your platform:
23
+
24
+ bundle lock --add-platform #{RUBY_PLATFORM}
25
+ bundle install
26
+
27
+ If you are on an unsupported platform, this gem cannot be used in your
28
+ environment. Please open an issue at:
29
+ https://github.com/trunk-io/analytics-cli/issues
30
+
31
+ Current platform: #{RUBY_PLATFORM}
32
+ Current Ruby version: #{RUBY_VERSION}
33
+ MSG
34
+ end
35
+ end
@@ -0,0 +1,443 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Trunk RSpec Helper
4
+ #
5
+ # This helper integrates Trunk Flaky Tests with RSpec to automatically
6
+ # quarantine flaky tests and upload test results.
7
+ #
8
+ # Required environment variables:
9
+ # TRUNK_ORG_URL_SLUG - Your organization's URL slug
10
+ # TRUNK_API_TOKEN - Your API token for authentication
11
+ #
12
+ # Optional environment variables for repository metadata:
13
+ # TRUNK_REPO_ROOT - Path to repository root
14
+ # TRUNK_REPO_URL - Repository URL (e.g., https://github.com/org/repo.git)
15
+ # TRUNK_REPO_HEAD_SHA - HEAD commit SHA
16
+ # TRUNK_REPO_HEAD_BRANCH - HEAD branch name
17
+ # TRUNK_REPO_HEAD_COMMIT_EPOCH - HEAD commit timestamp (seconds since epoch)
18
+ # TRUNK_REPO_HEAD_AUTHOR_NAME - HEAD commit author name
19
+ # TRUNK_PR_NUMBER - PR number, if uploading from a PR (normally inferred from CI environment variables)
20
+ #
21
+ # Optional environment variables for configuration:
22
+ # TRUNK_CODEOWNERS_PATH - Path to CODEOWNERS file
23
+ # TRUNK_TEST_COLLECTION_ID - Optional 8 character alphanumeric ID for a test collection
24
+ # TRUNK_VARIANT - Variant name for test results (e.g., 'linux', 'pr-123')
25
+ # TRUNK_DISABLE_QUARANTINING - Set to 'true' to disable quarantining
26
+ # TRUNK_ALLOW_EMPTY_TEST_RESULTS - Set to 'true' to allow empty results
27
+ # TRUNK_DRY_RUN - Set to 'true' to save bundle locally instead of uploading
28
+ # TRUNK_USE_UNCLONED_REPO - Set to 'true' for uncloned repo mode
29
+ # TRUNK_LOCAL_UPLOAD_DIR - Directory to save test results locally (disables upload)
30
+ # TRUNK_QUARANTINED_TESTS_DISK_CACHE_TTL_SECS - Time to cache quarantined tests on disk (in seconds)
31
+ # TRUNK_QUARANTINE_QUERY_FAILURE_EXIT - Set to 'true' to abort the RSpec run when quarantine
32
+ # lookup fails (remaining examples are skipped)
33
+ # DISABLE_RSPEC_TRUNK_FLAKY_TESTS - Set to 'true' to completely disable Trunk
34
+ #
35
+ require 'rspec/core'
36
+ require 'rspec/core/formatters/exception_presenter'
37
+ require 'time'
38
+ require 'rspec_trunk_flaky_tests'
39
+
40
+ # trunk-ignore-all(rubocop/Style/GlobalVars)
41
+
42
+ # String is an override to the main String class that is used to colorize the output
43
+ # it is used to make the output more readable
44
+ class String
45
+ def colorize(color_code)
46
+ "\e[#{color_code}m#{self}\e[0m"
47
+ end
48
+
49
+ def red
50
+ colorize(31)
51
+ end
52
+
53
+ def green
54
+ colorize(32)
55
+ end
56
+
57
+ def yellow
58
+ colorize(33)
59
+ end
60
+ end
61
+
62
+ ANSI_ESCAPE_PATTERN = %r{(?:\e[@-Z\\-_]|\e\[[0-?]*[ -/]*[@-~])}
63
+
64
+ def escape(str)
65
+ str.dump[1..-2]
66
+ end
67
+
68
+ def strip_ansi_codes(text)
69
+ text.to_s.gsub(ANSI_ESCAPE_PATTERN, '')
70
+ end
71
+
72
+ # Knapsack example detector instantiates all test cases in order to determine how to shard them
73
+ # These instantiations should not generate test bundles, so we
74
+ # disable the gem when running under knapsack_pro:rspec_test_example_detector
75
+ def knapsack_detector_mode?
76
+ knapsack_detector_command?
77
+ end
78
+
79
+ def knapsack_detector_command?
80
+ command_line = "#{$PROGRAM_NAME} #{ARGV.join(' ')}".strip
81
+ command_line.include?('knapsack_pro:rspec_test_example_detector') ||
82
+ command_line.include?('knapsack_pro:queue:rspec:initialize')
83
+ end
84
+
85
+ def trunk_disabled
86
+ knapsack_detector_mode? || ENV['DISABLE_RSPEC_TRUNK_FLAKY_TESTS'] == 'true' ||
87
+ ENV['TRUNK_ORG_URL_SLUG'].nil? || ENV['TRUNK_API_TOKEN'].nil?
88
+ end
89
+
90
+ def quarantine_query_failure_exit?
91
+ ENV['TRUNK_QUARANTINE_QUERY_FAILURE_EXIT'] == 'true'
92
+ end
93
+
94
+ # we want to cache the test report in memory so we can add to it as we go and reduce the number of API calls
95
+ $test_report = TestReport.new('rspec', "#{$PROGRAM_NAME} #{ARGV.join(' ')}", nil)
96
+ $failure_encountered_and_quarantining_disabled = false
97
+ $failure_encountered_and_quarantine_lookup_failed = false
98
+
99
+ module RSpec
100
+ module Core
101
+ # Example is the class that represents a test case
102
+ class Example
103
+ # keep the original method around so we can call it
104
+ alias set_exception_core set_exception
105
+ alias assign_generated_description_core assign_generated_description
106
+ # RSpec uses the existance of an exception to determine if the test failed
107
+ # We need to override this to allow us to capture the exception and then
108
+ # decide if we want to fail the test or not
109
+ # trunk-ignore(rubocop/Naming/AccessorMethodName)
110
+ def set_exception(exception)
111
+ # Pending stays green, except a fixed pending example is a real failure.
112
+ return set_exception_core(exception) if metadata[:pending] && !pending_example_fixed?(exception)
113
+ return set_exception_core(exception) if trunk_disabled
114
+ return set_exception_core(exception) if metadata[:retry_attempts]&.positive?
115
+
116
+ handle_quarantine_check_safely(exception)
117
+ end
118
+
119
+ # If the quarantine machinery itself blows up, the failure must stand.
120
+ def handle_quarantine_check_safely(exception)
121
+ handle_quarantine_check(exception)
122
+ rescue StandardError => e
123
+ puts "Quarantine check errored (#{e.class}: #{e.message}), treating test as not quarantined".yellow
124
+ set_exception_core(exception)
125
+ end
126
+
127
+ def pending_example_fixed?(exception)
128
+ defined?(RSpec::Core::Pending::PendingExampleFixedError) &&
129
+ exception.is_a?(RSpec::Core::Pending::PendingExampleFixedError)
130
+ end
131
+
132
+ # trunk-ignore(rubocop/Metrics/AbcSize,rubocop/Metrics/MethodLength,rubocop/Metrics/CyclomaticComplexity)
133
+ def handle_quarantine_check(exception)
134
+ id = generate_trunk_id
135
+ name = full_description
136
+ parent_name = example_group.metadata[:description]
137
+ parent_name = parent_name.empty? ? 'rspec' : parent_name
138
+ file = escape(metadata[:file_path])
139
+ classname = file.sub(%r{\.[^/.]+\Z}, '').gsub('/', '.').gsub(/\A\.+|\.+\Z/, '')
140
+ unless $failure_encountered_and_quarantining_disabled
141
+ puts "Test failed, checking if it can be quarantined: `#{location}`".yellow
142
+ end
143
+ is_quarantined_result = $test_report.is_quarantined(id, name, parent_name, classname, file)
144
+
145
+ if is_quarantined_result.quarantine_lookup_failed
146
+ unless $failure_encountered_and_quarantine_lookup_failed
147
+ puts 'Failed to check quarantining status, no failures will be quarantined'.yellow
148
+ $failure_encountered_and_quarantine_lookup_failed = true
149
+ end
150
+ if quarantine_query_failure_exit?
151
+ puts 'Quarantine lookup failed, exiting early'.red
152
+ RSpec.world.wants_to_quit = true
153
+ end
154
+ set_exception_core(exception)
155
+ elsif is_quarantined_result.quarantining_disabled_for_repo
156
+ unless $failure_encountered_and_quarantining_disabled
157
+ puts 'Quarantining is disabled for this repo, no failures will be quarantined'.yellow
158
+ $failure_encountered_and_quarantining_disabled = true
159
+ end
160
+ set_exception_core(exception)
161
+ elsif is_quarantined_result.test_is_quarantined
162
+ # monitor the override in the metadata
163
+ metadata[:quarantined_exception] = exception
164
+ puts "Test is quarantined, overriding exception: #{exception}".green
165
+ nil
166
+ else
167
+ puts 'Test is not quarantined, continuing'.red
168
+ set_exception_core(exception)
169
+ end
170
+ end
171
+
172
+ def assign_generated_description
173
+ metadata[:is_description_generated] = description_generated?
174
+ assign_generated_description_core
175
+ end
176
+
177
+ def description_generated?
178
+ return metadata[:is_description_generated] unless metadata[:is_description_generated].nil?
179
+
180
+ description == location_description
181
+ end
182
+
183
+ def generate_trunk_id
184
+ return "trunk:#{id}-#{location}" if description_generated?
185
+ end
186
+
187
+ # Procsy is a class that is used to wrap execution of the Example class
188
+ class Procsy
189
+ def run_with_trunk
190
+ RSpec::Trunk.new(self).run
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ module RSpec
198
+ # Trunk is a class that is used to monitor the execution of the Example class
199
+ class Trunk
200
+ def self.setup
201
+ RSpec.configure do |config|
202
+ if trunk_disabled
203
+ config.around(:each, &:run)
204
+ else
205
+ config.around(:each, &:run_with_trunk)
206
+ end
207
+ end
208
+ end
209
+
210
+ def initialize(example)
211
+ @example = example
212
+ end
213
+
214
+ def current_example
215
+ @current_example ||= RSpec.current_example
216
+ end
217
+
218
+ def run
219
+ # run the test
220
+ @example.run
221
+ # monitor attempts in the metadata
222
+ if @example.metadata[:attempt_number]
223
+ @example.metadata[:attempt_number] += 1
224
+ else
225
+ @example.metadata[:attempt_number] = 0
226
+ end
227
+ end
228
+ end
229
+ end
230
+
231
+ # PlainColorizer is a no-op colorizer passed to RSpec's ExceptionPresenter so the
232
+ # formatted output is plain text suitable for storage and the web UI.
233
+ module PlainColorizer
234
+ module_function
235
+
236
+ def wrap(text, _code_or_symbol)
237
+ text
238
+ end
239
+ end
240
+
241
+ # Defer to RSpec's own ExceptionPresenter so the failure_message field matches
242
+ # what users see in their RSpec console output (Failure/Error: <source line>,
243
+ # the exception class and message, and any "Caused by:" chain).
244
+ def format_exception_message(exception, example)
245
+ return '' unless exception
246
+
247
+ presenter = RSpec::Core::Formatters::ExceptionPresenter.new(exception, example)
248
+ strip_ansi_codes(presenter.fully_formatted(nil, PlainColorizer))
249
+ rescue StandardError
250
+ legacy_format_exception_message(exception)
251
+ end
252
+
253
+ # trunk-ignore(rubocop/Metrics/MethodLength,rubocop/Metrics/AbcSize)
254
+ def format_exception_backtrace(exception, example)
255
+ return '' unless exception
256
+
257
+ lines = exception_backtrace_lines(exception, example)
258
+
259
+ cause = exception.cause
260
+ depth = 0
261
+ while cause && depth < 10
262
+ lines << ''
263
+ lines << "Caused by: #{cause.class}: #{cause.message}"
264
+ lines.concat(exception_backtrace_lines(cause, example))
265
+ cause = cause.cause
266
+ depth += 1
267
+ end
268
+
269
+ result = lines.join("\n")
270
+ # The exception presenter may choke on MultipleExceptionError, such as errors in before
271
+ # and after hooks, so we fall back to the legacy formatter
272
+ return legacy_format_exception_backtrace(exception) if result.strip.empty?
273
+
274
+ strip_ansi_codes(result)
275
+ rescue StandardError
276
+ legacy_format_exception_backtrace(exception)
277
+ end
278
+
279
+ def exception_backtrace_lines(exception, example)
280
+ presenter = RSpec::Core::Formatters::ExceptionPresenter.new(exception, example)
281
+ Array(presenter.formatted_backtrace)
282
+ rescue StandardError
283
+ Array(exception.backtrace)
284
+ end
285
+
286
+ def legacy_format_exception_message(exception)
287
+ case exception
288
+ when RSpec::Core::MultipleExceptionError
289
+ messages = exception.all_exceptions.map { |e| "#{e.class}: #{e.message}" }
290
+ strip_ansi_codes("#{exception.class}: #{messages.join(' | ')}")
291
+ else
292
+ strip_ansi_codes(exception.to_s)
293
+ end
294
+ end
295
+
296
+ # trunk-ignore(rubocop/Metrics/MethodLength,rubocop/Metrics/AbcSize)
297
+ def legacy_format_exception_backtrace(exception)
298
+ case exception
299
+ when RSpec::Core::MultipleExceptionError
300
+ strip_ansi_codes(exception.all_exceptions.map do |e|
301
+ if e.backtrace && !e.backtrace.empty?
302
+ "#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
303
+ else
304
+ "#{e.class}: #{e.message}"
305
+ end
306
+ end.join("\n\n"))
307
+ else
308
+ strip_ansi_codes(exception.backtrace&.join("\n") || '')
309
+ end
310
+ end
311
+
312
+ # TrunkAnalyticsListener is a class that is used to listen to the execution of the Example class
313
+ # it generates and submits the final test reports
314
+ class TrunkAnalyticsListener
315
+ MAX_TEXT_FIELD_SIZE = 8_000
316
+
317
+ def initialize
318
+ @testreport = $test_report
319
+ end
320
+
321
+ def example_finished(notification)
322
+ add_test_case(notification.example)
323
+ end
324
+
325
+ # trunk-ignore(rubocop/Metrics/MethodLength,rubocop/Metrics/AbcSize)
326
+ def close(_notification)
327
+ if $failure_encountered_and_quarantining_disabled
328
+ puts 'Note: Quarantining is disabled for this repo. Test failures were not quarantined.'.yellow
329
+ end
330
+ if $failure_encountered_and_quarantine_lookup_failed
331
+ puts 'Note: Failed to check quarantining status. Test failures were not quarantined.'.yellow
332
+ end
333
+
334
+ if ENV['TRUNK_LOCAL_UPLOAD_DIR']
335
+ saved = @testreport.try_save(ENV['TRUNK_LOCAL_UPLOAD_DIR'])
336
+ if saved
337
+ puts 'Local Flaky tests report generated'.green
338
+ else
339
+ puts 'Failed to generate local flaky tests report'.red
340
+ end
341
+ else
342
+ published = @testreport.publish
343
+ if published
344
+ puts 'Flaky tests report upload complete'.green
345
+ else
346
+ puts 'Failed to publish flaky tests report'.red
347
+ end
348
+ end
349
+ end
350
+
351
+ # trunk-ignore(rubocop/Metrics/CyclomaticComplexity,rubocop/Metrics/AbcSize,rubocop/Metrics/MethodLength)
352
+ def add_test_case(example)
353
+ status, exception = status_and_exception(example)
354
+ failure_message = ''
355
+ backtrace = ''
356
+ if exception
357
+ failure_message = format_exception_message(exception, example).strip
358
+ backtrace = format_exception_backtrace(exception, example).strip
359
+ end
360
+ failure_message = failure_message[0...MAX_TEXT_FIELD_SIZE] if failure_message.length > MAX_TEXT_FIELD_SIZE
361
+ backtrace = backtrace[0...MAX_TEXT_FIELD_SIZE] if backtrace.length > MAX_TEXT_FIELD_SIZE
362
+ # TODO: should we use concatenated string or alias when auto-generated description?
363
+ name = example.full_description
364
+ file = escape(example.metadata[:file_path])
365
+ classname = file.sub(%r{\.[^/.]+\Z}, '').gsub('/', '.').gsub(/\A\.+|\.+\Z/, '')
366
+ line = example.metadata[:line_number]
367
+ started_at = example.execution_result.started_at.to_i
368
+ finished_at = example.execution_result.finished_at.to_i
369
+ id = example.generate_trunk_id
370
+
371
+ attempt_number = example.metadata[:retry_attempts] || example.metadata[:attempt_number] || 0
372
+ # set the status to failure, but mark it as quarantined
373
+ is_quarantined = example.metadata[:quarantined_exception] ? true : false
374
+ parent_name = example.example_group.metadata[:description]
375
+ parent_name = parent_name.empty? ? 'rspec' : parent_name
376
+ @testreport.add_test(id, name, classname, file, parent_name, line, status, attempt_number,
377
+ started_at, finished_at, failure_message || '', backtrace || '', is_quarantined)
378
+ end
379
+
380
+ # Determine the Trunk status to report for an example, plus the exception (if
381
+ # any) whose message/backtrace should be recorded for it.
382
+ #
383
+ # `pending` examples need care because RSpec expresses their outcome as the
384
+ # inverse of the body's pass/fail. A pending example's contract is "this is
385
+ # expected to fail", so:
386
+ # - body still fails -> expectation met -> RSpec status :pending, build green
387
+ # - body now passes -> expectation violated -> RSpec status :failed
388
+ # (PendingExampleFixedError), build red
389
+ # We report the outcome RSpec actually decided, which also matches the build
390
+ # result:
391
+ # - skip / xit (never ran) -> skipped
392
+ # - pending, body still failing -> success (expectation met)
393
+ # - pending, body now passing -> failure (PendingExampleFixedError)
394
+ # RSpec's own build pass/fail behavior is left untouched (see #set_exception).
395
+ #
396
+ # trunk-ignore(rubocop/Metrics/AbcSize,rubocop/Metrics/CyclomaticComplexity,rubocop/Metrics/MethodLength)
397
+ def status_and_exception(example)
398
+ result = example.execution_result
399
+ quarantined_exception = example.metadata[:quarantined_exception]
400
+
401
+ # A genuinely skipped example (`skip`/`xit`, or `skip` called from a hook or
402
+ # body) never runs, so it has no real pass/fail outcome. RSpec still reports
403
+ # it with status :pending, so detect skips explicitly -- and up front -- via
404
+ # metadata[:skip] before interpreting any pending pass/fail semantics below.
405
+ return [Status.new('skipped'), nil] if example.metadata[:skip]
406
+
407
+ case result.status
408
+ when :passed
409
+ # A quarantined failure is recorded as :passed by RSpec (see #set_exception),
410
+ # so report it as a failure but carry the original quarantined exception.
411
+ quarantined_exception ? [Status.new('failure'), quarantined_exception] : [Status.new('success'), nil]
412
+ when :failed
413
+ # Includes a pending example whose body unexpectedly passed: RSpec reports it
414
+ # as :failed with a PendingExampleFixedError (on example.exception) and breaks
415
+ # the build (the pending expectation was violated), so it is a failure here too.
416
+ [Status.new('failure'), example.exception || quarantined_exception]
417
+ when :pending
418
+ # A quarantined fixed-pending is left :pending but pending_fixed? -- still a
419
+ # failure. Otherwise the pending "should fail" expectation was met -> success.
420
+ if result.pending_fixed?
421
+ [Status.new('failure'), quarantined_exception || example.exception]
422
+ else
423
+ [Status.new('success'), nil]
424
+ end
425
+ else
426
+ [Status.new(result.status.to_s), example.exception || quarantined_exception]
427
+ end
428
+ end
429
+ end
430
+
431
+ RSpec.configure do |c|
432
+ next if trunk_disabled
433
+
434
+ c.before(:example) do
435
+ if $failure_encountered_and_quarantine_lookup_failed && quarantine_query_failure_exit?
436
+ skip('Quarantine lookup failed, skipping test run')
437
+ end
438
+ end
439
+
440
+ c.reporter.register_listener TrunkAnalyticsListener.new, :example_finished, :close
441
+ end
442
+
443
+ RSpec::Trunk.setup
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec_trunk_flaky_tests
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.14.0
5
+ platform: aarch64-linux-gnu
6
+ authors:
7
+ - Trunk Technologies, Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Integrates RSpec with Trunk Flaky Tests to automatically upload test
42
+ results from your CI jobs. Enables accurate flaky test detection, quarantining,
43
+ and analytics.
44
+ email: support@trunk.io
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - lib/rspec_trunk_flaky_tests.rb
50
+ - lib/rspec_trunk_flaky_tests/3.1/rspec_trunk_flaky_tests.so
51
+ - lib/rspec_trunk_flaky_tests/3.2/rspec_trunk_flaky_tests.so
52
+ - lib/rspec_trunk_flaky_tests/3.3/rspec_trunk_flaky_tests.so
53
+ - lib/rspec_trunk_flaky_tests/3.4/rspec_trunk_flaky_tests.so
54
+ - lib/rspec_trunk_flaky_tests/4.0/rspec_trunk_flaky_tests.so
55
+ - lib/trunk_spec_helper.rb
56
+ homepage: https://docs.trunk.io/flaky-tests/get-started/frameworks/rspec
57
+ licenses:
58
+ - MIT
59
+ metadata:
60
+ source_code_uri: https://github.com/trunk-io/analytics-cli/tree/main/rspec-trunk-flaky-tests
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.1'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: 4.1.dev
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 3.3.22
78
+ requirements: []
79
+ rubygems_version: 3.5.23
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: RSpec plugin for Trunk Flaky Tests - automatically uploads test results to
83
+ detect and quarantine flaky tests
84
+ test_files: []