-
Notifications
You must be signed in to change notification settings - Fork 25
[NETOBSERV-2376] FlowCollector Status Page UI Test #1439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,62 @@ | ||||||||||||||
| import { Operator } from "@views/netobserv" | ||||||||||||||
| import { flowcollectorStatusPage, flowcollectorStatusSelectors } from "@views/flowcollector-status" | ||||||||||||||
|
|
||||||||||||||
| 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) | ||||||||||||||
|
|
||||||||||||||
| Operator.createFlowcollector("LokiWithoutLokiStack") | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| 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) | ||||||||||||||
| flowcollectorStatusPage.visit() | ||||||||||||||
| 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') | ||||||||||||||
|
Comment on lines
+33
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fragile row lookup — anchor to the component table.
♻️ Suggested tightening- cy.contains('td', 'Flowlogs Pipeline').parent('tr')
- .should('contain.text', 'loki-gateway-ca-bundle')
+ cy.contains('Component statuses')
+ .parents('section, [role="region"], .pf-v6-c-card, .pf-c-card').first()
+ .contains('td', /^Flowlogs Pipeline$/).parent('tr')
+ .should('contain.text', 'loki-gateway-ca-bundle')As per coding guidelines, 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| // Verify WaitingLokiStack condition shows LokiStack not found error | ||||||||||||||
| cy.get(flowcollectorStatusSelectors.lokiStackRow).should('exist') | ||||||||||||||
| .should('have.attr', 'data-test-status', 'True') | ||||||||||||||
| cy.get(flowcollectorStatusSelectors.lokiStackRow) | ||||||||||||||
| .should('contain.text', 'Loki is configured in LokiStack mode, but LokiStack API is missing') | ||||||||||||||
|
Comment on lines
+36
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not assert the environment-specific LokiStack API message. This exact text only holds when the LokiStack API is absent. On clusters where the CRD exists but the Proposed adjustment // Verify WaitingLokiStack condition shows LokiStack not found error
cy.get(flowcollectorStatusSelectors.lokiStackRow).should('exist')
.should('have.attr', 'data-test-status', 'True')
+ .should('have.attr', 'data-test-reason', 'CantFetchLokiStack')
cy.get(flowcollectorStatusSelectors.lokiStackRow)
- .should('contain.text', 'Loki is configured in LokiStack mode, but LokiStack API is missing')
+ .should('contain.text', 'LokiStack')As per coding guidelines, 🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| // 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(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.byLegacyTestID('open-network-traffic').should('exist') | ||||||||||||||
| .should('have.attr', 'aria-disabled', 'true') | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| after("all tests", function () { | ||||||||||||||
| Operator.deleteFlowCollector() | ||||||||||||||
| cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) | ||||||||||||||
| }) | ||||||||||||||
| }) | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| export namespace flowcollectorStatusSelectors { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these can be moved to netfow-page.ts instead of a new file
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if Page is diff it should have a diff view |
||
| 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 flpMonolithRow = '[id=WaitingFLPMonolith-row]' | ||
| export const lokiStackRow = '[id=WaitingLokiStack-row]' | ||
| export const flpParentRow = '[id=WaitingFLPParent-row]' | ||
| } | ||
|
|
||
| export const flowcollectorStatusPage = { | ||
| visit: () => { | ||
| cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') | ||
| cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 30000 }).should('exist') | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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: () => { | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This func already exists know?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just copied the search view from openshfit-test-private repo and this function is for search view. |
||||||||||||||||||||||||||
| 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}`); | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
|
Comment on lines
+18
to
+23
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer
- method = method.toLocaleLowerCase();
+ method = method.toLowerCase();📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| searchBy: (text) => { | ||||||||||||||||||||||||||
| cy.get('input[data-test-id="item-filter"]').clear().type(`${text}`) | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error-scenario
beforehook skips the "FlowCollector already exists" guard.Unlike the success scenario which uses
Operator.createFlowcollector()(which deletes any pre-existing FC and waits for console refresh), this blockoc applys directly. If the previousdescribe'safterfailed for any reason (see the outstanding concern aboutafterhooks not running whenbeforethrows), the old Ready FlowCollector will be patched in-place rather than replaced, and the 120s wait at Line 127 may observe staleReady=Truestatus before flipping. Suggest callingOperator.deleteFlowCollector()first, or reusingOperator.createFlowcollector('LokiWithoutStack')(after fixing the Ready assertion flagged innetobserv.ts), plus a console-refresh wait similar tocreateFlowcollector.🤖 Prompt for AI Agents