From d985cda6d77a6d91c5a11141d613db7191aa7af2 Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Fri, 17 Apr 2026 12:21:42 -0400 Subject: [PATCH 1/6] FlowCollector Status ui Test --- .../flowcollector/fc_lokiWithoutStack.yaml | 14 ++ .../flowcollector_status.cy.ts | 146 ++++++++++++++++++ web/cypress/views/flowcollector-status.ts | 17 ++ web/cypress/views/netobserv.ts | 5 + web/cypress/views/search.ts | 27 ++++ 5 files changed, 209 insertions(+) create mode 100644 web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml create mode 100644 web/cypress/integration-tests/flowcollector_status.cy.ts create mode 100644 web/cypress/views/flowcollector-status.ts create mode 100644 web/cypress/views/search.ts diff --git a/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml b/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml new file mode 100644 index 000000000..d30b3bfbe --- /dev/null +++ b/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml @@ -0,0 +1,14 @@ +kind: FlowCollector +apiVersion: flows.netobserv.io/v1beta2 +metadata: + name: cluster +spec: + agent: + ebpf: + sampling: 1 + type: eBPF + loki: + enable: true + mode: LokiStack + lokiStack: + name: loki \ No newline at end of file diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts new file mode 100644 index 000000000..5714819fc --- /dev/null +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -0,0 +1,146 @@ +import { pluginSelectors } from "@views/netflow-page" +import { Operator } from "@views/netobserv" +import { flowcollectorStatusPage, flowcollectorStatusSelectors } from "@views/flowcollector-status" +import { searchPage } from "@views/search" + +describe('Network_Observability FlowCollector status and status indicator tests', { 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')) + + Operator.install() + cy.checkStorageClass(this) + Operator.createFlowcollector() + }) + + beforeEach('test', function () { + cy.clearLocalStorage() + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status page components and conditions", { tags: ['@netobserv-critical'] }, function () { + flowcollectorStatusPage.visit() + + // Verify status page title with status icon and tooltip on hover + cy.contains('Network Observability FlowCollector status').should('exist') + cy.get('button[aria-label="FlowCollector status"]').should('exist') + cy.get('button[aria-label="FlowCollector status"] span').first().trigger('mouseenter', { force: true }) + cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + + // Verify component statuses table headers + cy.contains('Component statuses').should('exist') + cy.contains('th', 'Component').should('exist') + cy.contains('th', 'State').should('exist') + cy.contains('th', 'Replicas').should('exist') + cy.contains('th', 'Details').should('exist') + + // Verify component rows + cy.contains('eBPF Agent').should('exist') + cy.contains('Flowlogs Pipeline').should('exist') + cy.contains('Console Plugin').should('exist') + cy.contains('Loki').should('exist') + cy.contains('Monitoring').should('exist') + + // Verify "Open Network Traffic page" button is enabled when FC is ready + cy.get(pluginSelectors.openNetworkTraffic).should('exist') + .should('not.have.attr', 'aria-disabled', 'true') + + // Verify demoloki install warning alert at top of status page + cy.get(flowcollectorStatusSelectors.configIssueRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + .should('have.attr', 'data-test-reason', 'Warnings') + cy.get(flowcollectorStatusSelectors.configWarningAlert).should('exist') + .find('.pf-v5-c-alert__title') + .should('contain.text', 'Configuration warnings') + + // Verify Conditions + cy.contains('Conditions').should('exist') + cy.get(flowcollectorStatusSelectors.readyRow) + .should('have.attr', 'data-test-status', 'True') + cy.get(flowcollectorStatusSelectors.agentReadyRow).should('exist') + cy.get(flowcollectorStatusSelectors.pluginReadyRow).should('exist') + cy.get(flowcollectorStatusSelectors.monitoringReadyRow).should('exist') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Traffic page", function () { + cy.visit('/netflow-traffic') + cy.get('#overview-container', { timeout: 60000 }).should('exist') + cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') + + // Verify tooltip on hover - mouseenter triggers Floating UI tooltip + cy.get(flowcollectorStatusSelectors.statusIndicator + ' span').first().trigger('mouseenter', { force: true }) + cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + + cy.get(flowcollectorStatusSelectors.statusIndicator).click() + cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Health page", function () { + cy.visit('/network-health') + cy.get('#content-scrollable', { timeout: 30000 }).should('exist') + cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') + + // Verify tooltip on hover - mouseenter triggers Floating UI tooltip + cy.get(flowcollectorStatusSelectors.statusIndicator + ' span').first().trigger('mouseenter', { force: true }) + cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + + cy.get(flowcollectorStatusSelectors.statusIndicator).click() + cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status via search and cluster columns", function () { + // Search for FlowCollector via search page + searchPage.navToSearchPage() + searchPage.chooseResourceType('FlowCollector') + cy.get('table[data-test="data-view-table"]', { timeout: 30000 }).should('exist') + cy.get('[data-test="data-view-cell-cluster-name"]').should('exist') + + // Verify additionalPrinterColumn headers + cy.get('[data-test="additional-printer-column-header-Agent"]').should('exist') + cy.get('[data-test="additional-printer-column-header-Processor"]').should('exist') + cy.get('[data-test="additional-printer-column-header-Plugin"]').should('exist') + cy.get('[data-test="additional-printer-column-header-Status"]').should('exist') + + // Verify status column shows Ready + cy.get('[data-test="additional-printer-column-data-Status"]').should('contain.text', 'Ready') + }) + + after("after all tests are done", function () { + Operator.deleteFlowCollector() + cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) + }) +}) + +describe('Network_Observability FlowCollector status error scenario', { tags: ['Network_Observability'] }, function () { + + before('setup', 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')) + + Operator.install() + cy.checkStorageClass(this) + + // Deploy FlowCollector with Loki enabled pointing to a non-existent LokiStack + cy.deployFlowcollectorFromFixture('./cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify error status when Loki enabled without LokiStack", function () { + // Visit status page and wait for Ready condition to show False (error state) + cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') + cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 120000 }).should('exist') + .should('have.attr', 'data-test-status', 'False') + + // Verify status icon tooltip shows error + cy.get('button[aria-label="FlowCollector status"] span').first().trigger('mouseenter', { force: true }) + cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector has errors') + + // Verify "Open Network Traffic page" button is disabled + cy.get(pluginSelectors.openNetworkTraffic).should('exist') + .should('have.attr', 'aria-disabled', 'true') + }) + + after("cleanup", function () { + Operator.deleteFlowCollector() + cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) + }) +}) diff --git a/web/cypress/views/flowcollector-status.ts b/web/cypress/views/flowcollector-status.ts new file mode 100644 index 000000000..996750534 --- /dev/null +++ b/web/cypress/views/flowcollector-status.ts @@ -0,0 +1,17 @@ +export namespace flowcollectorStatusSelectors { + export const statusIndicator = '#flowcollector-status-indicator' + export const readyRow = '[id=Ready-row]' + export const agentReadyRow = '[id=WaitingEBPFAgents-row]' + export const pluginReadyRow = '[id=WaitingWebConsole-row]' + export const monitoringReadyRow = '[id=WaitingMonitoring-row]' + export const configIssueRow = '[id=ConfigurationIssue-row]' + export const configWarningAlert = '.pf-v5-c-alert.pf-m-warning.pf-m-inline' + export const configErrorAlert = '.pf-v5-c-alert.pf-m-danger.pf-m-inline' +} + +export const flowcollectorStatusPage = { + visit: () => { + cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') + cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 30000 }).should('exist') + } +} diff --git a/web/cypress/views/netobserv.ts b/web/cypress/views/netobserv.ts index e66be5432..26c159e66 100644 --- a/web/cypress/views/netobserv.ts +++ b/web/cypress/views/netobserv.ts @@ -19,6 +19,7 @@ type FlowCollectorParameter = | 'DNSTracking' | 'UDNMapping' | 'LokiDisabled' + | 'LokiWithoutStack' | 'Conversations' | 'ZonesAndMultiCluster' | 'BytesMetrics' @@ -48,6 +49,7 @@ const FIXTURE_PATHS = { flowRTT: './cypress/fixtures/flowcollector/fc_flowRTT.yaml', udnMapping: './cypress/fixtures/flowcollector/fc_UDN.yaml', lokiDisabled: './cypress/fixtures/flowcollector/fc_lokiDisabled.yaml', + lokiWithoutStack: './cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml', conversations: './cypress/fixtures/flowcollector/fc_conversations.yaml', subnetLabels: './cypress/fixtures/flowcollector/fc_subnetLabel.yaml', zonesMultiCluster: './cypress/fixtures/flowcollector/fc_zoneMulticluster.yaml', @@ -165,6 +167,9 @@ export const Operator = { case "LokiDisabled": cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiDisabled) break; + case "LokiWithoutStack": + cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiWithoutStack) + break; case "Conversations": cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.conversations) break; diff --git a/web/cypress/views/search.ts b/web/cypress/views/search.ts new file mode 100644 index 000000000..25c483f88 --- /dev/null +++ b/web/cypress/views/search.ts @@ -0,0 +1,27 @@ +export const searchPage = { + navToSearchPage: () => cy.visit('/search/all-namespaces'), + chooseResourceType: (resource_type) => { + cy.get('input[placeholder="Resources"]').clear().type(`${resource_type}`); + cy.get(`label[id$="~${resource_type}"]`).click(); + }, + checkNoMachineResources: () => { + searchPage.navToSearchPage(); + cy.get('[placeholder="Resources"]').type("machine"); + const machineResources = ['MMachine','MAMachineAutoscaler','MCMachineConfig','MCPMachineConfigPool','MHCMachineHealthCheck','MSMachineSet']; + machineResources.forEach((machineResource) => { + cy.get(`[data-filter-text=${machineResource}]`).should('not.exist'); + }); + }, + clearAllFilters: () => { + cy.byButtonText('Clear all filters').click({force: true}); + }, + searchMethodValues: (method, value) => { + method = method.toLocaleLowerCase(); + cy.get('button[id="search-filter-toggle"]').click(); + cy.get(`li[data-test="${method}-filter"] button[role="option"]`).click(); + cy.get('input[id="search-filter-input"]').clear().type(`${value}`); + }, + searchBy: (text) => { + cy.get('input[data-test-id="item-filter"]').clear().type(`${text}`) + }, +} From fa0d9b9953af7d649e1fbbae29e1194ed55cd8fe Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Wed, 22 Apr 2026 15:27:26 -0400 Subject: [PATCH 2/6] Loki Negative test cases --- .../flowcollector/fc_lokiWithoutStack.yaml | 2 +- .../flowcollector_status.cy.ts | 81 ++++++++++++------- web/cypress/views/flowcollector-status.ts | 7 +- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml b/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml index d30b3bfbe..a77f4a042 100644 --- a/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml +++ b/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml @@ -11,4 +11,4 @@ spec: enable: true mode: LokiStack lokiStack: - name: loki \ No newline at end of file + name: loki diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts index 5714819fc..24a355d51 100644 --- a/web/cypress/integration-tests/flowcollector_status.cy.ts +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -1,4 +1,3 @@ -import { pluginSelectors } from "@views/netflow-page" import { Operator } from "@views/netobserv" import { flowcollectorStatusPage, flowcollectorStatusSelectors } from "@views/flowcollector-status" import { searchPage } from "@views/search" @@ -23,9 +22,10 @@ describe('Network_Observability FlowCollector status and status indicator tests' // Verify status page title with status icon and tooltip on hover cy.contains('Network Observability FlowCollector status').should('exist') - cy.get('button[aria-label="FlowCollector status"]').should('exist') - cy.get('button[aria-label="FlowCollector status"] span').first().trigger('mouseenter', { force: true }) - cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + cy.get(flowcollectorStatusSelectors.statusButton).should('exist') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') // Verify component statuses table headers cy.contains('Component statuses').should('exist') @@ -42,16 +42,14 @@ describe('Network_Observability FlowCollector status and status indicator tests' cy.contains('Monitoring').should('exist') // Verify "Open Network Traffic page" button is enabled when FC is ready - cy.get(pluginSelectors.openNetworkTraffic).should('exist') + cy.byLegacyTestID('open-network-traffic').should('exist') .should('not.have.attr', 'aria-disabled', 'true') // Verify demoloki install warning alert at top of status page cy.get(flowcollectorStatusSelectors.configIssueRow).should('exist') .should('have.attr', 'data-test-status', 'True') .should('have.attr', 'data-test-reason', 'Warnings') - cy.get(flowcollectorStatusSelectors.configWarningAlert).should('exist') - .find('.pf-v5-c-alert__title') - .should('contain.text', 'Configuration warnings') + cy.contains('Configuration warnings').should('exist') // Verify Conditions cy.contains('Conditions').should('exist') @@ -66,10 +64,9 @@ describe('Network_Observability FlowCollector status and status indicator tests' cy.visit('/netflow-traffic') cy.get('#overview-container', { timeout: 60000 }).should('exist') cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') - - // Verify tooltip on hover - mouseenter triggers Floating UI tooltip - cy.get(flowcollectorStatusSelectors.statusIndicator + ' span').first().trigger('mouseenter', { force: true }) - cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') cy.get(flowcollectorStatusSelectors.statusIndicator).click() cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') @@ -79,10 +76,9 @@ describe('Network_Observability FlowCollector status and status indicator tests' cy.visit('/network-health') cy.get('#content-scrollable', { timeout: 30000 }).should('exist') cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') - - // Verify tooltip on hover - mouseenter triggers Floating UI tooltip - cy.get(flowcollectorStatusSelectors.statusIndicator + ' span').first().trigger('mouseenter', { force: true }) - cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector is ready') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') cy.get(flowcollectorStatusSelectors.statusIndicator).click() cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') @@ -92,20 +88,20 @@ describe('Network_Observability FlowCollector status and status indicator tests' // Search for FlowCollector via search page searchPage.navToSearchPage() searchPage.chooseResourceType('FlowCollector') - cy.get('table[data-test="data-view-table"]', { timeout: 30000 }).should('exist') - cy.get('[data-test="data-view-cell-cluster-name"]').should('exist') + cy.byTestID('data-view-table', { timeout: 30000 }).should('exist') + cy.byTestID('data-view-cell-cluster-name').should('exist') // Verify additionalPrinterColumn headers - cy.get('[data-test="additional-printer-column-header-Agent"]').should('exist') - cy.get('[data-test="additional-printer-column-header-Processor"]').should('exist') - cy.get('[data-test="additional-printer-column-header-Plugin"]').should('exist') - cy.get('[data-test="additional-printer-column-header-Status"]').should('exist') + cy.byTestID('additional-printer-column-header-Agent').should('exist') + cy.byTestID('additional-printer-column-header-Processor').should('exist') + cy.byTestID('additional-printer-column-header-Plugin').should('exist') + cy.byTestID('additional-printer-column-header-Status').should('exist') // Verify status column shows Ready - cy.get('[data-test="additional-printer-column-data-Status"]').should('contain.text', 'Ready') + cy.byTestID('additional-printer-column-data-Status').should('contain.text', 'Ready') }) - after("after all tests are done", function () { + after("all tests", function () { Operator.deleteFlowCollector() cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) }) @@ -129,17 +125,46 @@ describe('Network_Observability FlowCollector status error scenario', { tags: [' cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 120000 }).should('exist') .should('have.attr', 'data-test-status', 'False') + cy.get(flowcollectorStatusSelectors.readyRow) + .should('have.attr', 'data-test-reason') + .and('not.equal', 'Pending') + .and('not.equal', 'Valid') + + // Verify WaitingFLPMonolith condition shows error about loki-gateway-ca-bundle + cy.get(flowcollectorStatusSelectors.flpMonolithRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + cy.get(flowcollectorStatusSelectors.flpMonolithRow).parent() + .should('contain.text', 'loki-gateway-ca-bundle') + + // Verify Flowlogs Pipeline component shows error about loki-gateway-ca-bundle + cy.contains('td', 'Flowlogs Pipeline').parent('tr') + .should('contain.text', 'loki-gateway-ca-bundle') + + // Verify WaitingLokiStack condition shows LokiStack not found error + cy.get(flowcollectorStatusSelectors.lokiStackRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + .and('have.attr', 'data-test-reason', 'CantFetchLokiStack') + cy.get(flowcollectorStatusSelectors.lokiStackRow) + .should('contain.text', 'LokiStack.loki.grafana.com') + .and('contain.text', 'not found') + + // Verify WaitingFLPParent condition shows FLP error + cy.get(flowcollectorStatusSelectors.flpParentRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + .and('have.attr', 'data-test-reason', 'FLPError') // Verify status icon tooltip shows error - cy.get('button[aria-label="FlowCollector status"] span').first().trigger('mouseenter', { force: true }) - cy.get('.pf-v5-c-tooltip__content', { timeout: 10000 }).should('contain.text', 'FlowCollector has errors') + cy.get(flowcollectorStatusSelectors.statusButton) + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector has errors') // Verify "Open Network Traffic page" button is disabled - cy.get(pluginSelectors.openNetworkTraffic).should('exist') + cy.byLegacyTestID('open-network-traffic').should('exist') .should('have.attr', 'aria-disabled', 'true') }) - after("cleanup", function () { + after("all tests", function () { Operator.deleteFlowCollector() cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) }) diff --git a/web/cypress/views/flowcollector-status.ts b/web/cypress/views/flowcollector-status.ts index 996750534..6a8f0eb5c 100644 --- a/web/cypress/views/flowcollector-status.ts +++ b/web/cypress/views/flowcollector-status.ts @@ -1,12 +1,15 @@ export namespace flowcollectorStatusSelectors { export const statusIndicator = '#flowcollector-status-indicator' + export const statusButton = 'button[aria-label="FlowCollector status"]' + export const statusTooltip = '#flowcollector-status-tooltip' export const readyRow = '[id=Ready-row]' export const agentReadyRow = '[id=WaitingEBPFAgents-row]' export const pluginReadyRow = '[id=WaitingWebConsole-row]' export const monitoringReadyRow = '[id=WaitingMonitoring-row]' export const configIssueRow = '[id=ConfigurationIssue-row]' - export const configWarningAlert = '.pf-v5-c-alert.pf-m-warning.pf-m-inline' - export const configErrorAlert = '.pf-v5-c-alert.pf-m-danger.pf-m-inline' + export const flpMonolithRow = '[id=WaitingFLPMonolith-row]' + export const lokiStackRow = '[id=WaitingLokiStack-row]' + export const flpParentRow = '[id=WaitingFLPParent-row]' } export const flowcollectorStatusPage = { From 7ec6e1202e5a222c6b23728be819d1cad08ed684 Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Thu, 23 Apr 2026 09:32:04 -0400 Subject: [PATCH 3/6] Lokistack Condition update --- web/cypress/integration-tests/flowcollector_status.cy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts index 24a355d51..4d017bc0c 100644 --- a/web/cypress/integration-tests/flowcollector_status.cy.ts +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -143,10 +143,8 @@ describe('Network_Observability FlowCollector status error scenario', { tags: [' // Verify WaitingLokiStack condition shows LokiStack not found error cy.get(flowcollectorStatusSelectors.lokiStackRow).should('exist') .should('have.attr', 'data-test-status', 'True') - .and('have.attr', 'data-test-reason', 'CantFetchLokiStack') cy.get(flowcollectorStatusSelectors.lokiStackRow) - .should('contain.text', 'LokiStack.loki.grafana.com') - .and('contain.text', 'not found') + .should('contain.text', 'Loki is configured in LokiStack mode, but LokiStack API is missing') // Verify WaitingFLPParent condition shows FLP error cy.get(flowcollectorStatusSelectors.flpParentRow).should('exist') From ad34470f38be01963a37e3d06888698478229115 Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Fri, 24 Apr 2026 13:00:37 -0400 Subject: [PATCH 4/6] LokiStack Case --- ...utStack.yaml => fc_lokiWithoutLokiStack.yaml} | 0 .../integration-tests/flowcollector_status.cy.ts | 3 +-- web/cypress/views/netobserv.ts | 16 +++++++++------- 3 files changed, 10 insertions(+), 9 deletions(-) rename web/cypress/fixtures/flowcollector/{fc_lokiWithoutStack.yaml => fc_lokiWithoutLokiStack.yaml} (100%) diff --git a/web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml b/web/cypress/fixtures/flowcollector/fc_lokiWithoutLokiStack.yaml similarity index 100% rename from web/cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml rename to web/cypress/fixtures/flowcollector/fc_lokiWithoutLokiStack.yaml diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts index 4d017bc0c..0b0689f04 100644 --- a/web/cypress/integration-tests/flowcollector_status.cy.ts +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -116,8 +116,7 @@ describe('Network_Observability FlowCollector status error scenario', { tags: [' Operator.install() cy.checkStorageClass(this) - // Deploy FlowCollector with Loki enabled pointing to a non-existent LokiStack - cy.deployFlowcollectorFromFixture('./cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml') + Operator.createFlowcollector("LokiWithoutLokiStack") }) it("(OCP-88744, kapjain, Network_Observability) Verify error status when Loki enabled without LokiStack", function () { diff --git a/web/cypress/views/netobserv.ts b/web/cypress/views/netobserv.ts index 26c159e66..1fa005129 100644 --- a/web/cypress/views/netobserv.ts +++ b/web/cypress/views/netobserv.ts @@ -19,7 +19,7 @@ type FlowCollectorParameter = | 'DNSTracking' | 'UDNMapping' | 'LokiDisabled' - | 'LokiWithoutStack' + | 'LokiWithoutLokiStack' | 'Conversations' | 'ZonesAndMultiCluster' | 'BytesMetrics' @@ -49,7 +49,7 @@ const FIXTURE_PATHS = { flowRTT: './cypress/fixtures/flowcollector/fc_flowRTT.yaml', udnMapping: './cypress/fixtures/flowcollector/fc_UDN.yaml', lokiDisabled: './cypress/fixtures/flowcollector/fc_lokiDisabled.yaml', - lokiWithoutStack: './cypress/fixtures/flowcollector/fc_lokiWithoutStack.yaml', + lokiWithoutLokiStack: './cypress/fixtures/flowcollector/fc_lokiWithoutLokiStack.yaml', conversations: './cypress/fixtures/flowcollector/fc_conversations.yaml', subnetLabels: './cypress/fixtures/flowcollector/fc_subnetLabel.yaml', zonesMultiCluster: './cypress/fixtures/flowcollector/fc_zoneMulticluster.yaml', @@ -167,8 +167,8 @@ export const Operator = { case "LokiDisabled": cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiDisabled) break; - case "LokiWithoutStack": - cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiWithoutStack) + case "LokiWithoutLokiStack": + cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiWithoutLokiStack) break; case "Conversations": cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.conversations) @@ -204,11 +204,13 @@ export const Operator = { // wait for all window refresh cy.wait('@reload', { timeout: 100000 }) cy.log("Console refreshed successfully") - if (parameters !== "LokiDisabled") { + if (parameters !== "LokiDisabled" && parameters !== "LokiWithoutLokiStack") { 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') + if (parameters !== "LokiWithoutLokiStack") { + Operator.visitFlowcollector() + cy.byTestID('status-text', { timeout: 120000 }).should('exist').should('contain.text', 'Ready') + } } }) }, From 6ee6578e759ef33c05119f9195610fd3f4f8f50b Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Mon, 27 Apr 2026 14:42:22 -0400 Subject: [PATCH 5/6] Moved test to static Plugin --- .../flowcollector_status.cy.ts | 108 +----------------- .../integration-tests/static_plugin.cy.ts | 97 ++++++++++++++-- 2 files changed, 88 insertions(+), 117 deletions(-) diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts index 0b0689f04..2a6ff1d4e 100644 --- a/web/cypress/integration-tests/flowcollector_status.cy.ts +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -1,111 +1,5 @@ import { Operator } from "@views/netobserv" import { flowcollectorStatusPage, flowcollectorStatusSelectors } from "@views/flowcollector-status" -import { searchPage } from "@views/search" - -describe('Network_Observability FlowCollector status and status indicator tests', { 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')) - - Operator.install() - cy.checkStorageClass(this) - Operator.createFlowcollector() - }) - - beforeEach('test', function () { - cy.clearLocalStorage() - }) - - it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status page components and conditions", { tags: ['@netobserv-critical'] }, function () { - flowcollectorStatusPage.visit() - - // Verify status page title with status icon and tooltip on hover - cy.contains('Network Observability FlowCollector status').should('exist') - cy.get(flowcollectorStatusSelectors.statusButton).should('exist') - .find('span span').trigger('mouseenter', { force: true }) - cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) - .should('contain.text', 'FlowCollector is ready') - - // Verify component statuses table headers - cy.contains('Component statuses').should('exist') - cy.contains('th', 'Component').should('exist') - cy.contains('th', 'State').should('exist') - cy.contains('th', 'Replicas').should('exist') - cy.contains('th', 'Details').should('exist') - - // Verify component rows - cy.contains('eBPF Agent').should('exist') - cy.contains('Flowlogs Pipeline').should('exist') - cy.contains('Console Plugin').should('exist') - cy.contains('Loki').should('exist') - cy.contains('Monitoring').should('exist') - - // Verify "Open Network Traffic page" button is enabled when FC is ready - cy.byLegacyTestID('open-network-traffic').should('exist') - .should('not.have.attr', 'aria-disabled', 'true') - - // Verify demoloki install warning alert at top of status page - cy.get(flowcollectorStatusSelectors.configIssueRow).should('exist') - .should('have.attr', 'data-test-status', 'True') - .should('have.attr', 'data-test-reason', 'Warnings') - cy.contains('Configuration warnings').should('exist') - - // Verify Conditions - cy.contains('Conditions').should('exist') - cy.get(flowcollectorStatusSelectors.readyRow) - .should('have.attr', 'data-test-status', 'True') - cy.get(flowcollectorStatusSelectors.agentReadyRow).should('exist') - cy.get(flowcollectorStatusSelectors.pluginReadyRow).should('exist') - cy.get(flowcollectorStatusSelectors.monitoringReadyRow).should('exist') - }) - - it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Traffic page", function () { - cy.visit('/netflow-traffic') - cy.get('#overview-container', { timeout: 60000 }).should('exist') - cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') - .find('span span').trigger('mouseenter', { force: true }) - cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) - .should('contain.text', 'FlowCollector is ready') - - cy.get(flowcollectorStatusSelectors.statusIndicator).click() - cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') - }) - - it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Health page", function () { - cy.visit('/network-health') - cy.get('#content-scrollable', { timeout: 30000 }).should('exist') - cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') - .find('span span').trigger('mouseenter', { force: true }) - cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) - .should('contain.text', 'FlowCollector is ready') - - cy.get(flowcollectorStatusSelectors.statusIndicator).click() - cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') - }) - - it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status via search and cluster columns", function () { - // Search for FlowCollector via search page - searchPage.navToSearchPage() - searchPage.chooseResourceType('FlowCollector') - cy.byTestID('data-view-table', { timeout: 30000 }).should('exist') - cy.byTestID('data-view-cell-cluster-name').should('exist') - - // Verify additionalPrinterColumn headers - cy.byTestID('additional-printer-column-header-Agent').should('exist') - cy.byTestID('additional-printer-column-header-Processor').should('exist') - cy.byTestID('additional-printer-column-header-Plugin').should('exist') - cy.byTestID('additional-printer-column-header-Status').should('exist') - - // Verify status column shows Ready - cy.byTestID('additional-printer-column-data-Status').should('contain.text', 'Ready') - }) - - after("all tests", function () { - Operator.deleteFlowCollector() - cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) - }) -}) describe('Network_Observability FlowCollector status error scenario', { tags: ['Network_Observability'] }, function () { @@ -121,7 +15,7 @@ describe('Network_Observability FlowCollector status error scenario', { tags: [' it("(OCP-88744, kapjain, Network_Observability) Verify error status when Loki enabled without LokiStack", function () { // Visit status page and wait for Ready condition to show False (error state) - cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') + flowcollectorStatusPage.visit() cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 120000 }).should('exist') .should('have.attr', 'data-test-status', 'False') cy.get(flowcollectorStatusSelectors.readyRow) diff --git a/web/cypress/integration-tests/static_plugin.cy.ts b/web/cypress/integration-tests/static_plugin.cy.ts index 1edbc34f7..09ae5ac51 100644 --- a/web/cypress/integration-tests/static_plugin.cy.ts +++ b/web/cypress/integration-tests/static_plugin.cy.ts @@ -1,7 +1,9 @@ import { netflowPage, overviewSelectors, pluginSelectors } from "@views/netflow-page" import { Operator } from "@views/netobserv" +import {flowcollectorStatusPage, flowcollectorStatusSelectors} from "@views/flowcollector-status"; +import {searchPage} from "@views/search"; -describe('(OCP-84156 Network_Observability) StaticPlugin test', { tags: ['Network_Observability'] }, function () { +describe('(OCP-84156 OCP-88744 Network_Observability) StaticPlugin test with Status Check', { tags: ['Network_Observability'] }, function () { before('any test', function () { cy.adminCLI(`oc adm policy add-cluster-role-to-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) @@ -12,19 +14,56 @@ describe('(OCP-84156 Network_Observability) StaticPlugin test', { tags: ['Networ Operator.createFlowcollector("StaticPlugin") }) - it("(OCP-84156, aramesha, Network_Observability) Edit flowcollector form view", function () { + it("(OCP-84156, OCP-88744 aramesha, Network_Observability) Edit flowcollector form view with Status Check", function () { // Edit flowcollector form view to update sampling to 1 - cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') + flowcollectorStatusPage.visit() + // Verify status page title with status icon and tooltip on hover + cy.contains('Network Observability FlowCollector status').should('exist') + cy.get(flowcollectorStatusSelectors.statusButton).should('exist') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') + + // Verify component statuses table headers + cy.contains('Component statuses').should('exist') + cy.contains('th', 'Component').should('exist') + cy.contains('th', 'State').should('exist') + cy.contains('th', 'Replicas').should('exist') + cy.contains('th', 'Details').should('exist') + + // Verify component rows + cy.contains('eBPF Agent').should('exist') + cy.contains('Flowlogs Pipeline').should('exist') + cy.contains('Console Plugin').should('exist') + cy.contains('Loki').should('exist') + cy.contains('Monitoring').should('exist') + + // Verify "Open Network Traffic page" button is enabled when FC is ready + cy.byLegacyTestID('open-network-traffic').should('exist') + .should('not.have.attr', 'aria-disabled', 'true') + + // Verify demoloki install warning alert at top of status page + cy.get(flowcollectorStatusSelectors.configIssueRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + .should('have.attr', 'data-test-reason', 'Warnings') + cy.contains('Configuration warnings').should('exist') + + // Verify Conditions + cy.contains('Conditions').should('exist') + cy.get(flowcollectorStatusSelectors.readyRow) + .should('have.attr', 'data-test-status', 'True') + cy.get(flowcollectorStatusSelectors.agentReadyRow).should('exist') + cy.get(flowcollectorStatusSelectors.pluginReadyRow).should('exist') + cy.get(flowcollectorStatusSelectors.monitoringReadyRow).should('exist') cy.get(pluginSelectors.editFlowcollector).click() cy.get('#root_spec_agent_accordion-toggle').click() cy.get('#root_spec_agent_ebpf_sampling').clear().type('1') cy.get(pluginSelectors.update).click() // Wait for flowcollector to get ready cy.wait(20000) - cy.get('[id=Ready-row]', { timeout: 60000 }).each($td => { - cy.wrap($td).should('have.attr', 'data-test-status', 'True') - cy.wrap($td).should('have.attr', "data-test-reason", 'Ready') - }) + cy.get(flowcollectorStatusSelectors.readyRow).should('exist') + .should('have.attr', 'data-test-status', 'True') + .should('have.attr', 'data-test-reason', 'Ready') cy.get(pluginSelectors.openNetworkTraffic).click() // Verify PacketDrop data is seen @@ -35,12 +74,50 @@ describe('(OCP-84156 Network_Observability) StaticPlugin test', { tags: ['Networ cy.checkPanelsNum(6); cy.checkNetflowTraffic() - }) - - afterEach("test", function () { netflowPage.resetClearFilters() }) + it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Health page", function () { + cy.visit('/network-health') + // cy.get('#content-scrollable', { timeout: 30000 }).should('exist') + cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') + + cy.get(flowcollectorStatusSelectors.statusIndicator).click() + cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Traffic page", function () { + cy.visit('/netflow-traffic') + // cy.get('#overview-container', { timeout: 60000 }).should('exist') + cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') + .find('span span').trigger('mouseenter', { force: true }) + cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) + .should('contain.text', 'FlowCollector is ready') + + cy.get(flowcollectorStatusSelectors.statusIndicator).click() + cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') + }) + + it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status via search and cluster columns", function () { + // Search for FlowCollector via search page + searchPage.navToSearchPage() + searchPage.chooseResourceType('FlowCollector') + cy.byTestID('data-view-table', { timeout: 30000 }).should('exist') + cy.byTestID('data-view-cell-cluster-name').should('exist') + + // Verify additionalPrinterColumn headers + cy.byTestID('additional-printer-column-header-Agent').should('exist') + cy.byTestID('additional-printer-column-header-Processor').should('exist') + cy.byTestID('additional-printer-column-header-Plugin').should('exist') + cy.byTestID('additional-printer-column-header-Status').should('exist') + + // Verify status column shows Ready + cy.byTestID('additional-printer-column-data-Status').should('contain.text', 'Ready') + }) + after("after all tests", function () { Operator.deleteFlowCollector() cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) From f071eb9a94ab32343ff80f1544ecb01520889bbf Mon Sep 17 00:00:00 2001 From: Kapil Jain Date: Tue, 28 Apr 2026 10:20:52 -0400 Subject: [PATCH 6/6] Search View Update --- .../flowcollector_status.cy.ts | 1 - .../integration-tests/static_plugin.cy.ts | 13 ++++++++----- web/cypress/views/search.ts | 17 ----------------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/web/cypress/integration-tests/flowcollector_status.cy.ts b/web/cypress/integration-tests/flowcollector_status.cy.ts index 2a6ff1d4e..fb7e1074d 100644 --- a/web/cypress/integration-tests/flowcollector_status.cy.ts +++ b/web/cypress/integration-tests/flowcollector_status.cy.ts @@ -9,7 +9,6 @@ describe('Network_Observability FlowCollector status error scenario', { tags: [' Operator.install() cy.checkStorageClass(this) - Operator.createFlowcollector("LokiWithoutLokiStack") }) diff --git a/web/cypress/integration-tests/static_plugin.cy.ts b/web/cypress/integration-tests/static_plugin.cy.ts index 09ae5ac51..4b6bf357b 100644 --- a/web/cypress/integration-tests/static_plugin.cy.ts +++ b/web/cypress/integration-tests/static_plugin.cy.ts @@ -17,6 +17,7 @@ describe('(OCP-84156 OCP-88744 Network_Observability) StaticPlugin test with Sta it("(OCP-84156, OCP-88744 aramesha, Network_Observability) Edit flowcollector form view with Status Check", function () { // Edit flowcollector form view to update sampling to 1 flowcollectorStatusPage.visit() + // Verify status page title with status icon and tooltip on hover cy.contains('Network Observability FlowCollector status').should('exist') cy.get(flowcollectorStatusSelectors.statusButton).should('exist') @@ -55,48 +56,50 @@ describe('(OCP-84156 OCP-88744 Network_Observability) StaticPlugin test with Sta cy.get(flowcollectorStatusSelectors.agentReadyRow).should('exist') cy.get(flowcollectorStatusSelectors.pluginReadyRow).should('exist') cy.get(flowcollectorStatusSelectors.monitoringReadyRow).should('exist') + + // Updating ebpf Sampling to 1 cy.get(pluginSelectors.editFlowcollector).click() cy.get('#root_spec_agent_accordion-toggle').click() cy.get('#root_spec_agent_ebpf_sampling').clear().type('1') cy.get(pluginSelectors.update).click() + // Wait for flowcollector to get ready cy.wait(20000) - cy.get(flowcollectorStatusSelectors.readyRow).should('exist') + cy.get(flowcollectorStatusSelectors.readyRow,{ timeout: 60000 }).should('exist') .should('have.attr', 'data-test-status', 'True') .should('have.attr', 'data-test-reason', 'Ready') - cy.get(pluginSelectors.openNetworkTraffic).click() + // Verify PacketDrop data is seen cy.get('li.overviewTabButton').trigger('click') netflowPage.clearAllFilters() netflowPage.setAutoRefresh() cy.checkPanel(overviewSelectors.defaultPacketDropPanels) cy.checkPanelsNum(6); - cy.checkNetflowTraffic() netflowPage.resetClearFilters() }) it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Health page", function () { cy.visit('/network-health') + // cy.get('#content-scrollable', { timeout: 30000 }).should('exist') cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') .find('span span').trigger('mouseenter', { force: true }) cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) .should('contain.text', 'FlowCollector is ready') - cy.get(flowcollectorStatusSelectors.statusIndicator).click() cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') }) it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Traffic page", function () { cy.visit('/netflow-traffic') + // cy.get('#overview-container', { timeout: 60000 }).should('exist') cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') .find('span span').trigger('mouseenter', { force: true }) cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) .should('contain.text', 'FlowCollector is ready') - cy.get(flowcollectorStatusSelectors.statusIndicator).click() cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') }) diff --git a/web/cypress/views/search.ts b/web/cypress/views/search.ts index 25c483f88..25af40594 100644 --- a/web/cypress/views/search.ts +++ b/web/cypress/views/search.ts @@ -4,24 +4,7 @@ export const searchPage = { cy.get('input[placeholder="Resources"]').clear().type(`${resource_type}`); cy.get(`label[id$="~${resource_type}"]`).click(); }, - checkNoMachineResources: () => { - searchPage.navToSearchPage(); - cy.get('[placeholder="Resources"]').type("machine"); - const machineResources = ['MMachine','MAMachineAutoscaler','MCMachineConfig','MCPMachineConfigPool','MHCMachineHealthCheck','MSMachineSet']; - machineResources.forEach((machineResource) => { - cy.get(`[data-filter-text=${machineResource}]`).should('not.exist'); - }); - }, clearAllFilters: () => { cy.byButtonText('Clear all filters').click({force: true}); }, - searchMethodValues: (method, value) => { - method = method.toLocaleLowerCase(); - cy.get('button[id="search-filter-toggle"]').click(); - cy.get(`li[data-test="${method}-filter"] button[role="option"]`).click(); - cy.get('input[id="search-filter-input"]').clear().type(`${value}`); - }, - searchBy: (text) => { - cy.get('input[data-test-id="item-filter"]').clear().type(`${text}`) - }, }