@@ -35,7 +35,7 @@ function formatNumber(number: number) {
3535 + ( res [ 1 ] ? `.${ res [ 1 ] } ` : '' )
3636}
3737
38- function renderHookState ( task : Task , hookName : keyof SuiteHooks , level = 0 ) {
38+ function renderHookState ( task : Task , hookName : keyof SuiteHooks , level = 0 ) : string {
3939 const state = task . result ?. hooks ?. [ hookName ]
4040 if ( state && state === 'run' )
4141 return `${ ' ' . repeat ( level ) } ${ getHookStateSymbol ( task , hookName ) } ${ c . dim ( `[ ${ hookName } ]` ) } `
@@ -86,10 +86,14 @@ function renderBenchmark(task: Benchmark, tasks: Task[]): string {
8686 ] . join ( '' )
8787}
8888
89- export function renderTree ( tasks : Task [ ] , options : ListRendererOptions , level = 0 ) {
90- let output : string [ ] = [ ]
89+ export function renderTree ( tasks : Task [ ] , options : ListRendererOptions , level = 0 , maxRows ?: number ) : string {
90+ const output : string [ ] = [ ]
91+ let currentRowCount = 0
92+
93+ // Go through tasks in reverse order since maxRows is used to bail out early when limit is reached
94+ for ( const task of [ ...tasks ] . reverse ( ) ) {
95+ const taskOutput = [ ]
9196
92- for ( const task of tasks ) {
9397 let suffix = ''
9498 let prefix = ` ${ getStateSymbol ( task ) } `
9599
@@ -124,7 +128,7 @@ export function renderTree(tasks: Task[], options: ListRendererOptions, level =
124128 ? renderBenchmark ( task as Benchmark , tasks )
125129 : name
126130
127- output . push ( padding + prefix + body + suffix )
131+ taskOutput . push ( padding + prefix + body + suffix )
128132
129133 if ( ( task . result ?. state !== 'pass' ) && outputMap . get ( task ) != null ) {
130134 let data : string | undefined = outputMap . get ( task )
@@ -136,22 +140,29 @@ export function renderTree(tasks: Task[], options: ListRendererOptions, level =
136140
137141 if ( data != null ) {
138142 const out = `${ ' ' . repeat ( level ) } ${ F_RIGHT } ${ data } `
139- output . push ( ` ${ c . gray ( cliTruncate ( out , getCols ( - 3 ) ) ) } ` )
143+ taskOutput . push ( ` ${ c . gray ( cliTruncate ( out , getCols ( - 3 ) ) ) } ` )
140144 }
141145 }
142146
143- output = output . concat ( renderHookState ( task , 'beforeAll' , level + 1 ) )
144- output = output . concat ( renderHookState ( task , 'beforeEach' , level + 1 ) )
147+ taskOutput . push ( renderHookState ( task , 'beforeAll' , level + 1 ) )
148+ taskOutput . push ( renderHookState ( task , 'beforeEach' , level + 1 ) )
145149 if ( task . type === 'suite' && task . tasks . length > 0 ) {
146150 if ( ( task . result ?. state === 'fail' || task . result ?. state === 'run' || options . renderSucceed ) )
147- output = output . concat ( renderTree ( task . tasks , options , level + 1 ) )
151+ taskOutput . push ( renderTree ( task . tasks , options , level + 1 , maxRows ) )
148152 }
149- output = output . concat ( renderHookState ( task , 'afterAll' , level + 1 ) )
150- output = output . concat ( renderHookState ( task , 'afterEach' , level + 1 ) )
153+ taskOutput . push ( renderHookState ( task , 'afterAll' , level + 1 ) )
154+ taskOutput . push ( renderHookState ( task , 'afterEach' , level + 1 ) )
155+
156+ const rows = taskOutput . filter ( Boolean )
157+ output . push ( rows . join ( '\n' ) )
158+ currentRowCount += rows . length
159+
160+ if ( maxRows && currentRowCount >= maxRows )
161+ break
151162 }
152163
153164 // TODO: moving windows
154- return output . filter ( Boolean ) . join ( '\n' )
165+ return output . reverse ( ) . join ( '\n' )
155166}
156167
157168export const createListRenderer = ( _tasks : Task [ ] , options : ListRendererOptions ) => {
@@ -161,19 +172,25 @@ export const createListRenderer = (_tasks: Task[], options: ListRendererOptions)
161172 const log = options . logger . logUpdate
162173
163174 function update ( ) {
164- log ( renderTree ( tasks , options ) )
175+ log ( renderTree (
176+ tasks ,
177+ options ,
178+ 0 ,
179+ // log-update already limits the amount of printed rows to fit the current terminal
180+ // but we can optimize performance by doing it ourselves
181+ process . stdout . rows ,
182+ ) )
165183 }
166184
167185 return {
168186 start ( ) {
169187 if ( timer )
170188 return this
171- timer = setInterval ( update , 200 )
189+ timer = setInterval ( update , 16 )
172190 return this
173191 } ,
174192 update ( _tasks : Task [ ] ) {
175193 tasks = _tasks
176- update ( )
177194 return this
178195 } ,
179196 async stop ( ) {
@@ -182,6 +199,8 @@ export const createListRenderer = (_tasks: Task[], options: ListRendererOptions)
182199 timer = undefined
183200 }
184201 log . clear ( )
202+
203+ // Note that at this point the renderTree should output all tasks
185204 options . logger . log ( renderTree ( tasks , options ) )
186205 return this
187206 } ,
0 commit comments