@@ -6,72 +6,82 @@ import type {
6
6
TestResult ,
7
7
FullResult ,
8
8
Reporter ,
9
+ TestError ,
9
10
} from "@playwright/test/reporter" ;
10
11
import axios from "axios" ;
11
12
import type { Writable } from "stream" ;
12
13
13
- const testOutput = new Map < string , Array < [ Writable , string ] > > ( ) ;
14
-
15
14
class CoderReporter implements Reporter {
15
+ config : FullConfig | null = null ;
16
+ testOutput = new Map < string , Array < [ Writable , string ] > > ( ) ;
17
+ passedCount = 0 ;
18
+ failedTests : TestCase [ ] = [ ] ;
19
+ timedOutTests : TestCase [ ] = [ ] ;
20
+
16
21
onBegin ( config : FullConfig , suite : Suite ) {
22
+ this . config = config ;
17
23
// eslint-disable-next-line no-console -- Helpful for debugging
18
24
console . log ( `==> Running ${ suite . allTests ( ) . length } tests` ) ;
19
25
}
20
26
21
27
onTestBegin ( test : TestCase ) {
22
- testOutput . set ( test . id , [ ] ) ;
28
+ this . testOutput . set ( test . id , [ ] ) ;
23
29
// eslint-disable-next-line no-console -- Helpful for debugging
24
30
console . log ( `==> Starting test ${ test . title } ` ) ;
25
31
}
26
32
27
33
onStdOut ( chunk : string , test ?: TestCase , _ ?: TestResult ) : void {
28
34
if ( ! test ) {
29
- // console.log(`[stdout] [unknown] ${chunk.replace(/\n$/g, "")}`);
35
+ const preserve = this . config ?. preserveOutput === "always" ;
36
+ if ( preserve ) {
37
+ console . log ( `[stdout] ${ chunk . replace ( / \n $ / g, "" ) } ` ) ;
38
+ }
30
39
return ;
31
40
}
32
- testOutput . get ( test . id ) ! . push ( [ process . stdout , chunk ] ) ;
41
+ this . testOutput . get ( test . id ) ! . push ( [ process . stdout , chunk ] ) ;
33
42
}
34
43
35
44
onStdErr ( chunk : string , test ?: TestCase , _ ?: TestResult ) : void {
36
45
if ( ! test ) {
37
- // console.error(`[stderr] [unknown] ${chunk.replace(/\n$/g, "")}`);
46
+ const preserve = this . config ?. preserveOutput === "always" ;
47
+ if ( preserve ) {
48
+ console . error ( `[stderr] ${ chunk . replace ( / \n $ / g, "" ) } ` ) ;
49
+ }
38
50
return ;
39
51
}
40
- testOutput . get ( test . id ) ! . push ( [ process . stderr , chunk ] ) ;
52
+ this . testOutput . get ( test . id ) ! . push ( [ process . stderr , chunk ] ) ;
41
53
}
42
54
43
55
async onTestEnd ( test : TestCase , result : TestResult ) {
44
- // eslint-disable-next-line no-console -- Helpful for debugging
45
- console . log ( `==> Finished test ${ test . title } : ${ result . status } ` ) ;
56
+ console . log ( `==> Finished test ${ test . title } : ${ result . status } ` ) ; // eslint-disable-line no-console -- Helpful for debugging
57
+
58
+ if ( result . status === "passed" ) {
59
+ this . passedCount ++ ;
60
+ }
61
+
62
+ if ( result . status === "failed" ) {
63
+ this . failedTests . push ( test ) ;
64
+ }
46
65
47
- if ( result . status !== "passed" ) {
48
- // eslint-disable-next-line no-console -- Debugging output
49
- console . log ( "==> Output" ) ;
50
- const output = testOutput . get ( test . id ) ! ;
66
+ if ( result . status === "timedOut" ) {
67
+ this . timedOutTests . push ( test ) ;
68
+ }
69
+
70
+ const preserve = this . config ?. preserveOutput ;
71
+ const logOutput =
72
+ preserve === "always" ||
73
+ ( result . status !== "passed" && preserve !== "never" ) ;
74
+ if ( logOutput ) {
75
+ console . log ( "==> Output" ) ; // eslint-disable-line no-console -- Debugging output
76
+ const output = this . testOutput . get ( test . id ) ! ;
51
77
for ( const [ target , chunk ] of output ) {
52
78
target . write ( `${ chunk . replace ( / \n $ / g, "" ) } \n` ) ;
53
79
}
54
80
55
81
if ( result . errors . length > 0 ) {
56
- // eslint-disable-next-line no-console -- Debugging output
57
- console . log ( "==> Errors" ) ;
82
+ console . log ( "==> Errors" ) ; // eslint-disable-line no-console -- Debugging output
58
83
for ( const error of result . errors ) {
59
- if ( error . location ) {
60
- // eslint-disable-next-line no-console -- Debugging output
61
- console . log ( `${ error . location . file } :${ error . location . line } :` ) ;
62
- }
63
- if ( error . snippet ) {
64
- // eslint-disable-next-line no-console -- Debugging output
65
- console . log ( error . snippet ) ;
66
- }
67
-
68
- if ( error . message ) {
69
- // eslint-disable-next-line no-console -- Debugging output
70
- console . log ( error . message ) ;
71
- } else {
72
- // eslint-disable-next-line no-console -- Debugging output
73
- console . log ( error ) ;
74
- }
84
+ reportError ( error ) ;
75
85
}
76
86
}
77
87
@@ -84,13 +94,27 @@ class CoderReporter implements Reporter {
84
94
}
85
95
}
86
96
}
87
- testOutput . delete ( test . id ) ;
97
+ this . testOutput . delete ( test . id ) ;
98
+
88
99
await exportDebugPprof ( test . title ) ;
89
100
}
90
101
91
102
onEnd ( result : FullResult ) {
92
103
// eslint-disable-next-line no-console -- Helpful for debugging
93
104
console . log ( `==> Tests ${ result . status } ` ) ;
105
+ console . log ( `${ this . passedCount } passed` ) ;
106
+ if ( this . failedTests . length > 0 ) {
107
+ console . log ( `${ this . failedTests . length } failed` ) ;
108
+ for ( const test of this . failedTests ) {
109
+ console . log ( ` ${ test . location . file } › ${ test . title } ` ) ;
110
+ }
111
+ }
112
+ if ( this . timedOutTests . length > 0 ) {
113
+ console . log ( `${ this . timedOutTests . length } timed out` ) ;
114
+ for ( const test of this . timedOutTests ) {
115
+ console . log ( ` ${ test . location . file } › ${ test . title } ` ) ;
116
+ }
117
+ }
94
118
}
95
119
}
96
120
@@ -119,5 +143,24 @@ const exportDebugPprof = async (testName: string) => {
119
143
} ) ;
120
144
} ;
121
145
146
+ const reportError = ( error : TestError ) => {
147
+ if ( error . location ) {
148
+ // eslint-disable-next-line no-console -- Debugging output
149
+ console . log ( `${ error . location . file } :${ error . location . line } :` ) ;
150
+ }
151
+ if ( error . snippet ) {
152
+ // eslint-disable-next-line no-console -- Debugging output
153
+ console . log ( error . snippet ) ;
154
+ }
155
+
156
+ if ( error . message ) {
157
+ // eslint-disable-next-line no-console -- Debugging output
158
+ console . log ( error . message ) ;
159
+ } else {
160
+ // eslint-disable-next-line no-console -- Debugging output
161
+ console . log ( error ) ;
162
+ }
163
+ } ;
164
+
122
165
// eslint-disable-next-line no-unused-vars -- Playwright config uses it
123
166
export default CoderReporter ;
0 commit comments