11import chalk from 'chalk'
22import indentString from 'indent-string'
3+ import { DateTime } from 'luxon'
34
45import { TestResultsShortLinks } from '../rest/test-sessions'
56import { Reporter } from './reporter'
@@ -20,6 +21,7 @@ export type checkFilesMap = Map<string | undefined, Map<SequenceId, {
2021 testResultId ?: string
2122 links ?: TestResultsShortLinks
2223 numRetries : number
24+ hasStreamedLogs ?: boolean
2325} > >
2426
2527export default abstract class AbstractListReporter implements Reporter {
@@ -101,6 +103,37 @@ export default abstract class AbstractListReporter implements Reporter {
101103 printLn ( chalk . red ( 'Unable to run checks: ' ) + err . message )
102104 }
103105
106+ onStreamLogs ( check : any , sequenceId : SequenceId , logs : Array < { timestamp : number , message : string } > | undefined ) {
107+ const checkFile = this . checkFilesMap ! . get ( check . getSourceFile ?.( ) ) ! . get ( sequenceId ) !
108+ const logList = logs || [ ]
109+
110+ // Display the check title if this is the first time we're streaming logs for this check
111+ const isFirstLogBatch = ! checkFile . hasStreamedLogs
112+ checkFile . hasStreamedLogs = true
113+ if ( isFirstLogBatch ) {
114+ // For Playwright tests, we need to create a better display name
115+ const displayCheck = {
116+ ...check ,
117+ sourceFile : check . getSourceFile ?.( ) || 'Playwright Test' ,
118+ name : check . name || check . logicalId || 'Unknown Test' ,
119+ }
120+ printLn ( formatCheckTitle ( CheckStatus . RUNNING , displayCheck , { includeSourceFile : true } ) )
121+ }
122+
123+ // Format and display each log with proper indentation and timestamp handling
124+ logList . forEach ( logEntry => {
125+ // Format timestamp from Unix timestamp to HH:mm:ss.SSS format
126+ const timestamp = DateTime . fromMillis ( logEntry . timestamp ) . toFormat ( 'HH:mm:ss.SSS' )
127+ // Handle logs that contain newlines by splitting and prefixing each line with timestamp
128+ const messageLines = logEntry . message . split ( '\n' )
129+ messageLines . forEach ( line => {
130+ // Each line gets its own timestamp for clarity
131+ const formattedLine = `[${ timestamp } ] ${ line } `
132+ printLn ( indentString ( formattedLine , 4 ) )
133+ } )
134+ } )
135+ }
136+
104137 // Clear the summary which was printed by _printStatus from stdout
105138 // TODO: Rather than clearing the whole status bar, we could overwrite the exact lines that changed.
106139 // This might look a bit smoother and reduce the flickering effects.
0 commit comments