@@ -366,7 +366,7 @@ describe("ClineProvider", () => {
366366 let provider : ClineProvider
367367 let mockContext : vscode . ExtensionContext
368368 let mockOutputChannel : vscode . OutputChannel
369- let mockWebviewView : vscode . WebviewView
369+ let mockWebviewView : any
370370 let mockPostMessage : any
371371 let updateGlobalStateSpy : any
372372
@@ -445,7 +445,7 @@ describe("ClineProvider", () => {
445445 return { dispose : vi . fn ( ) }
446446 } ) ,
447447 onDidChangeVisibility : vi . fn ( ) . mockImplementation ( ( ) => ( { dispose : vi . fn ( ) } ) ) ,
448- } as unknown as vscode . WebviewView
448+ }
449449
450450 provider = new ClineProvider ( mockContext , mockOutputChannel , "sidebar" , new ContextProxy ( mockContext ) )
451451
@@ -505,6 +505,48 @@ describe("ClineProvider", () => {
505505 expect ( mockWebviewView . webview . html ) . toContain ( "<!DOCTYPE html>" )
506506 } )
507507
508+ describe ( "logWebviewHiddenDiagnostics" , ( ) => {
509+ let visibilityCallback : ( ) => void
510+
511+ beforeEach ( async ( ) => {
512+ // Capture the visibility callback registered during resolveWebviewView
513+ mockWebviewView . onDidChangeVisibility = vi . fn ( ) . mockImplementation ( ( cb : ( ) => void ) => {
514+ visibilityCallback = cb
515+ return { dispose : vi . fn ( ) }
516+ } )
517+ // @ts -ignore - accessing private property for testing
518+ provider . view = mockWebviewView
519+ await provider . resolveWebviewView ( mockWebviewView )
520+ ; ( mockOutputChannel . appendLine as ReturnType < typeof vi . fn > ) . mockClear ( )
521+ } )
522+
523+ test ( "does not log when no task is active" , ( ) => {
524+ // view becomes hidden with no task on the stack
525+ Object . defineProperty ( mockWebviewView , "visible" , { value : false , configurable : true } )
526+ visibilityCallback ( )
527+ expect ( mockOutputChannel . appendLine ) . not . toHaveBeenCalled ( )
528+ } )
529+
530+ test ( "does not log when the active task is aborted" , async ( ) => {
531+ const task = new Task ( defaultTaskOptions )
532+ Object . defineProperty ( task , "taskId" , { value : "aborted-task" , writable : true } )
533+ task . abort = true
534+ await provider . addClineToStack ( task )
535+ Object . defineProperty ( mockWebviewView , "visible" , { value : false , configurable : true } )
536+ visibilityCallback ( )
537+ expect ( mockOutputChannel . appendLine ) . not . toHaveBeenCalled ( )
538+ } )
539+
540+ test ( "logs task state to output channel when an active task is running" , async ( ) => {
541+ const task = new Task ( defaultTaskOptions )
542+ Object . defineProperty ( task , "taskId" , { value : "running-task" , writable : true } )
543+ await provider . addClineToStack ( task )
544+ Object . defineProperty ( mockWebviewView , "visible" , { value : false , configurable : true } )
545+ visibilityCallback ( )
546+ expect ( mockOutputChannel . appendLine ) . toHaveBeenCalledWith ( expect . stringContaining ( "running-task" ) )
547+ } )
548+ } )
549+
508550 test ( "resolveWebviewView sets up webview correctly in development mode even if local server is not running" , async ( ) => {
509551 provider = new ClineProvider (
510552 { ...mockContext , extensionMode : vscode . ExtensionMode . Development } ,
@@ -2059,7 +2101,7 @@ describe("Project MCP Settings", () => {
20592101 let provider : ClineProvider
20602102 let mockContext : vscode . ExtensionContext
20612103 let mockOutputChannel : vscode . OutputChannel
2062- let mockWebviewView : vscode . WebviewView
2104+ let mockWebviewView : any
20632105 let mockPostMessage : any
20642106
20652107 beforeEach ( async ( ) => {
@@ -2113,7 +2155,7 @@ describe("Project MCP Settings", () => {
21132155 visible : true ,
21142156 onDidDispose : vi . fn ( ) ,
21152157 onDidChangeVisibility : vi . fn ( ) ,
2116- } as unknown as vscode . WebviewView
2158+ }
21172159 ; ( vscode . window as any ) . activeTextEditor = undefined
21182160 ; ( vscode . workspace . getWorkspaceFolder as any ) . mockReset ( )
21192161 provider = new ClineProvider ( mockContext , mockOutputChannel , "sidebar" , new ContextProxy ( mockContext ) )
@@ -2376,7 +2418,7 @@ describe("ClineProvider - Router Models", () => {
23762418 let provider : ClineProvider
23772419 let mockContext : vscode . ExtensionContext
23782420 let mockOutputChannel : vscode . OutputChannel
2379- let mockWebviewView : vscode . WebviewView
2421+ let mockWebviewView : any
23802422 let mockPostMessage : any
23812423
23822424 beforeEach ( ( ) => {
@@ -2435,7 +2477,7 @@ describe("ClineProvider - Router Models", () => {
24352477 return { dispose : vi . fn ( ) }
24362478 } ) ,
24372479 onDidChangeVisibility : vi . fn ( ) . mockImplementation ( ( ) => ( { dispose : vi . fn ( ) } ) ) ,
2438- } as unknown as vscode . WebviewView
2480+ }
24392481
24402482 if ( ! TelemetryService . hasInstance ( ) ) {
24412483 TelemetryService . createInstance ( [ ] )
@@ -2687,7 +2729,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
26872729 let provider : ClineProvider
26882730 let mockContext : vscode . ExtensionContext
26892731 let mockOutputChannel : vscode . OutputChannel
2690- let mockWebviewView : vscode . WebviewView
2732+ let mockWebviewView : any
26912733 let mockPostMessage : any
26922734 let defaultTaskOptions : TaskOptions
26932735
@@ -2756,7 +2798,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
27562798 return { dispose : vi . fn ( ) }
27572799 } ) ,
27582800 onDidChangeVisibility : vi . fn ( ) . mockImplementation ( ( ) => ( { dispose : vi . fn ( ) } ) ) ,
2759- } as unknown as vscode . WebviewView
2801+ }
27602802
27612803 provider = new ClineProvider ( mockContext , mockOutputChannel , "sidebar" , new ContextProxy ( mockContext ) )
27622804
0 commit comments