From bccac12a7d2cc1b11cd3047af46439ca04d65df0 Mon Sep 17 00:00:00 2001 From: Amoghrd Date: Fri, 15 May 2026 15:46:03 -0400 Subject: [PATCH] fixes --- .../fixtures/image-digest-mirror-set.yaml | 2 +- web/cypress/fixtures/test-server-client.yaml | 153 +++++++++--------- .../integration-tests/dns_tracking.cy.ts | 21 +-- .../netflow_cluster_admin_group.cy.ts | 16 +- .../netflow_external_subnet.cy.ts | 11 +- .../integration-tests/netflow_table.cy.ts | 21 ++- .../netflow_zone_multiCluster.cy.ts | 24 +-- .../integration-tests/quickFilters.cy.ts | 16 +- .../integration-tests/table_queryopts.cy.ts | 11 +- web/cypress/views/netflow-page.ts | 88 ++++++---- web/cypress/views/netobserv.ts | 86 +++++----- 11 files changed, 223 insertions(+), 226 deletions(-) diff --git a/web/cypress/fixtures/image-digest-mirror-set.yaml b/web/cypress/fixtures/image-digest-mirror-set.yaml index f331a8e13..8d1a20539 100644 --- a/web/cypress/fixtures/image-digest-mirror-set.yaml +++ b/web/cypress/fixtures/image-digest-mirror-set.yaml @@ -31,4 +31,4 @@ spec: - mirrors: - quay.io/redhat-user-workloads/ocp-network-observab-tenant/network-observability-console-plugin-pf4-ystream - quay.io/redhat-user-workloads/ocp-network-observab-tenant/network-observability-console-plugin-pf4-zstream - source: registry.redhat.io/network-observability/network-observability-console-plugin-compat-rhel9 + source: registry.redhat.io/network-observability/network-observability-console-plugin-pf4-rhel9 diff --git a/web/cypress/fixtures/test-server-client.yaml b/web/cypress/fixtures/test-server-client.yaml index 040e4e9cb..1c95ae7e6 100644 --- a/web/cypress/fixtures/test-server-client.yaml +++ b/web/cypress/fixtures/test-server-client.yaml @@ -1,19 +1,25 @@ -apiVersion: template.openshift.io/v1 -kind: Template +--- +apiVersion: v1 +kind: Namespace metadata: - name: netobserv-test-client-server -objects: - - kind: Namespace - apiVersion: v1 - metadata: - name: ${SERVER_NS} - labels: - name: ${SERVER_NS} - - apiVersion: apps/v1 - kind: Deployment + name: test-server-56222 + labels: + name: test-server-56222 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + namespace: test-server-56222 + labels: + app: nginx +spec: + replicas: 1 + selector: + matchLabels: + app: nginx + template: metadata: - name: nginx - namespace: ${SERVER_NS} labels: app: nginx spec: @@ -21,74 +27,61 @@ objects: runAsNonRoot: true seccompProfile: type: RuntimeDefault - replicas: 1 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - privileged: false - image: quay.io/openshifttest/nginx-alpine:1.2.3 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8080 - - apiVersion: v1 - kind: Service - metadata: - namespace: ${SERVER_NS} - name: nginx-service - spec: - selector: - app: nginx - type: NodePort - ports: - - protocol: TCP - port: 80 - targetPort: 8080 - - kind: Namespace - apiVersion: v1 - metadata: - name: ${CLIENT_NS} - labels: - name: ${CLIENT_NS} - - apiVersion: v1 - kind: Pod - metadata: - creationTimestamp: null - labels: - run: client - name: client - namespace: ${CLIENT_NS} - spec: containers: - - command: - - sh - - -c - - " - \ while : ; do\n - \ curl nginx-service.${SERVER_NS}.svc:80/data/100K 2>&1 > /dev/null ; sleep 5 \n - \ done" - image: quay.io/openshifttest/hello-openshift:1.2.0 + - name: nginx + image: quay.io/openshifttest/nginx-alpine:1.2.3 + imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] - privileged: false - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - name: client -parameters: - - name: SERVER_NS - value: test-server - - name: CLIENT_NS - value: test-client + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: test-server-56222 + name: nginx-service +spec: + selector: + app: nginx + type: NodePort + ports: + - protocol: TCP + port: 80 + targetPort: 8080 +--- +apiVersion: v1 +kind: Namespace +metadata: + name: test-client-56222 + labels: + name: test-client-56222 +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + run: client + name: client + namespace: test-client-56222 +spec: + containers: + - name: client + image: quay.io/openshifttest/hello-openshift:1.2.0 + command: + - sh + - -c + - | + while : ; do + curl nginx-service.test-server-56222.svc:80/data/100K 2>&1 > /dev/null + sleep 5 + done + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: ["ALL"] + seccompProfile: + type: RuntimeDefault diff --git a/web/cypress/integration-tests/dns_tracking.cy.ts b/web/cypress/integration-tests/dns_tracking.cy.ts index 5d5b14d8e..41904cee2 100644 --- a/web/cypress/integration-tests/dns_tracking.cy.ts +++ b/web/cypress/integration-tests/dns_tracking.cy.ts @@ -67,22 +67,13 @@ describe('(OCP-67087 Network_Observability) DNSTracking test', { tags: ['Network cy.get('#search').type(dns_name + '{enter}') // select DNS Id, DNS Error and DNS Name columns - cy.openColumnsModal() - cy.get(colSelectors.columnsModal).should('be.visible') - cy.get('#DNSId').check() - cy.get('#DNSErrNo').check() - cy.get('#DNSName').check() - cy.byTestID(colSelectors.save).click() - cy.reload() - - // verify they are visible in table view - cy.byTestID('table-composable').should('exist').within(() => { - cy.get(colSelectors.dnsId).should('exist') - cy.get(colSelectors.dnsError).should('exist') - cy.get(colSelectors.dnsName).should('exist') - }) + cy.selectAndVerifyColumns([ + colSelectors.dnsId, + colSelectors.dnsError, + colSelectors.dnsName + ]) - // Verify DNSName column for all rows + // Verify DNSName value for all rows cy.get('[data-test-td-column-id="DNSName"]').each((td) => { expect(td).to.contain(`${dns_name}`) }) diff --git a/web/cypress/integration-tests/netflow_cluster_admin_group.cy.ts b/web/cypress/integration-tests/netflow_cluster_admin_group.cy.ts index b1a1b4f62..2fc7e0ff0 100644 --- a/web/cypress/integration-tests/netflow_cluster_admin_group.cy.ts +++ b/web/cypress/integration-tests/netflow_cluster_admin_group.cy.ts @@ -4,6 +4,11 @@ import { netflowPage } from "@views/netflow-page" describe('(OCP-67617 Network_Observability) User in group with cluster-admin role', { tags: ['Network_Observability'] }, function () { before('any test', function () { + // Skip this test suite if using kubeadmin (LOGIN_IDP is 'kube:admin') + if (Cypress.env('LOGIN_IDP') === 'kube:admin') { + this.skip() + } + // create new group, add user to that group and give that group cluster-admin role cy.adminCLI(`oc adm groups new netobservadmins`) cy.adminCLI(`oc adm groups add-users netobservadmins ${Cypress.env('LOGIN_USERNAME')}`) @@ -26,19 +31,24 @@ describe('(OCP-67617 Network_Observability) User in group with cluster-admin rol cy.visit('/netflow-traffic') // validate user is not able to access netflow traffic page // overview shows no panels - cy.get('li.overviewTabButton').should('exist').click() + cy.get('#tabs-container').contains('Overview').click() cy.get("#overview-flex").should('not.exist') // table view shows no grid - cy.get('li.tableTabButton').should('exist').click() + cy.get('#tabs-container').contains('Traffic flows').click() cy.byTestID("table-composable").should('not.exist') // topology view shows no view - cy.get('li.topologyTabButton').should('exist').click() + cy.get('#tabs-container').contains('Topology').click() cy.byTestID("error-state").should('exist') }) after("all tests", function () { + // Skip cleanup if using kubeadmin + if (Cypress.env('LOGIN_IDP') === 'kube:admin') { + return + } + cy.adminCLI(`oc adm groups remove-users netobservadmins ${Cypress.env('LOGIN_USERNAME')}`) cy.adminCLI(`oc delete groups netobservadmins`) cy.uiLogout() diff --git a/web/cypress/integration-tests/netflow_external_subnet.cy.ts b/web/cypress/integration-tests/netflow_external_subnet.cy.ts index 759a63155..5eae9a094 100644 --- a/web/cypress/integration-tests/netflow_external_subnet.cy.ts +++ b/web/cypress/integration-tests/netflow_external_subnet.cy.ts @@ -21,11 +21,10 @@ describe('(OCP-67615, OCP-72874 Network_Observability) Return external traffic a cy.byTestID("table-composable").should('exist') // enable SrcSubnetLabel and DstSubnetLabel columns - cy.openColumnsModal() - cy.get(colSelectors.columnsModal).should('be.visible') - cy.get('#SrcSubnetLabel').check() - cy.get('#DstSubnetLabel').check() - cy.byTestID(colSelectors.save).click() + cy.selectAndVerifyColumns([ + colSelectors.srcSubnetLabel, + colSelectors.dstSubnetLabel + ]) // filter on SrcSubnetLabel Pods and DstIP 52.200.142.250 cy.byTestID("column-filter-toggle").click().get('.pf-c-dropdown__menu').should('be.visible') @@ -64,6 +63,8 @@ describe('(OCP-67615, OCP-72874 Network_Observability) Return external traffic a cy.byTestID("column-filter-toggle").click().get('.pf-c-dropdown__menu').should('be.visible') cy.byTestID('group-0-toggle').click().should('be.visible') cy.byTestID('src_namespace').click() + + netflowPage.clearAllFilters() }) afterEach("each test", function () { diff --git a/web/cypress/integration-tests/netflow_table.cy.ts b/web/cypress/integration-tests/netflow_table.cy.ts index 5c3fe64d6..7af1264d8 100644 --- a/web/cypress/integration-tests/netflow_table.cy.ts +++ b/web/cypress/integration-tests/netflow_table.cy.ts @@ -55,21 +55,21 @@ describe('(OCP-50532, OCP-50531, OCP-50530, OCP-59408 Network_Observability) Net netflowPage.stopAutoRefresh() cy.openColumnsModal() cy.get(colSelectors.columnsModal).should('be.visible') - cy.get('#K8S_OwnerObject').check() - cy.get('#AddrPort').check() + cy.get(colSelectors.k8sOwner).check() + cy.get(colSelectors.ipPort).check() - cy.get('#Mac').should('exist').check() - cy.get('#FlowDirection').should('exist').check() + cy.get(colSelectors.mac).should('exist').check() + cy.get(colSelectors.direction).should('exist').check() // ICMP related columns - cy.get('#IcmpType').should('exist').check() - cy.get('#IcmpCode').should('exist').check() + cy.get(colSelectors.icmpType).should('exist').check() + cy.get(colSelectors.icmpCode).should('exist').check() // source columns - cy.get('#SrcK8S_HostIP').check() + cy.get(colSelectors.srcNodeIP).check() cy.get('#SrcK8S_Namespace[type="checkbox"]').uncheck() // dest columns - cy.get('#DstK8S_HostIP').check() + cy.get(colSelectors.dstNodeIP).check() cy.byTestID(colSelectors.save).click() cy.reload() @@ -203,10 +203,7 @@ describe('(OCP-50532, OCP-50531, OCP-50530, OCP-59408 Network_Observability) Net cy.get(displayDropdownSelectors.table).should('exist').click() cy.byTestID('size-s').click() cy.get(displayDropdownSelectors.table).should('exist').click() - cy.openColumnsModal() - cy.get(colSelectors.columnsModal).should('be.visible') - cy.get('#StartTime').check() - cy.byTestID(colSelectors.save).click() + cy.selectAndVerifyColumns([colSelectors.startTime]) cy.showAdvancedOptions() cy.visit('/monitoring/alerts') diff --git a/web/cypress/integration-tests/netflow_zone_multiCluster.cy.ts b/web/cypress/integration-tests/netflow_zone_multiCluster.cy.ts index 654546088..6a707bd87 100644 --- a/web/cypress/integration-tests/netflow_zone_multiCluster.cy.ts +++ b/web/cypress/integration-tests/netflow_zone_multiCluster.cy.ts @@ -24,24 +24,12 @@ describe('Netflow Zone and multiCluster test', { tags: ['Network_Observability'] cy.get('#tabs-container').contains('Traffic flows').click() cy.byTestID("table-composable").should('exist') - cy.openColumnsModal() - cy.get(colSelectors.columnsModal).should('be.visible') - // Check zone columns - cy.get('#SrcZone').check() - cy.get('#DstZone').check() - - // Check multiCluster column - cy.get('#ClusterName').check() - cy.byTestID(colSelectors.save).click() - - cy.byTestID('table-composable').should('exist').within(() => { - // Verify zone column - cy.get(colSelectors.srcZone).should('exist') - cy.get(colSelectors.dstZone).should('exist') - - // Verify multiCluster column - cy.get(colSelectors.clusterName).should('exist') - }) + // Check zone and multiCluster columns + cy.selectAndVerifyColumns([ + colSelectors.srcZone, + colSelectors.dstZone, + colSelectors.clusterName + ]) }) it("(OCP-71524, aramesha, Network_Observability) should verify zone/cluster scope topology", function () { diff --git a/web/cypress/integration-tests/quickFilters.cy.ts b/web/cypress/integration-tests/quickFilters.cy.ts index ca6a769b6..f1f39a3ae 100644 --- a/web/cypress/integration-tests/quickFilters.cy.ts +++ b/web/cypress/integration-tests/quickFilters.cy.ts @@ -17,20 +17,26 @@ var patch = [{ } ] }] -var templateParams = `-p SERVER_NS=${SERVER_NS} CLIENT_NS=${CLIENT_NS}` -var templateProcessCmd = `oc process -f cypress/fixtures/test-server-client.yaml ${templateParams} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}` describe('(OCP-56222 Network_Observability) Quick Filters test', { tags: ['Network_Observability'] }, function () { before('any test', function () { cy.adminCLI(`oc adm policy add-cluster-role-to-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) cy.uiLogin(Cypress.env('LOGIN_IDP'), Cypress.env('LOGIN_USERNAME'), Cypress.env('LOGIN_PASSWORD')) - // create test server and client pods - cy.adminCLI(`${templateProcessCmd}| oc apply -f -`) Operator.install() cy.checkStorageClass(this) Operator.createFlowcollector() + + // create test server and client pods + cy.adminCLI('oc apply -f cypress/fixtures/test-server-client.yaml') + + // Wait for pods to be created + cy.wait(10000) + + // Wait for pods to be ready + cy.adminCLI('oc wait --for=condition=Ready pod -l app=nginx -n test-server-56222 --timeout=120s') + cy.adminCLI('oc wait --for=condition=Ready pod -n test-client-56222 client --timeout=120s') }) beforeEach('any netflow table test', function () { @@ -79,7 +85,7 @@ describe('(OCP-56222 Network_Observability) Quick Filters test', { tags: ['Netwo }) after("all tests", function () { - cy.adminCLI(`${templateProcessCmd} | oc delete -f -`) + cy.adminCLI('oc delete -f cypress/fixtures/test-server-client.yaml --ignore-not-found') cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) }) }) diff --git a/web/cypress/integration-tests/table_queryopts.cy.ts b/web/cypress/integration-tests/table_queryopts.cy.ts index d4f9e704b..9d27b8ec8 100644 --- a/web/cypress/integration-tests/table_queryopts.cy.ts +++ b/web/cypress/integration-tests/table_queryopts.cy.ts @@ -83,16 +83,7 @@ describe('(OCP-50532, OCP-50531, OCP-50530, OCP-59408 Network_Observability) Net it("(OCP-68125, aramesha, Network_Observability) should verify DSCP column", function () { netflowPage.stopAutoRefresh() - cy.openColumnsModal().then(col => { - cy.get(colSelectors.columnsModal).should('be.visible') - cy.get('#Dscp').check() - cy.byTestID(colSelectors.save).click() - }) - cy.reload() - - cy.byTestID('table-composable').should('exist').within(() => { - cy.get(colSelectors.dscp).should('exist') - }) + cy.selectAndVerifyColumns([colSelectors.dscp]) // filter on DSCP values cy.byTestID("column-filter-toggle").click().get('.pf-c-dropdown__menu').should('be.visible') diff --git a/web/cypress/views/netflow-page.ts b/web/cypress/views/netflow-page.ts index d79b404c1..b019186c9 100644 --- a/web/cypress/views/netflow-page.ts +++ b/web/cypress/views/netflow-page.ts @@ -8,6 +8,7 @@ declare global { checkPanel(panelName: string[]): Chainable openPanelsModal(): Chainable openColumnsModal(): Chainable + selectAndVerifyColumns(columnSelectors: string[]): Chainable selectPopupItems(id: string, names: string[]): Chainable checkPopupItems(id: string, names: string[]): Chainable checkQuerySummary(metric: JQuery): Chainable @@ -55,11 +56,6 @@ export const netflowPage = { guidedTour.close() cy.visit(`/dev-monitoring/ns/${project}/netflow-traffic`) }, - toggleFullScreen: () => { - cy.byTestID(genSelectors.moreOpts).should('exist').click().then(() => { - cy.get(genSelectors.expand).click() - }) - }, setAutoRefresh: () => { cy.byTestID(genSelectors.refreshDrop).then(btn => { expect(btn).to.exist @@ -180,37 +176,37 @@ export namespace genSelectors { export const fullScreen = '[data-test=fullscreen-button]' } -// Helper function to generate table header column selectors -const thCol = (columnId: string): string => `[data-test=th-${columnId}] button`; - export namespace colSelectors { export const columnsModal = '.modal-content' export const save = 'columns-save-button' export const resetDefault = 'columns-reset-button' - export const mac = thCol('Mac') - export const k8sOwner = thCol('K8S_OwnerObject') - export const ipPort = thCol('AddrPort') - export const protocol = thCol('Proto') - export const icmpType = thCol('IcmpType') - export const icmpCode = thCol('IcmpCode') - export const srcNodeIP = thCol('SrcK8S_HostIP') - export const srcNS = thCol('SrcK8S_Namespace') - export const dstNodeIP = thCol('DstK8S_HostIP') - export const direction = thCol('FlowDirection') - export const bytes = thCol('Bytes') - export const packets = thCol('Packets') - export const recordType = thCol('RecordType') - export const conversationID = thCol('_HashId') - export const flowRTT = thCol('TimeFlowRttMs') - export const dscp = thCol('Dscp') - export const dnsLatency = thCol('DNSLatency') - export const dnsResponseCode = thCol('DNSResponseCode') - export const dnsId = thCol('DNSId') - export const dnsError = thCol('DNSErrNo') - export const dnsName = thCol('DNSName') - export const srcZone = thCol('SrcZone') - export const dstZone = thCol('DstZone') - export const clusterName = thCol('ClusterName') + export const mac = '#Mac' + export const k8sOwner = '#K8S_OwnerObject' + export const ipPort = '#AddrPort' + export const protocol = '#Proto' + export const icmpType = '#IcmpType' + export const icmpCode = '#IcmpCode' + export const srcNodeIP = '#SrcK8S_HostIP' + export const srcNS = '#SrcK8S_Namespace' + export const dstNodeIP = '#DstK8S_HostIP' + export const direction = '#FlowDirection' + export const bytes = '#Bytes' + export const packets = '#Packets' + export const recordType = '#RecordType' + export const conversationID = '#_HashId' + export const startTime = '#StartTime' + export const flowRTT = '#TimeFlowRttMs' + export const dscp = '#Dscp' + export const dnsLatency = '#DNSLatency' + export const dnsResponseCode = '#DNSResponseCode' + export const dnsId = '#DNSId' + export const dnsError = '#DNSErrNo' + export const dnsName = '#DNSName' + export const srcZone = '#SrcZone' + export const dstZone = '#DstZone' + export const clusterName = '#ClusterName' + export const srcSubnetLabel = '#SrcSubnetLabel' + export const dstSubnetLabel = '#DstSubnetLabel' } export namespace exportSelectors { @@ -364,6 +360,28 @@ Cypress.Commands.add('selectPopupItems', (id, names) => { } }); +Cypress.Commands.add('selectAndVerifyColumns', (columnSelectors: string[]) => { + // Open the columns modal + cy.openColumnsModal().then(() => { + cy.get(colSelectors.columnsModal).should('be.visible'); + + // Check each column + columnSelectors.forEach(selector => { + cy.get(selector).check(); + }); + + cy.byTestID(colSelectors.save).click(); + }); + cy.reload(); + + // Verify columns appear in table + cy.byTestID('table-composable').should('exist').within(() => { + columnSelectors.forEach(selector => { + cy.get(selector).should('exist'); + }); + }); +}); + Cypress.Commands.add('checkQuerySummary', (metric) => { // parseFloat handles formats: "123 ms", "123+ ms", "1.5k ms", "1.5k+ ms" const num = parseFloat(metric.text()) @@ -389,7 +407,7 @@ Cypress.Commands.add('visitNetflowTrafficTab', (page) => { Cypress.Commands.add('checkNetflowTraffic', (loki = "Enabled") => { // overview panels - cy.get('li.overviewTabButton').should('exist').click({ force: true }) + cy.get('#tabs-container').contains('Overview').click({ force: true }) netflowPage.setAutoRefresh() cy.wait(2000) cy.checkPanel(overviewSelectors.defaultPanels) @@ -400,13 +418,13 @@ Cypress.Commands.add('checkNetflowTraffic', (loki = "Enabled") => { cy.get('li.tableTabButton > button').should('exist').should('have.class', 'pf-m-aria-disabled') } else { - cy.get('li.tableTabButton').should('exist').click() + cy.get('#tabs-container').contains('Traffic flows').click() cy.wait(1000) cy.byTestID("table-composable", { timeout: 60000 }).should('exist') } // topology view - cy.get('li.topologyTabButton').should('exist').click() + cy.get('#tabs-container').contains('Topology').click() cy.wait(2000) cy.get('#drawer', { timeout: 60000 }).should('not.be.empty') }); diff --git a/web/cypress/views/netobserv.ts b/web/cypress/views/netobserv.ts index 2f0088660..9a1974171 100644 --- a/web/cypress/views/netobserv.ts +++ b/web/cypress/views/netobserv.ts @@ -52,7 +52,7 @@ const FIXTURE_PATHS = { export const Operator = { name: () => { - if (`${Cypress.env('NOO_CATALOG_SOURCE')}` == "upstream") { + if (`${Cypress.env('NOO_CATALOG_SOURCE')}` === "upstream") { return "NetObserv Operator" } else { @@ -64,7 +64,7 @@ export const Operator = { let catalogImg: string let catalogSource: string - if (catSrc == "upstream") { + if (catSrc === "upstream") { catalogImg = catSrcImage ? catSrcImage : DEFAULT_UPSTREAM_IMAGE catalogSource = "netobserv-test" catalogDisplayName = "NetObserv QE" @@ -81,52 +81,51 @@ export const Operator = { return catalogSource }, install: () => { - if (`${Cypress.env('SKIP_NOO_INSTALL')}` == "true") { + if (`${Cypress.env('SKIP_NOO_INSTALL')}` === "true") { return null } - var catalogSource = Operator.install_catalogsource() + // Check operator status via CLI + cy.adminCLI('oc get csv -n openshift-netobserv-operator --no-headers -o custom-columns=":metadata.name" 2>/dev/null || echo "NotFound"') + .then((result: any) => { + const stdout = result.stdout ? result.stdout.trim() : '' + const csvName = stdout.split('\n').find((line: string) => + line.includes('netobserv-operator') || line.includes('network-observability-operator') + ) - cy.visit(`/k8s/ns/openshift-netobserv-operator/operators.coreos.com~v1alpha1~ClusterServiceVersion`); - cy.reload() - // if user still does not have admin access - // try few more times - cy.contains("openshift-netobserv-operator").should('be.visible') + if (csvName && !stdout.includes('NotFound') && !stdout.includes('No resources found')) { + // CSV exists, check if it's in Succeeded state + cy.adminCLI(`oc wait csv ${csvName.trim()} -n openshift-netobserv-operator --for=jsonpath='{.status.phase}'=Succeeded --timeout=120s`) + .then(() => { + cy.log('NetObserv Operator already installed') + }) + } else { + cy.log('Installing NetObserv Operator') + var catalogSource = Operator.install_catalogsource() - const waitForAccess = (retries = 15) => { - cy.get("div.loading-box").should('be.visible') - cy.document().then(doc => { - if (doc.querySelectorAll('.co-disabled').length > 0 && retries > 0) { - cy.log(`user does not have access, retries left: ${retries}`) - cy.wait(5000) - cy.reload(true) - waitForAccess(retries - 1) + if (catSrc === "upstream") { + // metrics checkbox is not available for upstream operators + operatorHubPage.install("netobserv-operator", catalogSource, false) + } else { + operatorHubPage.install("netobserv-operator", catalogSource, true) + } } }) - } - waitForAccess() - // don't install operator if its already installed - cy.get("div.loading-box").should('be.visible').then(loading => { - if (Cypress.$('td[role="gridcell"]').length == 0) { - if (catSrc == "upstream") { - // metrics checkbox is not available for upstream operators - operatorHubPage.install("netobserv-operator", catalogSource, false) - } else { - operatorHubPage.install("netobserv-operator", catalogSource, true) - } - } - }) }, visitFlowcollector: () => { - cy.visit('k8s/ns/openshift-netobserv-operator/operators.coreos.com~v1alpha1~ClusterServiceVersion') - const selector = '[data-test-operator-row="' + Operator.name() + '"]' - cy.get(selector).invoke('attr', 'href').then(href => { - cy.visit(href as string) - cy.reload() - }) + cy.adminCLI('oc get csv -n openshift-netobserv-operator --no-headers -o custom-columns=":metadata.name" 2>/dev/null || echo "NotFound"') + .then((result: any) => { + const stdout = result.stdout ? result.stdout.trim() : '' + const csvName = stdout.split('\n').find((line: string) => + line.includes('netobserv-operator') || line.includes('network-observability-operator') + ) - cy.contains('Flow Collector').invoke('attr', 'href').then(href => { - cy.visit(href as string) - }) + if (csvName && !stdout.includes('NotFound') && !stdout.includes('No resources found')) { + cy.visit(`/k8s/ns/openshift-netobserv-operator/operators.coreos.com~v1alpha1~ClusterServiceVersion/${csvName.trim()}/flows.netobserv.io~v1beta2~FlowCollector`) + cy.get('div.loading-box__loaded', { timeout: 30000 }).should('exist') + } else { + throw new Error('NetObserv CSV not found') + } + }) }, createFlowcollector: (parameters?: FlowCollectorParameter) => { Operator.visitFlowcollector() @@ -141,7 +140,7 @@ export const Operator = { }) // don't create flowcollector if already exists cy.get('div.loading-box:nth-child(1)').should('be.visible').then(() => { - if (Cypress.$('td[role="gridcell"]').length == 0) { + if (Cypress.$('td[role="gridcell"]').length === 0) { cy.log("Deploying flowcollector") switch (parameters) { case "PacketDrop": @@ -184,8 +183,11 @@ export const Operator = { if (parameters !== "LokiDisabled") { cy.adminCLI(`oc wait --for=condition=Ready pod -l app=loki -n ${project} --timeout=180s`) } - Operator.visitFlowcollector() - cy.byTestID('status-text', { timeout: 120000 }).should('exist').should('contain.text', 'Ready') + // Check FlowCollector status and wait for plugin pod to be Ready + cy.contains('tr', 'cluster').within(() => { + cy.byTestID('status-text', { timeout: 60000 }).should('contain.text', 'Ready') + }) + cy.adminCLI(`oc wait --for=condition=Ready pod -l app=netobserv-plugin -n ${project} --timeout=180s`) } }) },