@@ -3,39 +3,42 @@ import * as reporters from '@jest/reporters';
33import {
44 AggregatedResult ,
55 AssertionResult ,
6+ Status ,
67 Test ,
78 TestContext ,
89 TestResult
910} from '@jest/test-result' ;
1011import chalk from 'chalk' ;
12+ import { specialChars } from 'jest-util' ;
1113
12- type ResultTree = {
14+ const ICONS = specialChars . ICONS ;
15+
16+ type PerformanceInfo = {
17+ end : number ;
18+ runtime : number ;
19+ slow : boolean ;
20+ start : number ;
21+ } ;
22+
23+ type ResultTreeLeaf = {
1324 name : string ;
14- passed : boolean ;
15- performanceInfo : PerformanceInfo ;
16- children : ( ResultTreeNode | ResultTreeLeaf ) [ ] ;
25+ status : Status ;
26+ duration : number ;
27+ children : Array < never > ;
1728} ;
1829
1930type ResultTreeNode = {
2031 name : string ;
2132 passed : boolean ;
22- children : ( ResultTreeNode | ResultTreeLeaf ) [ ] ;
33+ children : Array < ResultTreeNode | ResultTreeLeaf > ;
2334} ;
2435
25- type ResultTreeLeaf = {
36+ type ResultTree = {
37+ children : Array < ResultTreeLeaf | ResultTreeNode > ;
2638 name : string ;
2739 passed : boolean ;
28- duration : number ;
29- children : never [ ] ;
30- } ;
31-
32- type PerformanceInfo = {
33- end : number ;
34- runtime : number ;
35- slow : boolean ;
36- start : number ;
40+ performanceInfo : PerformanceInfo ;
3741} ;
38-
3942export default class GithubActionsReporter extends reporters . BaseReporter {
4043 override onTestResult (
4144 test : Test ,
@@ -44,10 +47,7 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
4447 ) : void {
4548 this . printFullResult ( test . context , testResult ) ;
4649 if ( this . isLastTestSuite ( results ) ) {
47- core . info ( '' ) ;
48- if ( this . printFailedTestLogs ( test , results ) ) {
49- core . info ( '' ) ;
50- }
50+ this . printFailedTestLogs ( test , results ) ;
5151 }
5252 }
5353
@@ -71,9 +71,9 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
7171 testContexts : Set < TestContext > ,
7272 results : AggregatedResult
7373 ) : void {
74- core . info ( '' ) ;
75- core . info ( reporters . utils . getSummary ( results ) ) ;
76- core . info ( 'Ran all test suites.' ) ;
74+ this . log ( '' ) ;
75+ this . log ( reporters . utils . getSummary ( results ) ) ;
76+ this . log ( 'Ran all test suites.' ) ;
7777 }
7878
7979 private printFullResult ( context : TestContext , results : TestResult ) : void {
@@ -89,12 +89,11 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
8989 }
9090
9191 // eslint-disable-next-line @typescript-eslint/no-explicit-any
92- private arrayEqual ( a1 : any [ ] , a2 : any [ ] ) : boolean {
92+ private arrayEqual ( a1 : Array < any > , a2 : Array < any > ) : boolean {
9393 if ( a1 . length !== a2 . length ) {
9494 return false ;
9595 }
96- for ( let index = 0 ; index < a1 . length ; index ++ ) {
97- const element = a1 [ index ] ;
96+ for ( const [ index , element ] of a1 . entries ( ) ) {
9897 if ( element !== a2 [ index ] ) {
9998 return false ;
10099 }
@@ -103,12 +102,11 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
103102 }
104103
105104 // eslint-disable-next-line @typescript-eslint/no-explicit-any
106- private arrayChild ( a1 : any [ ] , a2 : any [ ] ) : boolean {
105+ private arrayChild ( a1 : Array < any > , a2 : Array < any > ) : boolean {
107106 if ( a1 . length - a2 . length !== 1 ) {
108107 return false ;
109108 }
110- for ( let index = 0 ; index < a2 . length ; index ++ ) {
111- const element = a2 [ index ] ;
109+ for ( const [ index , element ] of a2 . entries ( ) ) {
112110 if ( element !== a1 [ index ] ) {
113111 return false ;
114112 }
@@ -117,7 +115,7 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
117115 }
118116
119117 private getResultTree (
120- suiteResult : AssertionResult [ ] ,
118+ suiteResult : Array < AssertionResult > ,
121119 testPath : string ,
122120 suitePerf : PerformanceInfo
123121 ) : ResultTree {
@@ -127,23 +125,18 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
127125 passed : true ,
128126 performanceInfo : suitePerf
129127 } ;
130- const branches : string [ ] [ ] = [ ] ;
128+ const branches : Array < Array < string > > = [ ] ;
131129 for ( const element of suiteResult ) {
132130 if ( element . ancestorTitles . length === 0 ) {
133- let passed = true ;
134131 if ( element . status === 'failed' ) {
135132 root . passed = false ;
136- passed = false ;
137- } else if ( element . status !== 'passed' ) {
138- throw new Error (
139- `Expected status to be 'failed' or 'passed', got ${ element . status } `
140- ) ;
141133 }
134+ const duration = element . duration || 1 ;
142135 root . children . push ( {
143136 children : [ ] ,
144- duration : Math . max ( element . duration || 0 , 1 ) ,
137+ duration,
145138 name : element . title ,
146- passed
139+ status : element . status
147140 } ) ;
148141 } else {
149142 let alreadyInserted = false ;
@@ -169,27 +162,29 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
169162 }
170163
171164 private getResultChildren (
172- suiteResult : AssertionResult [ ] ,
173- ancestors : string [ ]
174- ) : ResultTreeNode | ResultTreeLeaf {
175- const node : ResultTreeNode | ResultTreeLeaf = {
165+ suiteResult : Array < AssertionResult > ,
166+ ancestors : Array < string >
167+ ) : ResultTreeNode {
168+ const node : ResultTreeNode = {
176169 children : [ ] ,
177- name : ancestors [ ancestors . length - 1 ] ,
170+ name : ancestors . at ( - 1 ) || '' ,
178171 passed : true
179172 } ;
180- const branches : string [ ] [ ] = [ ] ;
173+ const branches : Array < Array < string > > = [ ] ;
181174 for ( const element of suiteResult ) {
182- let passed = true ;
175+ let duration = element . duration ;
176+ if ( ! duration || Number . isNaN ( duration ) ) {
177+ duration = 1 ;
178+ }
183179 if ( this . arrayEqual ( element . ancestorTitles , ancestors ) ) {
184180 if ( element . status === 'failed' ) {
185181 node . passed = false ;
186- passed = false ;
187182 }
188183 node . children . push ( {
189184 children : [ ] ,
190- duration : Math . max ( element . duration || 0 , 1 ) ,
185+ duration,
191186 name : element . title ,
192- passed
187+ status : element . status
193188 } ) ;
194189 } else if (
195190 this . arrayChild (
@@ -234,15 +229,15 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
234229 perfMs = ` (${ resultTree . performanceInfo . runtime } ms)` ;
235230 }
236231 if ( resultTree . passed ) {
237- core . startGroup (
232+ this . startGroup (
238233 `${ chalk . bold . green . inverse ( 'PASS' ) } ${ resultTree . name } ${ perfMs } `
239234 ) ;
240235 for ( const child of resultTree . children ) {
241236 this . recursivePrintResultTree ( child , true , 1 ) ;
242237 }
243- core . endGroup ( ) ;
238+ this . endGroup ( ) ;
244239 } else {
245- core . info (
240+ this . log (
246241 ` ${ chalk . bold . red . inverse ( 'FAIL' ) } ${ resultTree . name } ${ perfMs } `
247242 ) ;
248243 for ( const child of resultTree . children ) {
@@ -257,37 +252,53 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
257252 depth : number
258253 ) : void {
259254 if ( resultTree . children . length === 0 ) {
260- const leaf = resultTree as ResultTreeLeaf ;
255+ if ( ! ( 'duration' in resultTree ) ) {
256+ throw new Error ( 'Expected a leaf. Got a node.' ) ;
257+ }
261258 let numberSpaces = depth ;
262259 if ( ! alreadyGrouped ) {
263260 numberSpaces ++ ;
264261 }
265262 const spaces = ' ' . repeat ( numberSpaces ) ;
266263 let resultSymbol ;
267- if ( leaf . passed ) {
268- resultSymbol = chalk . green ( '\u2713' ) ;
269- } else {
270- resultSymbol = chalk . red ( '\u00D7' ) ;
264+ switch ( resultTree . status ) {
265+ case 'passed' :
266+ resultSymbol = chalk . green ( ICONS . success ) ;
267+ break ;
268+ case 'failed' :
269+ resultSymbol = chalk . red ( ICONS . failed ) ;
270+ break ;
271+ case 'todo' :
272+ resultSymbol = chalk . magenta ( ICONS . todo ) ;
273+ break ;
274+ case 'pending' :
275+ case 'skipped' :
276+ resultSymbol = chalk . yellow ( ICONS . pending ) ;
277+ break ;
271278 }
272- core . info ( `${ spaces + resultSymbol } ${ leaf . name } (${ leaf . duration } ms)` ) ;
279+ this . log (
280+ `${ spaces } ${ resultSymbol } ${ resultTree . name } (${ resultTree . duration } ms)`
281+ ) ;
273282 } else {
274- const node = resultTree as ResultTreeNode ;
275- if ( node . passed ) {
283+ if ( ! ( 'passed' in resultTree ) ) {
284+ throw new Error ( 'Expected a node. Got a leaf' ) ;
285+ }
286+ if ( resultTree . passed ) {
276287 if ( alreadyGrouped ) {
277- core . info ( ' ' . repeat ( depth ) + node . name ) ;
278- for ( const child of node . children ) {
288+ this . log ( ' ' . repeat ( depth ) + resultTree . name ) ;
289+ for ( const child of resultTree . children ) {
279290 this . recursivePrintResultTree ( child , true , depth + 1 ) ;
280291 }
281292 } else {
282- core . startGroup ( ' ' . repeat ( depth ) + node . name ) ;
283- for ( const child of node . children ) {
293+ this . startGroup ( ' ' . repeat ( depth ) + resultTree . name ) ;
294+ for ( const child of resultTree . children ) {
284295 this . recursivePrintResultTree ( child , true , depth + 1 ) ;
285296 }
286- core . endGroup ( ) ;
297+ this . endGroup ( ) ;
287298 }
288299 } else {
289- core . info ( ' ' . repeat ( depth + 1 ) + node . name ) ;
290- for ( const child of node . children ) {
300+ this . log ( ' ' . repeat ( depth + 1 ) + resultTree . name ) ;
301+ for ( const child of resultTree . children ) {
291302 this . recursivePrintResultTree ( child , false , depth + 1 ) ;
292303 }
293304 }
@@ -306,12 +317,27 @@ export default class GithubActionsReporter extends reporters.BaseReporter {
306317 testDir = testDir . replace ( rootDir , '' ) ;
307318 testDir = testDir . slice ( 1 , testDir . length ) ;
308319 if ( result . failureMessage ) {
309- written = true ;
310- core . startGroup ( `Errors thrown in ${ testDir } ` ) ;
311- core . info ( result . failureMessage ) ;
312- core . endGroup ( ) ;
320+ if ( ! written ) {
321+ this . log ( '' ) ;
322+ written = true ;
323+ }
324+ this . startGroup ( `Errors thrown in ${ testDir } ` ) ;
325+ this . log ( result . failureMessage ) ;
326+ this . endGroup ( ) ;
313327 }
314328 }
315329 return written ;
316330 }
331+
332+ override log ( message : string ) : void {
333+ core . info ( message ) ;
334+ }
335+
336+ private startGroup ( title : string ) : void {
337+ core . startGroup ( title ) ;
338+ }
339+
340+ private endGroup ( ) : void {
341+ core . endGroup ( ) ;
342+ }
317343}
0 commit comments