@@ -6,6 +6,7 @@ import Shadow = Cypress.Shadow;
66import 'cypress-wait-until' ;
77import { operatorHubPage } from '../../views/operator-hub-page' ;
88import { nav } from '../../views/nav' ;
9+ import { DataTestIDs , LegacyTestIDs } from '../../../src/components/data-test' ;
910
1011export { } ;
1112
@@ -398,6 +399,38 @@ const operatorUtils = {
398399 cy . url ( ) . should ( 'include' , '/monitoring/v2/dashboards' ) ;
399400 } ,
400401
402+ setupTroubleshootingPanel ( MCP : { namespace : string } ) : void {
403+ cy . log ( 'Create troubleshooting panel instance.' ) ;
404+ cy . exec ( `oc apply -f ./cypress/fixtures/coo/troubleshooting-panel-ui-plugin.yaml --kubeconfig ${ Cypress . env ( 'KUBECONFIG_PATH' ) } ` ) ;
405+
406+ cy . log ( 'Troubleshooting panel instance created. Waiting for pods to be ready.' ) ;
407+ cy . exec (
408+ `sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=troubleshooting-panel -n ${ MCP . namespace } --timeout=60s --kubeconfig ${ Cypress . env ( 'KUBECONFIG_PATH' ) } ` ,
409+ {
410+ timeout : readyTimeoutMilliseconds ,
411+ failOnNonZeroExit : true
412+ }
413+ ) . then ( ( result ) => {
414+ expect ( result . code ) . to . eq ( 0 ) ;
415+ cy . log ( `Troubleshooting panel pod is now running in namespace: ${ MCP . namespace } ` ) ;
416+ } ) ;
417+
418+ cy . exec (
419+ `sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=korrel8r -n ${ MCP . namespace } --timeout=600s --kubeconfig ${ Cypress . env ( 'KUBECONFIG_PATH' ) } ` ,
420+ {
421+ timeout : installTimeoutMilliseconds ,
422+ failOnNonZeroExit : true
423+ }
424+ ) . then ( ( result ) => {
425+ expect ( result . code ) . to . eq ( 0 ) ;
426+ cy . log ( `Korrel8r pod is now running in namespace: ${ MCP . namespace } ` ) ;
427+ } ) ;
428+
429+ cy . reload ( true ) ;
430+ cy . byLegacyTestID ( LegacyTestIDs . ApplicationLauncher ) . should ( 'be.visible' ) . click ( ) ;
431+ cy . byTestID ( DataTestIDs . MastHeadApplicationItem ) . contains ( 'Signal Correlation' ) . should ( 'be.visible' ) ;
432+ } ,
433+
401434 revertMonitoringPluginImage ( MP : { namespace : string } ) : void {
402435 if ( Cypress . env ( 'MP_IMAGE' ) ) {
403436 cy . log ( 'MP_IMAGE is set. Lets revert CMO operator CSV' ) ;
@@ -484,7 +517,6 @@ const operatorUtils = {
484517 if ( checkResult . code === 0 ) {
485518 // Namespace exists, proceed with deletion
486519 cy . log ( 'Namespace exists, proceeding with deletion' ) ;
487- cy . log ( 'Eve' ) ;
488520
489521 // Step 1: Delete CSV (ClusterServiceVersion)
490522 cy . exec (
@@ -579,16 +611,66 @@ const operatorUtils = {
579611 }
580612 } ) ;
581613 } ;
582-
614+
583615 checkStatus ( ) ;
584616
617+ cy . then ( ( ) => {
618+ operatorUtils . waitForPodsDeleted ( MCP . namespace ) ;
619+ } ) ;
620+
585621 } else {
586622 cy . log ( 'Namespace does not exist, skipping deletion' ) ;
587623 }
588624 } ) ;
589625 }
590626 } ,
591627
628+ waitForPodsDeleted ( namespace : string , maxWaitMs : number = 120000 ) : void {
629+ const kubeconfigPath = Cypress . env ( 'KUBECONFIG_PATH' ) ;
630+ const checkIntervalMs = 5000 ;
631+ const startTime = Date . now ( ) ;
632+ const podPatterns = 'monitoring|perses|perses-0|health-analyzer|troubleshooting-panel|korrel8r' ;
633+
634+ const checkPods = ( ) => {
635+ const elapsed = Date . now ( ) - startTime ;
636+
637+ if ( elapsed > maxWaitMs ) {
638+ throw new Error ( `Timeout: Pods still exist after ${ maxWaitMs / 1000 } s` ) ;
639+ }
640+
641+ cy . exec (
642+ `oc get pods -n ${ namespace } --kubeconfig ${ kubeconfigPath } -o name 2>&1 | grep -E '${ podPatterns } ' | wc -l` ,
643+ { failOnNonZeroExit : false }
644+ ) . then ( ( result ) => {
645+ const count = parseInt ( result . stdout . trim ( ) , 10 ) ;
646+
647+ if ( count === 0 || result . stderr . includes ( 'not found' ) ) {
648+ cy . log ( `✓ All target pods deleted after ${ elapsed } ms` ) ;
649+ } else {
650+ cy . log ( `${ elapsed } ms - ${ count } pod(s) still exist, retrying...` ) ;
651+ cy . wait ( checkIntervalMs ) . then ( checkPods ) ;
652+ }
653+ } ) ;
654+ } ;
655+
656+ checkPods ( ) ;
657+ } ,
658+
659+ cleanupTroubleshootingPanel ( MCP : { namespace : string , config1 ?: { kind : string , name : string } } ) : void {
660+ const config1 = MCP . config1 || { kind : 'UIPlugin' , name : 'troubleshooting-panel' } ;
661+
662+ if ( Cypress . env ( 'SKIP_ALL_INSTALL' ) ) {
663+ cy . log ( 'SKIP_ALL_INSTALL is set. Skipping Troubleshooting Panel instance deletion.' ) ;
664+ return ;
665+ }
666+
667+ cy . log ( 'Delete Troubleshooting Panel instance.' ) ;
668+ cy . executeAndDelete (
669+ `oc delete ${ config1 . kind } ${ config1 . name } --ignore-not-found --kubeconfig ${ Cypress . env ( 'KUBECONFIG_PATH' ) } ` ,
670+ ) ;
671+
672+ } ,
673+
592674 RemoveClusterAdminRole ( ) : void {
593675 cy . log ( 'Remove cluster-admin role from user.' ) ;
594676 cy . executeAndDelete (
@@ -697,6 +779,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
697779 cy . log ( 'SKIP_ALL_INSTALL is set. Skipping COO cleanup and operator verifications (preserves existing setup).' ) ;
698780 return ;
699781 }
782+ operatorUtils . cleanupTroubleshootingPanel ( MCP ) ;
700783 operatorUtils . cleanup ( MCP ) ;
701784 operatorUtils . revertMonitoringPluginImage ( MP ) ;
702785 cy . log ( 'Cleanup COO (no session) completed' ) ;
@@ -711,6 +794,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
711794 operatorUtils . waitForCOOReady ( MCP ) ;
712795 operatorUtils . setupMonitoringConsolePlugin ( MCP ) ;
713796 operatorUtils . setupDashboardsAndPlugins ( MCP ) ;
797+ operatorUtils . setupTroubleshootingPanel ( MCP ) ;
714798 operatorUtils . setupMonitoringPluginImage ( MP ) ;
715799 operatorUtils . RemoveClusterAdminRole ( ) ;
716800 operatorUtils . collectDebugInfo ( MP , MCP ) ;
0 commit comments