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