Skip to content

Commit 278bd76

Browse files
committed
most of non-passing scenarios
1 parent 806fda1 commit 278bd76

File tree

2 files changed

+107
-12
lines changed

2 files changed

+107
-12
lines changed

javascript/src/SummaryPrinter.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1-
import { Envelope, TestRunFinished, TestRunStarted, TestStepResultStatus } from '@cucumber/messages'
1+
import {
2+
Envelope,
3+
Location,
4+
Pickle,
5+
TestRunFinished,
6+
TestRunStarted,
7+
TestStepResult,
8+
TestStepResultStatus,
9+
} from '@cucumber/messages'
210
import { Query } from '@cucumber/query'
311

4-
import { formatCounts, formatDuration, formatSnippets } from './helpers.js'
12+
import {
13+
ensure,
14+
ERROR_INDENT_LENGTH,
15+
formatCounts,
16+
formatDuration,
17+
formatNonPassingTitle,
18+
formatPickleLocation,
19+
formatTestStepResultError,
20+
GHERKIN_INDENT_LENGTH,
21+
indent,
22+
} from './helpers.js'
523
import type { Options } from './types.js'
624

725
export class SummaryPrinter {
@@ -25,6 +43,7 @@ export class SummaryPrinter {
2543
}
2644

2745
private printSummary() {
46+
this.printNonPassingScenarios()
2847
this.printStats()
2948
this.printSnippets()
3049
}
@@ -37,6 +56,70 @@ export class SummaryPrinter {
3756
this.printDuration()
3857
}
3958

59+
private printNonPassingScenarios() {
60+
const theOrder: TestStepResultStatus[] = [
61+
TestStepResultStatus.UNKNOWN,
62+
TestStepResultStatus.PENDING,
63+
TestStepResultStatus.UNDEFINED,
64+
TestStepResultStatus.AMBIGUOUS,
65+
TestStepResultStatus.FAILED,
66+
]
67+
68+
const picklesByStatus = new Map<
69+
TestStepResultStatus,
70+
Array<{ pickle: Pickle; location: Location | undefined; testStepResult: TestStepResult }>
71+
>()
72+
73+
for (const testCaseFinished of this.query.findAllTestCaseFinished()) {
74+
const pickle = ensure(
75+
this.query.findPickleBy(testCaseFinished),
76+
'Pickle must exist for TestCaseFinished'
77+
)
78+
const location = this.query.findLocationOf(pickle)
79+
const testStepResult = this.query.findMostSevereTestStepResultBy(testCaseFinished)
80+
if (testStepResult) {
81+
if (!picklesByStatus.has(testStepResult.status)) {
82+
picklesByStatus.set(testStepResult.status, [])
83+
}
84+
picklesByStatus.get(testStepResult.status)!.push({
85+
pickle,
86+
location,
87+
testStepResult,
88+
})
89+
}
90+
}
91+
92+
for (const status of theOrder) {
93+
const picklesForThisStatus = picklesByStatus.get(status) ?? []
94+
if (picklesForThisStatus.length > 0) {
95+
this.println()
96+
this.println(formatNonPassingTitle(status, this.options.theme, this.stream))
97+
picklesForThisStatus.forEach(({ pickle, location, testStepResult }, index) => {
98+
const formattedLocation = formatPickleLocation(
99+
pickle,
100+
location,
101+
this.options.theme,
102+
this.stream
103+
)
104+
this.println(
105+
indent(`${index + 1}) ${pickle.name} ${formattedLocation}`, GHERKIN_INDENT_LENGTH)
106+
)
107+
if (status === TestStepResultStatus.FAILED) {
108+
const content = formatTestStepResultError(
109+
testStepResult,
110+
this.options.theme,
111+
this.stream
112+
)
113+
if (content) {
114+
this.println(indent(content, GHERKIN_INDENT_LENGTH + ERROR_INDENT_LENGTH + 1))
115+
this.println()
116+
}
117+
}
118+
})
119+
}
120+
}
121+
}
122+
40123
private printGlobalHookCounts() {
41124
const testRunHookFinished = this.query.findAllTestRunHookFinished()
42125
if (testRunHookFinished.length === 0) {

javascript/src/helpers.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const GHERKIN_INDENT_LENGTH = 2
2929
export const STEP_ARGUMENT_INDENT_LENGTH = 2
3030
export const ATTACHMENT_INDENT_LENGTH = 4
3131
export const ERROR_INDENT_LENGTH = 4
32-
const DURATION_FORMAT = "m'm' s.S's'"
32+
3333
const STATUS_ORDER: TestStepResultStatus[] = [
3434
TestStepResultStatus.UNKNOWN,
3535
TestStepResultStatus.PASSED,
@@ -48,6 +48,7 @@ const STATUS_CHARACTERS: Record<TestStepResultStatus, string> = {
4848
[TestStepResultStatus.UNDEFINED]: 'U',
4949
[TestStepResultStatus.UNKNOWN]: '?',
5050
} as const
51+
const DURATION_FORMAT = "m'm' s.S's'"
5152

5253
export function ensure<T>(value: T | undefined, message: string): T {
5354
if (!value) {
@@ -340,15 +341,15 @@ export function formatStatusCharacter(
340341
return new TextBuilder(stream).append(character).build(theme.status?.all?.[status])
341342
}
342343

343-
export function formatDuration(start: Timestamp, finish: Timestamp) {
344-
const startMillis = new Date(TimeConversion.timestampToMillisecondsSinceEpoch(start))
345-
const finishMillis = new Date(TimeConversion.timestampToMillisecondsSinceEpoch(finish))
346-
const duration = Interval.fromDateTimes(startMillis, finishMillis).toDuration([
347-
'minutes',
348-
'seconds',
349-
'milliseconds',
350-
])
351-
return duration.toFormat(DURATION_FORMAT)
344+
export function formatNonPassingTitle(
345+
status: TestStepResultStatus,
346+
theme: Theme,
347+
stream: NodeJS.WritableStream
348+
) {
349+
return new TextBuilder(stream)
350+
.append(status.charAt(0).toUpperCase() + status.slice(1).toLowerCase())
351+
.append(' scenarios:')
352+
.build(theme.status?.all?.[status])
352353
}
353354

354355
export function formatCounts(
@@ -377,3 +378,14 @@ export function formatCounts(
377378
}
378379
return builder.build()
379380
}
381+
382+
export function formatDuration(start: Timestamp, finish: Timestamp) {
383+
const startMillis = new Date(TimeConversion.timestampToMillisecondsSinceEpoch(start))
384+
const finishMillis = new Date(TimeConversion.timestampToMillisecondsSinceEpoch(finish))
385+
const duration = Interval.fromDateTimes(startMillis, finishMillis).toDuration([
386+
'minutes',
387+
'seconds',
388+
'milliseconds',
389+
])
390+
return duration.toFormat(DURATION_FORMAT)
391+
}

0 commit comments

Comments
 (0)