@@ -2,41 +2,56 @@ import * as assert from 'node:assert'
2
2
3
3
import {
4
4
Envelope ,
5
+ Feature ,
5
6
getWorstTestStepResult ,
7
+ GherkinDocument ,
6
8
Pickle ,
9
+ PickleStep ,
10
+ Step ,
7
11
TestCase ,
8
12
TestCaseFinished ,
9
13
TestCaseStarted ,
10
14
TestRunFinished ,
11
15
TestRunStarted ,
16
+ TestStep ,
17
+ TestStepFinished ,
12
18
TestStepResultStatus ,
13
19
TimeConversion ,
14
20
} from '@cucumber/messages'
15
- import { Query as CucumberQuery } from '@cucumber/query '
21
+ import { ArrayMultimap } from '@teppeis/multimaps '
16
22
17
- export class ExtendedQuery extends CucumberQuery {
23
+ export class ExtendedQuery {
18
24
private testRunStarted : TestRunStarted
19
25
private testRunFinished : TestRunFinished
20
26
private testCaseStarted : Array < TestCaseStarted > = [ ]
27
+ private readonly stepById : Map < string , Step > = new Map ( )
21
28
private readonly pickleById : Map < string , Pickle > = new Map ( )
29
+ private readonly pickleStepById : Map < string , PickleStep > = new Map ( )
22
30
private readonly testCaseById : Map < string , TestCase > = new Map ( )
31
+ private readonly testStepById : Map < string , TestStep > = new Map ( )
23
32
private readonly testCaseFinishedByTestCaseStartedId : Map < string , TestCaseFinished > = new Map ( )
33
+ private readonly testStepFinishedByTestCaseStartedId : ArrayMultimap < string , TestStepFinished > =
34
+ new ArrayMultimap ( )
24
35
25
36
update ( envelope : Envelope ) {
26
- super . update ( envelope )
27
-
37
+ if ( envelope . gherkinDocument ) {
38
+ this . updateGherkinDocument ( envelope . gherkinDocument )
39
+ }
28
40
if ( envelope . pickle ) {
29
- this . pickleById . set ( envelope . pickle . id , envelope . pickle )
41
+ this . updatePickle ( envelope . pickle )
30
42
}
31
43
if ( envelope . testRunStarted ) {
32
44
this . testRunStarted = envelope . testRunStarted
33
45
}
34
46
if ( envelope . testCase ) {
35
- this . testCaseById . set ( envelope . testCase . id , envelope . testCase )
47
+ this . updateTestCase ( envelope . testCase )
36
48
}
37
49
if ( envelope . testCaseStarted ) {
38
50
this . updateTestCaseStarted ( envelope . testCaseStarted )
39
51
}
52
+ if ( envelope . testStepFinished ) {
53
+ this . updateTestStepFinished ( envelope . testStepFinished )
54
+ }
40
55
if ( envelope . testCaseFinished ) {
41
56
this . updateTestCaseFinished ( envelope . testCaseFinished )
42
57
}
@@ -45,6 +60,47 @@ export class ExtendedQuery extends CucumberQuery {
45
60
}
46
61
}
47
62
63
+ private updateGherkinDocument ( gherkinDocument : GherkinDocument ) {
64
+ if ( gherkinDocument . feature ) {
65
+ this . updateFeature ( gherkinDocument . feature )
66
+ }
67
+ }
68
+
69
+ private updateFeature ( feature : Feature ) {
70
+ feature . children . forEach ( ( featureChild ) => {
71
+ if ( featureChild . background ) {
72
+ this . updateSteps ( featureChild . background . steps )
73
+ }
74
+ if ( featureChild . scenario ) {
75
+ this . updateSteps ( featureChild . scenario . steps )
76
+ }
77
+ if ( featureChild . rule ) {
78
+ featureChild . rule . children . forEach ( ( ruleChild ) => {
79
+ if ( ruleChild . background ) {
80
+ this . updateSteps ( ruleChild . background . steps )
81
+ }
82
+ if ( ruleChild . scenario ) {
83
+ this . updateSteps ( ruleChild . scenario . steps )
84
+ }
85
+ } )
86
+ }
87
+ } )
88
+ }
89
+
90
+ private updateSteps ( steps : ReadonlyArray < Step > ) {
91
+ steps . forEach ( ( step ) => this . stepById . set ( step . id , step ) )
92
+ }
93
+
94
+ private updatePickle ( pickle : Pickle ) {
95
+ this . pickleById . set ( pickle . id , pickle )
96
+ pickle . steps . forEach ( ( pickleStep ) => this . pickleStepById . set ( pickleStep . id , pickleStep ) )
97
+ }
98
+
99
+ private updateTestCase ( testCase : TestCase ) {
100
+ this . testCaseById . set ( testCase . id , testCase )
101
+ testCase . testSteps . forEach ( ( testStep ) => this . testStepById . set ( testStep . id , testStep ) )
102
+ }
103
+
48
104
private updateTestCaseStarted ( testCaseStarted : TestCaseStarted ) {
49
105
// ensure this replaces any previous attempt for the same test case
50
106
this . testCaseStarted = [
@@ -55,13 +111,26 @@ export class ExtendedQuery extends CucumberQuery {
55
111
]
56
112
}
57
113
114
+ private updateTestStepFinished ( testStepFinished : TestStepFinished ) {
115
+ this . testStepFinishedByTestCaseStartedId . put (
116
+ testStepFinished . testCaseStartedId ,
117
+ testStepFinished
118
+ )
119
+ }
120
+
58
121
private updateTestCaseFinished ( testCaseFinished : TestCaseFinished ) {
59
122
this . testCaseFinishedByTestCaseStartedId . set (
60
123
testCaseFinished . testCaseStartedId ,
61
124
testCaseFinished
62
125
)
63
126
}
64
127
128
+ findStepBy ( pickleStep : PickleStep ) {
129
+ const [ astNodeId ] = pickleStep . astNodeIds
130
+ assert . ok ( 'Expected PickleStep to have an astNodeId' )
131
+ return this . stepById . get ( astNodeId )
132
+ }
133
+
65
134
findPickleBy ( testCaseStarted : TestCaseStarted ) {
66
135
const testCase = this . findTestCaseBy ( testCaseStarted )
67
136
if ( ! testCase ) {
@@ -70,6 +139,11 @@ export class ExtendedQuery extends CucumberQuery {
70
139
return this . pickleById . get ( testCase . pickleId )
71
140
}
72
141
142
+ findPickleStepBy ( testStep : TestStep ) {
143
+ assert . ok ( testStep . pickleStepId , 'Expected TestStep to have a pickleStepId' )
144
+ return this . pickleStepById . get ( testStep . pickleStepId )
145
+ }
146
+
73
147
findAllTestCaseStarted ( ) : ReadonlyArray < TestCaseStarted > {
74
148
return [ ...this . testCaseStarted ]
75
149
}
@@ -93,6 +167,22 @@ export class ExtendedQuery extends CucumberQuery {
93
167
)
94
168
}
95
169
170
+ findTestStepBy ( testStepFinished : TestStepFinished ) {
171
+ return this . testStepById . get ( testStepFinished . testStepId )
172
+ }
173
+
174
+ findTestStepFinishedAndTestStepBy (
175
+ testCaseStarted : TestCaseStarted
176
+ ) : ReadonlyArray < [ TestStepFinished , TestStep ] > {
177
+ return this . testStepFinishedByTestCaseStartedId
178
+ . get ( testCaseStarted . id )
179
+ . map ( ( testStepFinished ) => {
180
+ const testStep = this . findTestStepBy ( testStepFinished )
181
+ assert . ok ( testStep , 'Expected to find TestStep by TestStepFinished' )
182
+ return [ testStepFinished , testStep ]
183
+ } )
184
+ }
185
+
96
186
findTestRunDuration ( ) {
97
187
if ( ! this . testRunStarted || ! this . testRunFinished ) {
98
188
return undefined
@@ -114,13 +204,11 @@ export class ExtendedQuery extends CucumberQuery {
114
204
[ TestStepResultStatus . UNKNOWN ] : 0 ,
115
205
}
116
206
for ( const testCaseStarted of this . testCaseStarted ) {
117
- const testCase = this . findTestCaseBy ( testCaseStarted )
118
- assert . ok ( testCase , 'Expected to find TestCase for TestCaseStarted' )
119
- const statusesFromSteps = testCase . testSteps . map ( ( testStep ) => {
120
- return getWorstTestStepResult ( this . getTestStepResults ( testStep . id ) )
121
- } )
122
- const overallStatus = getWorstTestStepResult ( statusesFromSteps )
123
- result [ overallStatus . status ] ++
207
+ const testStepResults = this . findTestStepFinishedAndTestStepBy ( testCaseStarted ) . map (
208
+ ( [ testStepFinished ] ) => testStepFinished . testStepResult
209
+ )
210
+ const mostSevereResult = getWorstTestStepResult ( testStepResults )
211
+ result [ mostSevereResult . status ] ++
124
212
}
125
213
return result
126
214
}
0 commit comments