How to use emitBlock method of reporters Package

Best Ginkgo code snippet using reporters.emitBlock

Run Ginkgo automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

default_reporter.go

Source: default_reporter.go Github

copy
1/*
2Ginkgo's Default Reporter
3
4A number of command line flags are available to tweak Ginkgo's default output.
5
6These are documented [here](http://onsi.github.io/ginkgo/#running_tests)
7*/
8package reporters
9
10import (
11	"fmt"
12	"io"
13	"runtime"
14	"strings"
15
16	"github.com/onsi/ginkgo/v2/formatter"
17	"github.com/onsi/ginkgo/v2/types"
18)
19
20type DefaultReporter struct {
21	conf   types.ReporterConfig
22	writer io.Writer
23
24	// managing the emission stream
25	lastChar                 string
26	lastEmissionWasDelimiter bool
27
28	// rendering
29	specDenoter  string
30	retryDenoter string
31	formatter    formatter.Formatter
32}
33
34func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {
35	reporter := NewDefaultReporter(conf, writer)
36	reporter.formatter = formatter.New(formatter.ColorModePassthrough)
37
38	return reporter
39}
40
41func NewDefaultReporter(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {
42	reporter := &DefaultReporter{
43		conf:   conf,
44		writer: writer,
45
46		lastChar:                 "\n",
47		lastEmissionWasDelimiter: false,
48
49		specDenoter:  "•",
50		retryDenoter: "↺",
51		formatter:    formatter.NewWithNoColorBool(conf.NoColor),
52	}
53	if runtime.GOOS == "windows" {
54		reporter.specDenoter = "+"
55		reporter.retryDenoter = "R"
56	}
57
58	return reporter
59}
60
61/* The Reporter Interface */
62
63func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
64	if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) {
65		r.emit(r.f("[%d] {{bold}}%s{{/}} ", report.SuiteConfig.RandomSeed, report.SuiteDescription))
66		if len(report.SuiteLabels) > 0 {
67			r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteLabels, ", ")))
68		}
69		r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))
70		if report.SuiteConfig.ParallelTotal > 1 {
71			r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal))
72		}
73	} else {
74		banner := r.f("Running Suite: %s - %s", report.SuiteDescription, report.SuitePath)
75		r.emitBlock(banner)
76		bannerWidth := len(banner)
77		if len(report.SuiteLabels) > 0 {
78			labels := strings.Join(report.SuiteLabels, ", ")
79			r.emitBlock(r.f("{{coral}}[%s]{{/}} ", labels))
80			if len(labels)+2 > bannerWidth {
81				bannerWidth = len(labels) + 2
82			}
83		}
84		r.emitBlock(strings.Repeat("=", bannerWidth))
85
86		out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed)
87		if report.SuiteConfig.RandomizeAllSpecs {
88			out += r.f(" - will randomize all specs")
89		}
90		r.emitBlock(out)
91		r.emit("\n")
92		r.emitBlock(r.f("Will run {{bold}}%d{{/}} of {{bold}}%d{{/}} specs", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))
93		if report.SuiteConfig.ParallelTotal > 1 {
94			r.emitBlock(r.f("Running in parallel across {{bold}}%d{{/}} processes", report.SuiteConfig.ParallelTotal))
95		}
96	}
97}
98
99func (r *DefaultReporter) WillRun(report types.SpecReport) {
100	if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) {
101		return
102	}
103
104	r.emitDelimiter()
105	indentation := uint(0)
106	if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
107		r.emitBlock(r.f("{{bold}}[%s] %s{{/}}", report.LeafNodeType.String(), report.LeafNodeText))
108	} else {
109		if len(report.ContainerHierarchyTexts) > 0 {
110			r.emitBlock(r.cycleJoin(report.ContainerHierarchyTexts, " "))
111			indentation = 1
112		}
113		line := r.fi(indentation, "{{bold}}%s{{/}}", report.LeafNodeText)
114		labels := report.Labels()
115		if len(labels) > 0 {
116			line += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels, ", "))
117		}
118		r.emitBlock(line)
119	}
120	r.emitBlock(r.fi(indentation, "{{gray}}%s{{/}}", report.LeafNodeLocation))
121}
122
123func (r *DefaultReporter) DidRun(report types.SpecReport) {
124	v := r.conf.Verbosity()
125	var header, highlightColor string
126	includeRuntime, emitGinkgoWriterOutput, stream, denoter := true, true, false, r.specDenoter
127	succinctLocationBlock := v.Is(types.VerbosityLevelSuccinct)
128
129	hasGW := report.CapturedGinkgoWriterOutput != ""
130	hasStd := report.CapturedStdOutErr != ""
131	hasEmittableReports := report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) || (report.ReportEntries.HasVisibility(types.ReportEntryVisibilityFailureOrVerbose) && (!report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose)))
132
133	if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
134		denoter = fmt.Sprintf("[%s]", report.LeafNodeType)
135	}
136
137	switch report.State {
138	case types.SpecStatePassed:
139		highlightColor, succinctLocationBlock = "{{green}}", v.LT(types.VerbosityLevelVerbose)
140		emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW
141		if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
142			if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports {
143				header = fmt.Sprintf("%s PASSED", denoter)
144			} else {
145				return
146			}
147		} else {
148			header, stream = denoter, true
149			if report.NumAttempts > 1 {
150				header, stream = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), false
151			}
152			if report.RunTime > r.conf.SlowSpecThreshold {
153				header, stream = fmt.Sprintf("%s [SLOW TEST]", header), false
154			}
155		}
156		if hasStd || emitGinkgoWriterOutput || hasEmittableReports {
157			stream = false
158		}
159	case types.SpecStatePending:
160		highlightColor = "{{yellow}}"
161		includeRuntime, emitGinkgoWriterOutput = false, false
162		if v.Is(types.VerbosityLevelSuccinct) {
163			header, stream = "P", true
164		} else {
165			header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose)
166		}
167	case types.SpecStateSkipped:
168		highlightColor = "{{cyan}}"
169		if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) {
170			header = "S [SKIPPED]"
171		} else {
172			header, stream = "S", true
173		}
174	case types.SpecStateFailed:
175		highlightColor, header = "{{red}}", fmt.Sprintf("%s [FAILED]", denoter)
176	case types.SpecStatePanicked:
177		highlightColor, header = "{{magenta}}", fmt.Sprintf("%s! [PANICKED]", denoter)
178	case types.SpecStateInterrupted:
179		highlightColor, header = "{{orange}}", fmt.Sprintf("%s! [INTERRUPTED]", denoter)
180	case types.SpecStateAborted:
181		highlightColor, header = "{{coral}}", fmt.Sprintf("%s! [ABORTED]", denoter)
182	}
183
184	// Emit stream and return
185	if stream {
186		r.emit(r.f(highlightColor + header + "{{/}}"))
187		return
188	}
189
190	// Emit header
191	r.emitDelimiter()
192	if includeRuntime {
193		header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds())
194	}
195	r.emitBlock(r.f(highlightColor + header + "{{/}}"))
196
197	// Emit Code Location Block
198	r.emitBlock(r.codeLocationBlock(report, highlightColor, succinctLocationBlock, false))
199
200	//Emit Stdout/Stderr Output
201	if hasStd {
202		r.emitBlock("\n")
203		r.emitBlock(r.fi(1, "{{gray}}Begin Captured StdOut/StdErr Output >>{{/}}"))
204		r.emitBlock(r.fi(2, "%s", report.CapturedStdOutErr))
205		r.emitBlock(r.fi(1, "{{gray}}<< End Captured StdOut/StdErr Output{{/}}"))
206	}
207
208	//Emit Captured GinkgoWriter Output
209	if emitGinkgoWriterOutput && hasGW {
210		r.emitBlock("\n")
211		r.emitBlock(r.fi(1, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}"))
212		r.emitBlock(r.fi(2, "%s", report.CapturedGinkgoWriterOutput))
213		r.emitBlock(r.fi(1, "{{gray}}<< End Captured GinkgoWriter Output{{/}}"))
214	}
215
216	if hasEmittableReports {
217		r.emitBlock("\n")
218		r.emitBlock(r.fi(1, "{{gray}}Begin Report Entries >>{{/}}"))
219		reportEntries := report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways)
220		if !report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose) {
221			reportEntries = report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose)
222		}
223		for _, entry := range reportEntries {
224			r.emitBlock(r.fi(2, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT)))
225			if representation := entry.StringRepresentation(); representation != "" {
226				r.emitBlock(r.fi(3, representation))
227			}
228		}
229		r.emitBlock(r.fi(1, "{{gray}}<< End Report Entries{{/}}"))
230	}
231
232	// Emit Failure Message
233	if !report.Failure.IsZero() {
234		r.emitBlock("\n")
235		r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.Message))
236		r.emitBlock(r.fi(1, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.Location))
237		if report.Failure.ForwardedPanic != "" {
238			r.emitBlock("\n")
239			r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.ForwardedPanic))
240		}
241
242		if r.conf.FullTrace || report.Failure.ForwardedPanic != "" {
243			r.emitBlock("\n")
244			r.emitBlock(r.fi(1, highlightColor+"Full Stack Trace{{/}}"))
245			r.emitBlock(r.fi(2, "%s", report.Failure.Location.FullStackTrace))
246		}
247	}
248
249	r.emitDelimiter()
250}
251
252func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
253	failures := report.SpecReports.WithState(types.SpecStateFailureStates)
254	if len(failures) > 1 {
255		r.emitBlock("\n\n")
256		r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures)))
257		for _, specReport := range failures {
258			highlightColor, heading := "{{red}}", "[FAIL]"
259			switch specReport.State {
260			case types.SpecStatePanicked:
261				highlightColor, heading = "{{magenta}}", "[PANICKED!]"
262			case types.SpecStateAborted:
263				highlightColor, heading = "{{coral}}", "[ABORTED]"
264			case types.SpecStateInterrupted:
265				highlightColor, heading = "{{orange}}", "[INTERRUPTED]"
266			}
267			locationBlock := r.codeLocationBlock(specReport, highlightColor, true, true)
268			r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock))
269		}
270	}
271
272	//summarize the suite
273	if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded {
274		r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime))
275		return
276	}
277
278	r.emitBlock("\n")
279	color, status := "{{green}}{{bold}}", "SUCCESS!"
280	if !report.SuiteSucceeded {
281		color, status = "{{red}}{{bold}}", "FAIL!"
282	}
283
284	specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes
285	r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}",
286		specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates),
287		report.PreRunStats.TotalSpecs,
288		report.RunTime.Seconds()),
289	)
290
291	switch len(report.SpecialSuiteFailureReasons) {
292	case 0:
293		r.emit(r.f(color+"%s{{/}} -- ", status))
294	case 1:
295		r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0]))
296	default:
297		r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", ")))
298	}
299
300	if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 {
301		r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n"))
302	} else {
303		r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed)))
304		r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates)))
305		if specs.CountOfFlakedSpecs() > 0 {
306			r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs()))
307		}
308		r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending)))
309		r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped)))
310	}
311}
312
313/* Emitting to the writer */
314func (r *DefaultReporter) emit(s string) {
315	if len(s) > 0 {
316		r.lastChar = s[len(s)-1:]
317		r.lastEmissionWasDelimiter = false
318		r.writer.Write([]byte(s))
319	}
320}
321
322func (r *DefaultReporter) emitBlock(s string) {
323	if len(s) > 0 {
324		if r.lastChar != "\n" {
325			r.emit("\n")
326		}
327		r.emit(s)
328		if r.lastChar != "\n" {
329			r.emit("\n")
330		}
331	}
332}
333
334func (r *DefaultReporter) emitDelimiter() {
335	if r.lastEmissionWasDelimiter {
336		return
337	}
338	r.emitBlock(r.f("{{gray}}%s{{/}}", strings.Repeat("-", 30)))
339	r.lastEmissionWasDelimiter = true
340}
341
342/* Rendering text */
343func (r *DefaultReporter) f(format string, args ...interface{}) string {
344	return r.formatter.F(format, args...)
345}
346
347func (r *DefaultReporter) fi(indentation uint, format string, args ...interface{}) string {
348	return r.formatter.Fi(indentation, format, args...)
349}
350
351func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {
352	return r.formatter.CycleJoin(elements, joiner, []string{"{{/}}", "{{gray}}"})
353}
354
355func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, succinct bool, usePreciseFailureLocation bool) string {
356	texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{}
357	texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...)
358	if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
359		texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
360	} else {
361		texts = append(texts, report.LeafNodeText)
362	}
363	labels = append(labels, report.LeafNodeLabels)
364	locations = append(locations, report.LeafNodeLocation)
365
366	failureLocation := report.Failure.FailureNodeLocation
367	if usePreciseFailureLocation {
368		failureLocation = report.Failure.Location
369	}
370
371	switch report.Failure.FailureNodeContext {
372	case types.FailureNodeAtTopLevel:
373		texts = append([]string{r.f(highlightColor+"{{bold}}TOP-LEVEL [%s]{{/}}", report.Failure.FailureNodeType)}, texts...)
374		locations = append([]types.CodeLocation{failureLocation}, locations...)
375		labels = append([][]string{{}}, labels...)
376	case types.FailureNodeInContainer:
377		i := report.Failure.FailureNodeContainerIndex
378		texts[i] = r.f(highlightColor+"{{bold}}%s [%s]{{/}}", texts[i], report.Failure.FailureNodeType)
379		locations[i] = failureLocation
380	case types.FailureNodeIsLeafNode:
381		i := len(texts) - 1
382		texts[i] = r.f(highlightColor+"{{bold}}[%s] %s{{/}}", report.LeafNodeType, report.LeafNodeText)
383		locations[i] = failureLocation
384	}
385
386	out := ""
387	if succinct {
388		out += r.f("%s", r.cycleJoin(texts, " "))
389		flattenedLabels := report.Labels()
390		if len(flattenedLabels) > 0 {
391			out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", "))
392		}
393		out += "\n"
394		if usePreciseFailureLocation {
395			out += r.f("{{gray}}%s{{/}}", failureLocation)
396		} else {
397			out += r.f("{{gray}}%s{{/}}", locations[len(locations)-1])
398		}
399	} else {
400		for i := range texts {
401			out += r.fi(uint(i), "%s", texts[i])
402			if len(labels[i]) > 0 {
403				out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", "))
404			}
405			out += "\n"
406			out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
407		}
408	}
409	return out
410}
411
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)