diff --git a/ginkgo_t_dsl.go b/ginkgo_t_dsl.go index 17073145f..28447ffdd 100644 --- a/ginkgo_t_dsl.go +++ b/ginkgo_t_dsl.go @@ -80,6 +80,9 @@ type FullGinkgoTInterface interface { Fi(indentation uint, format string, args ...any) string Fiw(indentation uint, maxWidth uint, format string, args ...any) string + //Generates a formatted string version of the current spec's timeline + RenderTimeline() string + GinkgoRecover() DeferCleanup(args ...any) diff --git a/internal/testingtproxy/testing_t_proxy.go b/internal/testingtproxy/testing_t_proxy.go index 92acc0a00..73e265565 100644 --- a/internal/testingtproxy/testing_t_proxy.go +++ b/internal/testingtproxy/testing_t_proxy.go @@ -7,6 +7,7 @@ import ( "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/internal" + "github.com/onsi/ginkgo/v2/reporters" "github.com/onsi/ginkgo/v2/types" ) @@ -185,6 +186,9 @@ func (t *ginkgoTestingTProxy) Fi(indentation uint, format string, args ...any) s func (t *ginkgoTestingTProxy) Fiw(indentation uint, maxWidth uint, format string, args ...any) string { return t.f.Fiw(indentation, maxWidth, format, args...) } +func (t *ginkgoTestingTProxy) RenderTimeline() string { + return reporters.RenderTimeline(t.report(), false) +} func (t *ginkgoTestingTProxy) GinkgoRecover() { t.ginkgoRecover() } diff --git a/internal/testingtproxy/testingtproxy_test.go b/internal/testingtproxy/testingtproxy_test.go index 35dbe497e..22a3e9242 100644 --- a/internal/testingtproxy/testingtproxy_test.go +++ b/internal/testingtproxy/testingtproxy_test.go @@ -3,6 +3,7 @@ package testingtproxy_test import ( "os" "runtime" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -301,18 +302,47 @@ var _ = Describe("Testingtproxy", func() { Ω(string(buf.Contents())).Should(Equal(" hi 3\n")) }) - It("can provides a correctly configured Ginkgo Formatter", func() { + It("can provide a correctly configured Ginkgo Formatter", func() { Ω(t.F("{{blue}}%d{{/}}", 3)).Should(Equal("3")) }) - It("can printf to the GinkgoWriter", func() { + It("can provide a correctly configured Ginkgo Formatter, with indentation", func() { Ω(t.Fi(1, "{{blue}}%d{{/}}", 3)).Should(Equal(" 3")) }) - It("can println to the GinkgoWriter", func() { + It("can provide a correctly configured Ginkgo Formatter, with indentation and width constraints", func() { Ω(t.Fiw(1, 5, "{{blue}}%d{{/}} a number", 3)).Should(Equal(" 3 a\n number")) }) + It("can render the timeline of the current spec", func() { + cl := types.NewCustomCodeLocation("cl") + reportToReturn.CapturedGinkgoWriterOutput = "ABCDEFGHIJKLMNOP" + reportToReturn.SpecEvents = append(reportToReturn.SpecEvents, types.SpecEvent{ + TimelineLocation: types.TimelineLocation{Offset: 5, Order: 1}, + SpecEventType: types.SpecEventNodeStart, + Message: "The Test", + CodeLocation: cl, + NodeType: types.NodeTypeIt, + }) + reportToReturn.SpecEvents = append(reportToReturn.SpecEvents, types.SpecEvent{ + TimelineLocation: types.TimelineLocation{Offset: 10, Order: 3}, + SpecEventType: types.SpecEventNodeEnd, + Message: "The Test", + CodeLocation: cl, + NodeType: types.NodeTypeIt, + Duration: time.Second, + }) + reportToReturn.State = types.SpecStateFailed + reportToReturn.Failure = types.Failure{ + Message: "The Failure", + FailureNodeType: types.NodeTypeIt, + Location: cl, + TimelineLocation: types.TimelineLocation{Offset: 10, Order: 2}, + } + + Ω(t.RenderTimeline()).Should(Equal("ABCDE\n> Enter \x1b[1m[It]\x1b[0m The Test \x1b[38;5;243m- cl @ 01/01/01 00:00:00\x1b[0m\nFGHIJ\n\x1b[38;5;9m[FAILED] The Failure\x1b[0m\n\x1b[38;5;9mIn \x1b[1m[It]\x1b[0m\x1b[38;5;9m at: \x1b[1mcl\x1b[0m \x1b[38;5;243m@ 01/01/01 00:00:00\x1b[0m\n< Exit \x1b[1m[It]\x1b[0m The Test \x1b[38;5;243m- cl @ 01/01/01 00:00:00 (1s)\x1b[0m\nKLMNOP")) + }) + It("can provide GinkgoRecover", func() { Ω(recoverCall).Should(BeFalse()) t.GinkgoRecover() diff --git a/reporters/junit_report.go b/reporters/junit_report.go index ca98609d0..592d7f614 100644 --- a/reporters/junit_report.go +++ b/reporters/junit_report.go @@ -344,8 +344,12 @@ func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string { } func systemErrForUnstructuredReporters(spec types.SpecReport) string { + return RenderTimeline(spec, true) +} + +func RenderTimeline(spec types.SpecReport, noColor bool) string { out := &strings.Builder{} - NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline()) + NewDefaultReporter(types.ReporterConfig{NoColor: noColor, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline()) return out.String() }