11import { Element } from '@core/element'
22import { html , css , nothing , type TemplateResult } from 'lit'
3- import { customElement } from 'lit/decorators.js'
3+ import { customElement , property } from 'lit/decorators.js'
44import { consume } from '@lit/context'
55import type { TestStats , SuiteStats } from '@wdio/reporter'
66import type { Metadata } from '@wdio/devtools-service/types'
@@ -63,6 +63,7 @@ export class DevtoolsSidebarExplorer extends CollapseableEntry {
6363 ]
6464
6565 @consume ( { context : suiteContext , subscribe : true } )
66+ @property ( { type : Array } )
6667 suites : Record < string , SuiteStats > [ ] | undefined = undefined
6768
6869 @consume ( { context : metadataContext , subscribe : true } )
@@ -71,6 +72,10 @@ export class DevtoolsSidebarExplorer extends CollapseableEntry {
7172 @consume ( { context : isTestRunningContext , subscribe : true } )
7273 isTestRunning = false
7374
75+ updated ( changedProperties : Map < string | number | symbol , unknown > ) {
76+ super . updated ( changedProperties )
77+ }
78+
7479 connectedCallback ( ) : void {
7580 super . connectedCallback ( )
7681 window . addEventListener ( 'app-test-filter' , this . #filterListener)
@@ -285,6 +290,7 @@ export class DevtoolsSidebarExplorer extends CollapseableEntry {
285290 feature-file ="${ entry . featureFile || '' } "
286291 feature-line ="${ entry . featureLine ?? '' } "
287292 suite-type ="${ entry . suiteType || '' } "
293+ ?has-children ="${ entry . children && entry . children . length > 0 } "
288294 .runDisabled =${ this . #isRunDisabled( entry ) }
289295 .runDisabledReason =${ this . #getRunDisabledReason( entry ) }
290296 >
@@ -326,16 +332,48 @@ export class DevtoolsSidebarExplorer extends CollapseableEntry {
326332 )
327333 }
328334
335+ #isRunning( entry : TestStats | SuiteStats ) : boolean {
336+ if ( 'tests' in entry ) {
337+ // Check if any immediate test is running
338+ if ( entry . tests . some ( ( t ) => ! t . end ) ) {
339+ return true
340+ }
341+ // Check if any nested suite is running
342+ if ( entry . suites . some ( ( s ) => this . #isRunning( s ) ) ) {
343+ return true
344+ }
345+ return false
346+ }
347+ // For individual tests, check if end is not set
348+ return ! entry . end
349+ }
350+
351+ #hasFailed( entry : TestStats | SuiteStats ) : boolean {
352+ if ( 'tests' in entry ) {
353+ // Check if any immediate test failed
354+ if ( entry . tests . find ( ( t ) => t . state === 'failed' ) ) {
355+ return true
356+ }
357+ // Check if any nested suite has failures
358+ if ( entry . suites . some ( ( s ) => this . #hasFailed( s ) ) ) {
359+ return true
360+ }
361+ return false
362+ }
363+ // For individual tests
364+ return entry . state === 'failed'
365+ }
366+
329367 #getTestEntry( entry : TestStats | SuiteStats ) : TestEntry {
330368 if ( 'tests' in entry ) {
331369 const entries = [ ...entry . tests , ...entry . suites ]
332370 return {
333371 uid : entry . uid ,
334372 label : entry . title ,
335373 type : 'suite' ,
336- state : entry . tests . some ( ( t ) => ! t . end )
374+ state : this . #isRunning ( entry )
337375 ? TestState . RUNNING
338- : entry . tests . find ( ( t ) => t . state === 'failed' )
376+ : this . #hasFailed ( entry )
339377 ? TestState . FAILED
340378 : TestState . PASSED ,
341379 callSource : ( entry as any ) . callSource ,
@@ -421,9 +459,14 @@ export class DevtoolsSidebarExplorer extends CollapseableEntry {
421459 ( suite ) => suite . uid ,
422460 ( suite ) => this . #renderEntry( suite )
423461 )
424- : html `< p class ="text-disabledForeground text-sm px-4 py-2 ">
425- No tests found
426- </ p > ` }
462+ : html `< div class ="text-sm px-4 py-2 ">
463+ < p class ="text-disabledForeground "> No tests to display</ p >
464+ < p class ="text-xs text-disabledForeground mt-2 ">
465+ Debug: suites=${ this . suites ?. length || 0 } ,
466+ rootSuites=${ uniqueSuites . length } ,
467+ filtered=${ suites . length }
468+ </ p >
469+ </ div > ` }
427470 </ wdio-test-suite >
428471 `
429472 }
0 commit comments