@@ -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' ) ;
@@ -489,7 +522,6 @@ const operatorUtils = {
489522 if ( checkResult . code === 0 ) {
490523 // Namespace exists, proceed with deletion
491524 cy . log ( 'Namespace exists, proceeding with deletion' ) ;
492- cy . log ( 'Eve' ) ;
493525
494526 // Step 1: Delete CSV (ClusterServiceVersion)
495527 cy . exec (
@@ -584,16 +616,66 @@ const operatorUtils = {
584616 }
585617 } ) ;
586618 } ;
587-
619+
588620 checkStatus ( ) ;
589621
622+ cy . then ( ( ) => {
623+ operatorUtils . waitForPodsDeleted ( MCP . namespace ) ;
624+ } ) ;
625+
590626 } else {
591627 cy . log ( 'Namespace does not exist, skipping deletion' ) ;
592628 }
593629 } ) ;
594630 }
595631 } ,
596632
633+ waitForPodsDeleted ( namespace : string , maxWaitMs : number = 120000 ) : void {
634+ const kubeconfigPath = Cypress . env ( 'KUBECONFIG_PATH' ) ;
635+ const checkIntervalMs = 5000 ;
636+ const startTime = Date . now ( ) ;
637+ const podPatterns = 'monitoring|perses|perses-0|health-analyzer|troubleshooting-panel|korrel8r' ;
638+
639+ const checkPods = ( ) => {
640+ const elapsed = Date . now ( ) - startTime ;
641+
642+ if ( elapsed > maxWaitMs ) {
643+ throw new Error ( `Timeout: Pods still exist after ${ maxWaitMs / 1000 } s` ) ;
644+ }
645+
646+ cy . exec (
647+ `oc get pods -n ${ namespace } --kubeconfig ${ kubeconfigPath } -o name 2>&1 | grep -E '${ podPatterns } ' | wc -l` ,
648+ { failOnNonZeroExit : false }
649+ ) . then ( ( result ) => {
650+ const count = parseInt ( result . stdout . trim ( ) , 10 ) ;
651+
652+ if ( count === 0 || result . stderr . includes ( 'not found' ) ) {
653+ cy . log ( `✓ All target pods deleted after ${ elapsed } ms` ) ;
654+ } else {
655+ cy . log ( `${ elapsed } ms - ${ count } pod(s) still exist, retrying...` ) ;
656+ cy . wait ( checkIntervalMs ) . then ( checkPods ) ;
657+ }
658+ } ) ;
659+ } ;
660+
661+ checkPods ( ) ;
662+ } ,
663+
664+ cleanupTroubleshootingPanel ( MCP : { namespace : string , config1 ?: { kind : string , name : string } } ) : void {
665+ const config1 = MCP . config1 || { kind : 'UIPlugin' , name : 'troubleshooting-panel' } ;
666+
667+ if ( Cypress . env ( 'SKIP_ALL_INSTALL' ) ) {
668+ cy . log ( 'SKIP_ALL_INSTALL is set. Skipping Troubleshooting Panel instance deletion.' ) ;
669+ return ;
670+ }
671+
672+ cy . log ( 'Delete Troubleshooting Panel instance.' ) ;
673+ cy . executeAndDelete (
674+ `oc delete ${ config1 . kind } ${ config1 . name } --ignore-not-found --kubeconfig ${ Cypress . env ( 'KUBECONFIG_PATH' ) } ` ,
675+ ) ;
676+
677+ } ,
678+
597679 RemoveClusterAdminRole ( ) : void {
598680 cy . log ( 'Remove cluster-admin role from user.' ) ;
599681 cy . executeAndDelete (
@@ -702,6 +784,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
702784 cy . log ( 'SKIP_ALL_INSTALL is set. Skipping COO cleanup and operator verifications (preserves existing setup).' ) ;
703785 return ;
704786 }
787+ operatorUtils . cleanupTroubleshootingPanel ( MCP ) ;
705788 operatorUtils . cleanup ( MCP ) ;
706789 operatorUtils . revertMonitoringPluginImage ( MP ) ;
707790 cy . log ( 'Cleanup COO (no session) completed' ) ;
@@ -716,6 +799,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
716799 operatorUtils . waitForCOOReady ( MCP ) ;
717800 operatorUtils . setupMonitoringConsolePlugin ( MCP ) ;
718801 operatorUtils . setupDashboardsAndPlugins ( MCP ) ;
802+ operatorUtils . setupTroubleshootingPanel ( MCP ) ;
719803 operatorUtils . setupMonitoringPluginImage ( MP ) ;
720804 operatorUtils . RemoveClusterAdminRole ( ) ;
721805 operatorUtils . collectDebugInfo ( MP , MCP ) ;
0 commit comments