-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathprogress_bar_formatter.ts
123 lines (114 loc) · 4.24 KB
/
progress_bar_formatter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { WriteStream as TtyWriteStream } from 'node:tty'
import ProgressBar from 'progress'
import * as messages from '@cucumber/messages'
import { doesHaveValue, valueOrDefault } from '../value_checker'
import { durationBetweenTimestamps } from '../time'
import { formatUndefinedParameterType } from './helpers/issue_helpers'
import { formatIssue, formatSummary, isIssue } from './helpers'
import Formatter, { IFormatterOptions } from './'
// Inspired by https://github.com/thekompanee/fuubar and https://github.com/martinciu/fuubar-cucumber
export default class ProgressBarFormatter extends Formatter {
private numberOfSteps: number
private testRunStarted: messages.TestRunStarted
private issueCount: number
public progressBar: ProgressBar
public static readonly documentation: string =
'Similar to the Progress Formatter, but provides a real-time updating progress bar based on the total number of steps to be executed in the test run'
constructor(options: IFormatterOptions) {
super(options)
options.eventBroadcaster.on('envelope', this.parseEnvelope.bind(this))
this.numberOfSteps = 0
this.issueCount = 0
}
incrementStepCount(pickleId: string): void {
const pickle = this.eventDataCollector.getPickle(pickleId)
this.numberOfSteps += pickle.steps.length
}
initializeProgressBar(): void {
if (doesHaveValue(this.progressBar)) {
return
}
this.progressBar = new ProgressBar(':current/:total steps [:bar] ', {
clear: true,
incomplete: ' ',
stream: this.stream,
total: this.numberOfSteps,
width: valueOrDefault((this.stream as TtyWriteStream).columns, 80),
})
}
logProgress({
testStepId,
testCaseStartedId,
}: messages.TestStepFinished): void {
const { testCase } =
this.eventDataCollector.getTestCaseAttempt(testCaseStartedId)
const testStep = testCase.testSteps.find((s) => s.id === testStepId)
if (doesHaveValue(testStep.pickleStepId)) {
this.progressBar.tick()
}
}
logUndefinedParametertype(
parameterType: messages.UndefinedParameterType
): void {
this.log(
`Undefined parameter type: ${formatUndefinedParameterType(
parameterType
)}\n`
)
}
logErrorIfNeeded(testCaseFinished: messages.TestCaseFinished): void {
const { worstTestStepResult } = this.eventDataCollector.getTestCaseAttempt(
testCaseFinished.testCaseStartedId
)
if (isIssue(worstTestStepResult)) {
this.issueCount += 1
const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(
testCaseFinished.testCaseStartedId
)
this.progressBar.interrupt(
formatIssue({
colorFns: this.colorFns,
number: this.issueCount,
snippetBuilder: this.snippetBuilder,
supportCodeLibrary: this.supportCodeLibrary,
testCaseAttempt,
printAttachments: this.printAttachments,
})
)
if (testCaseFinished.willBeRetried) {
const stepsToRetry = testCaseAttempt.pickle.steps.length
this.progressBar.tick(-stepsToRetry)
}
}
}
logSummary(testRunFinished: messages.TestRunFinished): void {
const testRunDuration = durationBetweenTimestamps(
this.testRunStarted.timestamp,
testRunFinished.timestamp
)
this.log(
formatSummary({
colorFns: this.colorFns,
testCaseAttempts: this.eventDataCollector.getTestCaseAttempts(),
testRunDuration,
})
)
}
parseEnvelope(envelope: messages.Envelope): void {
if (doesHaveValue(envelope.undefinedParameterType)) {
this.logUndefinedParametertype(envelope.undefinedParameterType)
} else if (doesHaveValue(envelope.testCase)) {
this.incrementStepCount(envelope.testCase.pickleId)
} else if (doesHaveValue(envelope.testStepStarted)) {
this.initializeProgressBar()
} else if (doesHaveValue(envelope.testStepFinished)) {
this.logProgress(envelope.testStepFinished)
} else if (doesHaveValue(envelope.testCaseFinished)) {
this.logErrorIfNeeded(envelope.testCaseFinished)
} else if (doesHaveValue(envelope.testRunStarted)) {
this.testRunStarted = envelope.testRunStarted
} else if (doesHaveValue(envelope.testRunFinished)) {
this.logSummary(envelope.testRunFinished)
}
}
}